Skip to content

Logging

NimbleBrain writes structured logs as JSONL (one JSON object per line) to daily rolling log files. These logs capture LLM latency, tool execution times, cache token usage, per-tool statistics, and estimated costs.

Control logging through the logging object in nimblebrain.json:

{
"logging": {
"dir": "~/.nimblebrain/logs",
"disabled": false
}
}
FieldTypeDefaultDescription
dirstring{workDir}/logsDirectory where log files are written. Created automatically if it does not exist.
disabledbooleanfalseSet to true to disable structured logging entirely.

Structured logging is enabled by default. To disable it:

{
"logging": {
"disabled": true
}
}

Log files follow a daily rolling pattern:

{dir}/nimblebrain-YYYY-MM-DD.jsonl

A new file is created automatically each day. Examples:

~/.nimblebrain/logs/nimblebrain-2026-03-25.jsonl
~/.nimblebrain/logs/nimblebrain-2026-03-26.jsonl

Every log line is a JSON object with at minimum a timestamp and event type:

{"ts":"2026-03-25T14:30:00.123Z","event":"run.start","runId":"abc123","model":"claude-sonnet-4-5-20250929"}
FieldTypeDescription
tsstringISO 8601 timestamp of when the event was recorded.
eventstringEvent type (e.g., run.start, tool.done, run.done).
sidstringConversation ID, present when the log sink has a conversation context.
runIdstringUnique identifier for the agent run. Correlates all events in a single request.

The following events are logged. text.delta events are excluded to avoid log noise.

run.start — An agent run begins.

{"ts":"2026-03-25T14:30:00.123Z","event":"run.start","runId":"abc123","model":"claude-sonnet-4-5-20250929","sid":"conv-456"}

iteration.done — One LLM call + tool execution cycle completes.

{"ts":"2026-03-25T14:30:01.456Z","event":"iteration.done","runId":"abc123","llmMs":823,"cacheCreationTokens":1200,"cacheReadTokens":4500}

tool.done — A tool call finishes.

{"ts":"2026-03-25T14:30:01.200Z","event":"tool.done","runId":"abc123","name":"postgres__query","ms":45,"ok":true}

run.done — The agent run completes. This is the summary record with accumulated metrics.

{
"ts": "2026-03-25T14:30:02.789Z",
"event": "run.done",
"runId": "abc123",
"sid": "conv-456",
"inputTokens": 12500,
"outputTokens": 1830,
"cacheCreationTokens": 1200,
"cacheReadTokens": 4500,
"llmMs": 1650,
"toolMs": 320,
"toolCalls": 3,
"toolErrors": 0,
"costUsd": 0.004215,
"toolStats": {
"postgres__query": { "count": 2, "totalMs": 250 },
"filesystem__read_file": { "count": 1, "totalMs": 70 }
}
}

run.error — The agent run failed with an error.

{"ts":"2026-03-25T14:30:03.000Z","event":"run.error","runId":"abc123","error":"Token budget exceeded"}

The run.done event accumulates metrics across all iterations in the run:

FieldTypeDescription
inputTokensnumberTotal input tokens consumed.
outputTokensnumberTotal output tokens generated.
cacheCreationTokensnumberTokens written to prompt cache during this run.
cacheReadTokensnumberTokens read from prompt cache (cache hits).
llmMsnumberTotal milliseconds spent in LLM calls.
toolMsnumberTotal milliseconds spent executing tools.
toolCallsnumberTotal number of tool calls made.
toolErrorsnumberNumber of tool calls that returned errors.
costUsdnumberEstimated cost in USD, based on the model’s token pricing.
toolStatsobjectPer-tool breakdown: { "toolName": { "count": N, "totalMs": N } }. Only present when at least one tool was called.

Log files are plain JSONL, so you can use standard command-line tools:

Terminal window
# Total cost for today
cat ~/.nimblebrain/logs/nimblebrain-2026-03-25.jsonl \
| jq -s '[.[] | select(.event == "run.done") | .costUsd] | add'
# Slowest tool calls
cat ~/.nimblebrain/logs/nimblebrain-2026-03-25.jsonl \
| jq 'select(.event == "tool.done") | {name, ms}' \
| jq -s 'sort_by(-.ms) | .[0:5]'
# Errors only
cat ~/.nimblebrain/logs/nimblebrain-2026-03-25.jsonl \
| jq 'select(.event == "run.error")'

NimbleBrain does not delete old log files. Each day creates a new file, so you can manage retention with standard tools:

Terminal window
# Delete logs older than 30 days
find ~/.nimblebrain/logs -name "nimblebrain-*.jsonl" -mtime +30 -delete