Skip to content

Audit Logging and Token Tracking ​

mem0 Memory Service includes built-in audit logging and token usage tracking for every API call. Use it to monitor API usage, estimate LLM costs, and feed logs into external collectors.

Log Location ​

When deployed via Docker, audit logs are written to the ./audit_logs/ directory (mounted as ./audit_logs:/app/audit_logs in docker-compose.yml), directly accessible from the host.

  • Format: JSONL (one JSON object per line)
  • Rotation: Daily — a new file is created each day
  • Retention: Files older than 30 days are automatically deleted

Log Format ​

Every API call produces two log entries: a request log and a token usage log.

Request Log ​

json
{"ts":"2026-04-03T15:24:51.973471+00:00","method":"POST","path":"/memory/add","status":200,"elapsed_ms":36294,"ip":"127.0.0.1","agent_id":"dev","user_id":"boss"}
FieldTypeDescription
tsstringISO 8601 timestamp with timezone
methodstringHTTP method (GET, POST, PUT, DELETE)
pathstringAPI endpoint path
statusintHTTP response status code
elapsed_msintRequest duration in milliseconds
ipstringClient IP address
agent_idstringAgent identifier
user_idstringUser identifier

Token Usage Log ​

json
{"ts":"2026-04-03T15:24:51.973128+00:00","type":"token_usage","path":"/memory/add","agent_id":"dev","user_id":"boss","llm_calls":19,"input_tokens":42256,"output_tokens":38000,"total_tokens":80256}
FieldTypeDescription
tsstringISO 8601 timestamp with timezone
typestringAlways token_usage
pathstringAPI endpoint path
agent_idstringAgent identifier
user_idstringUser identifier
llm_callsintNumber of LLM invocations in this request
input_tokensintTotal input tokens consumed
output_tokensintTotal output tokens consumed
total_tokensintSum of input + output tokens

Token Tracking and Cost Estimation ​

Bedrock Pricing Reference ​

ModelInputOutput
Claude Haiku 3.5$0.80 / 1M tokens$4.00 / 1M tokens
Titan Embed Text v2$0.02 / 1M tokens—

Example Cost Calculation ​

Given the sample token usage log above (a single add with infer=True):

  • Input: 42,256 tokens × $0.80 / 1M = $0.0338
  • Output: 38,000 tokens × $4.00 / 1M = $0.1520
  • Total for this request: ~$0.186

WARNING

add with infer=True triggers multiple LLM calls (19 in this example) for memory extraction and deduplication — this is the most expensive operation. search only triggers embedding (Titan Embed v2 at $0.02/1M tokens), making it negligible in cost.

Integrating External Log Collectors ​

The JSONL files in audit_logs/ can be tailed by any file-based log shipper. Below are three common configurations.

Fluent Bit → OpenSearch ​

ini
[INPUT]
    Name        tail
    Path        /path/to/mem0-memory-service/audit_logs/*.jsonl
    Tag         mem0.audit
    Parser      json
    Refresh_Interval 5

[OUTPUT]
    Name        opensearch
    Match       mem0.audit
    Host        your-opensearch-host
    Port        443
    Index       mem0-audit-logs
    Type        _doc
    tls         On
    HTTP_User   admin
    HTTP_Passwd your-password

Vector → Elasticsearch ​

yaml
sources:
  mem0_audit:
    type: file
    include:
      - /path/to/mem0-memory-service/audit_logs/*.jsonl

transforms:
  parse_json:
    type: remap
    inputs:
      - mem0_audit
    source: '. = parse_json!(string!(.message))'

sinks:
  elasticsearch:
    type: elasticsearch
    inputs:
      - parse_json
    endpoints:
      - https://your-elasticsearch-host:9200
    bulk:
      index: mem0-audit-logs

AWS CloudWatch Logs Agent ​

json
{
  "logs": {
    "logs_collected": {
      "files": {
        "collect_list": [
          {
            "file_path": "/path/to/mem0-memory-service/audit_logs/*.jsonl",
            "log_group_name": "/mem0/audit-logs",
            "log_stream_name": "{instance_id}",
            "timezone": "UTC"
          }
        ]
      }
    }
  }
}

Querying Audit Logs ​

Use jq to query JSONL files directly from the host.

Today's total token usage:

bash
cat audit_logs/$(date +%Y-%m-%d)*.jsonl | \
  jq -s '[.[] | select(.type=="token_usage")] | {total_input: (map(.input_tokens) | add), total_output: (map(.output_tokens) | add), total: (map(.total_tokens) | add)}'

Token usage grouped by agent:

bash
cat audit_logs/*.jsonl | \
  jq -s 'group_by(.agent_id) | map({agent: .[0].agent_id, total_tokens: (map(.total_tokens // 0) | add)}) | sort_by(-.total_tokens)'

Top 5 slowest requests:

bash
cat audit_logs/*.jsonl | \
  jq -s '[.[] | select(.elapsed_ms)] | sort_by(-.elapsed_ms) | .[:5] | .[] | {path, elapsed_ms, agent_id, ts}'

Error rate (non-2xx responses):

bash
cat audit_logs/*.jsonl | \
  jq -s '[.[] | select(.status)] | {total: length, errors: ([.[] | select(.status >= 400)] | length)} | .rate = (.errors / .total * 100 | round | tostring + "%")'

Released under the MIT License.