Skip to content

OpenClaw Logging — Where Logs Live and How to Read Them

When something goes wrong, logs are your first stop. I can’t count how many times I’ve solved issues just by tailing the log file and spotting an obvious error message.

OpenClaw logs to two places: a JSON file (for parsing) and the console (for humans). Here’s how to find and use both.


By default, the Gateway writes a rolling log file:

/tmp/openclaw/openclaw-YYYY-MM-DD.log

Override in your config:

{
logging: {
file: "/custom/path/openclaw.log"
}
}

Terminal window
openclaw logs --follow

Output modes:

  • TTY: Pretty, colorized, structured
  • Non-TTY: Plain text
  • --json: Line-delimited JSON
  • --plain: Force plain text
  • --no-color: Disable ANSI colors

The Control UI’s Logs tab tails the same file. Open via openclaw control.

Filter to specific channels:

Terminal window
openclaw channels logs --channel whatsapp

{
logging: {
level: "info", // File log level
consoleLevel: "info", // Console verbosity
consoleStyle: "pretty" // pretty | compact | json
}
}

Levels: trace, debug, info, warn, error

--verbose flag only affects console output, not file logs.


Protect sensitive data in console output:

{
logging: {
redactSensitive: "tools", // off | tools
redactPatterns: ["sk-.*"] // Custom regex patterns
}
}

Redaction affects console only—file logs are unredacted.


For production monitoring, export metrics and traces to your observability stack.

{
diagnostics: {
enabled: true
}
}
{
plugins: {
allow: ["diagnostics-otel"],
entries: {
"diagnostics-otel": { enabled: true }
}
},
diagnostics: {
enabled: true,
otel: {
enabled: true,
endpoint: "http://otel-collector:4318",
serviceName: "openclaw-gateway",
traces: true,
metrics: true,
logs: true
}
}
}

Metrics:

  • openclaw.tokens — Token usage counter
  • openclaw.cost.usd — Cost tracking
  • openclaw.run.duration_ms — Run duration histogram
  • openclaw.webhook.received — Webhook activity
  • openclaw.message.processed — Message throughput

Traces:

  • openclaw.model.usage — Model completion spans
  • openclaw.webhook.processed — Webhook processing
  • openclaw.message.processed — Message handling

Get extra logs without raising the global level:

{
diagnostics: {
flags: ["telegram.http", "telegram.payload"]
}
}

Or via environment:

Terminal window
OPENCLAW_DIAGNOSTICS=telegram.http,telegram.payload

Supports wildcards: telegram.* or * for everything.


Terminal window
openclaw doctor

Check: Is the Gateway running? Is logging.file pointing to the right path?

Set logging.level to debug or trace:

{
logging: {
level: "debug"
}
}

In --json mode, the CLI emits type-tagged objects:

TypeDescription
metaStream metadata (file, cursor, size)
logParsed log entry
noticeTruncation/rotation hints
rawUnparsed log line

EventDescription
model.usageTokens, cost, duration, context, provider/model/channel, session IDs
EventDescription
webhook.receivedWebhook ingress per channel
webhook.processedWebhook handled + duration
webhook.errorWebhook handler errors
message.queuedMessage enqueued for processing
message.processedOutcome + duration + optional error
EventDescription
queue.lane.enqueueCommand queue lane enqueue + depth
queue.lane.dequeueCommand queue lane dequeue + wait time
session.stateSession state transition + reason
session.stuckSession stuck warning + age
run.attemptRun retry/attempt metadata
diagnostic.heartbeatAggregate counters (webhooks/queue/session)

MetricTypeAttributes
openclaw.tokensCountertype, channel, provider, model
openclaw.cost.usdCounterchannel, provider, model
openclaw.run.duration_msHistogramchannel, provider, model
openclaw.context.tokensHistogramcontext, channel, provider, model
MetricTypeAttributes
openclaw.webhook.receivedCounterchannel, webhook
openclaw.webhook.errorCounterchannel, webhook
openclaw.webhook.duration_msHistogramchannel, webhook
openclaw.message.queuedCounterchannel, source
openclaw.message.processedCounterchannel, outcome
openclaw.message.duration_msHistogramchannel, outcome
MetricTypeAttributes
openclaw.queue.lane.enqueueCounterlane
openclaw.queue.lane.dequeueCounterlane
openclaw.queue.depthHistogramlane or channel=heartbeat
openclaw.queue.wait_msHistogramlane
openclaw.session.stateCounterstate, reason
openclaw.session.stuckCounterstate
openclaw.session.stuck_age_msHistogramstate
openclaw.run.attemptCounterattempt

SpanKey Attributes
openclaw.model.usagechannel, provider, model, sessionKey, sessionId, tokens.*
openclaw.webhook.processedchannel, webhook, chatId
openclaw.webhook.errorchannel, webhook, chatId, error
openclaw.message.processedchannel, outcome, chatId, messageId, sessionKey, sessionId, reason
openclaw.session.stuckstate, ageMs, queueDepth, sessionKey, sessionId

SettingDescription
diagnostics.otel.sampleRate0.0–1.0, root spans only
diagnostics.otel.flushIntervalMsMetric export interval (min 1000ms)

  • OTLP/HTTP endpoints via diagnostics.otel.endpoint or OTEL_EXPORTER_OTLP_ENDPOINT
  • If endpoint contains /v1/traces, /v1/metrics, or /v1/logs, used as-is
  • Environment variables: OTEL_EXPORTER_OTLP_ENDPOINT, OTEL_SERVICE_NAME, OTEL_EXPORTER_OTLP_PROTOCOL
  • Currently supports http/protobuf only (grpc is ignored)

  • OTLP logs use the same structured records written to logging.file
  • Respects logging.level (file log level)
  • Console redaction does not apply to OTLP logs
  • High-volume installs should prefer OTLP collector sampling/filtering

Still stuck? Our AI Setup Assistant can help interpret your logs.



Need help? Join the OpenClaw Discord or check the GitHub Issues.

OpenClaw

OpenClaw Expert

Still stuck?

If this page didn't answer your case, ask OpenClaw Expert for step-by-step guidance.