Diagnostics Flags for Targeted Debug Logging

Learn how to enable extra logging for specific subsystems without raising the global log level. This page lists known flags and explains configuration, matching rules, and restart requirements.

Read this when

  • You need targeted debug logs without raising global logging levels
  • You need to capture subsystem-specific logs for support

Diagnostics flags add extra logging for a single subsystem without raising logging.level globally. Unless a subsystem explicitly checks for a flag, that flag has no effect.

How it works

  • Flags are case-insensitive strings, sourced from diagnostics.flags in config and the OPENCLAW_DIAGNOSTICS env override, with duplicates removed and lowercasing applied.
  • name.* matches both name and anything nested under name. (so telegram.* also matches telegram.http).
  • Setting * or all turns on all flags.
  • After modifying diagnostics.flags in config, restart the gateway; it does not hot-reload.

Known flags

FlagEnables
telegram.httpLogging of Telegram Bot API HTTP errors
brave.httpLogging of Brave Search requests, responses, and cache
profilerProfiler for reply stage and Codex app server (both)
reply.profilerProfiler for reply stage only
codex.profilerProfiler for Codex app server only
healthDebug details for gateway health probe, account, binding
ingress.timingTimings for session load, model selection, and model catalog
plugin.load-profileTimings for synchronous plugin module loading
timelineStructured JSONL timeline artifact (details below)

Enable via config

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

Multiple flags:

{
  "diagnostics": {
    "flags": ["telegram.http", "brave.http", "gateway.*"]
  }
}

Env override (one-off)

OPENCLAW_DIAGNOSTICS=telegram.http,brave.http

Values are split on commas or whitespace. Special values:

ValueEffect
0, false, off, noneTurn off all flags, including config
1, true, all, *Turn on every flag

For a given process, OPENCLAW_DIAGNOSTICS=0 disables flags from both env and config, which is handy for silencing a profiler flag left in config without editing the file.

Profiler flags

Profiler flags control lightweight timing spans; when off, they add no overhead.

To enable all profiler-gated spans for a single gateway run:

OPENCLAW_DIAGNOSTICS=profiler openclaw gateway run

To enable only reply-dispatch profiler spans:

OPENCLAW_DIAGNOSTICS=reply.profiler openclaw gateway run

To enable only Codex app-server startup, tool, and thread profiler spans:

OPENCLAW_DIAGNOSTICS=codex.profiler openclaw gateway run

profiler turns on both the reply profiler and the Codex profiler; to enable just one, use the scoped flag names.

Alternatively, set it in config:

{
  "diagnostics": {
    "flags": ["reply.profiler", "codex.profiler"]
  }
}

After changing config flags, restart the gateway. To disable a profiler flag, remove it from diagnostics.flags and restart, or start the process with OPENCLAW_DIAGNOSTICS=0 to override all diagnostics flags for that run.

Timeline artifacts

The timeline flag (alias: diagnostics.timeline) emits structured startup and runtime timing events as JSONL, intended for external QA harnesses:

OPENCLAW_DIAGNOSTICS=timeline \
OPENCLAW_DIAGNOSTICS_TIMELINE_PATH=/tmp/openclaw-timeline.jsonl \
openclaw gateway run

Or enable it in config:

{
  "diagnostics": {
    "flags": ["timeline"]
  }
}

The output path is always taken from OPENCLAW_DIAGNOSTICS_TIMELINE_PATH, even when the flag is set in config; no config key exists for the path. When timeline is enabled only from config, the earliest config-loading spans are absent because OpenClaw has not read config yet; later startup spans are captured as usual.

OPENCLAW_DIAGNOSTICS=1, =all, and =* also activate the timeline, since they enable all flags. When you want only the JSONL artifact and not every other diagnostics flag, prefer the scoped timeline flag.

Event-loop delay samples in the timeline require an extra opt-in beyond timeline: set OPENCLAW_DIAGNOSTICS_EVENT_LOOP=1 (or on/true/yes) in addition to enabling the timeline.

Timeline records rely on the openclaw.diagnostics.v1 envelope, carrying data such as process ids, phase names, span names, durations, plugin ids, dependency counts, event-loop delay samples, provider operation names, child-process exit state, and startup error names/messages. These timeline files should be handled as local diagnostics artifacts; inspect them before distributing them beyond your own system.

Where logs go

Flags direct their output into the standard diagnostics log file. The default configuration is:

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

Named profiles depend on /tmp/openclaw/openclaw-<profile>-YYYY-MM-DD.log; for instance, --dev relies on openclaw-dev-YYYY-MM-DD.log.

When logging.file is configured, that path takes precedence. The logs use JSONL format, with one JSON object per line. Redaction remains active at all times. Consult Logging for the complete log-path resolution, rotation, and redaction details.

Extract logs

Access the most recent log file from the active profile:

openclaw logs --plain
# Named profile example:
openclaw --profile work logs --plain

Narrow down to Telegram HTTP diagnostics:

openclaw logs --plain --limit 5000 | rg "telegram http error"

Narrow down to Brave Search HTTP diagnostics:

openclaw logs --plain --limit 5000 | rg "brave http"

Or follow the log while reproducing the issue:

openclaw logs --follow --plain | rg "telegram http error"

For remote gateways, switch to openclaw logs --follow instead (refer to /cli/logs).

Notes

  • When logging.level exceeds warn, flag-gated logs might be withheld. The default info works well.
  • brave.http captures Brave Search request URLs and query parameters, response status and timing, plus cache hit, miss, and write events. It excludes the API key (delivered as a request header) and response bodies, though search queries may carry sensitive information.
  • Leaving flags enabled is harmless; they only increase log volume for the targeted subsystem.
  • Use /logging to adjust log destinations, levels, and redaction settings.
887 words · updated Aug 3, 2026