openclaw-otel-plugin exports OpenClaw runtime and diagnostics data to any OTLP HTTP/protobuf receiver. It turns session activity into traces, emits the current recommended gen_ai.* metrics, and can optionally mirror diagnostics events to OTEL logs.
- A request-scoped root span named
openclaw_request - A request-scoped run span named
agent_run - Runtime lifecycle spans such as
channel_ingress,dispatch_queue,session_processing,runtime_orchestration, andchannel_egress - Model spans named
llm - Skill summary spans such as
skill:<name> - Skill call spans such as
skill_call:<name> - Tool spans such as
tool:<name> - Diagnostic spans for webhook, session health, and tool-loop related events
Trace notes:
- One inbound user message maps to one trace
message.processedreplays transcript turns first; trailingsession.state idleonly acts as a fallback close path- Transcript replay emits one
llmper assistant turn so multi-tool sessions showmodel -> tool -> modelloops instead of one oversized model span
Recommended metric namespaces:
gen_ai.client.*gen_ai.agent.*gen_ai.runtime.*
Common metrics include:
gen_ai.client.operation.duration(OTEL-native metric name)gen_ai.agent.token.usagegen_ai.agent.request.countgen_ai.agent.request.durationgen_ai.agent.operation.countgen_ai.agent.operation.durationgen_ai.agent.session.token.inputgen_ai.agent.session.token.outputgen_ai.agent.session.token.totalgen_ai.agent.session.trace.countgen_ai.agent.skill.activation.countgen_ai.runtime.message.*gen_ai.runtime.queue.*gen_ai.runtime.session.*gen_ai.runtime.webhook.*
Metric boundary notes:
gen_ai.client.*is reserved for OTEL-native client semantics; the plugin no longer writes custom token or operation metrics there.- OpenClaw custom model token and model/tool/skill operation metrics are reported under
gen_ai.agent.token.usageandgen_ai.agent.operation.*.
See docs/gen-ai-metrics.md for the full metric catalog.
When logsEnabled=true, the plugin mirrors diagnostics events to OTEL logs, including:
session.staterun.attemptmessage.queuedmodel.usagemessage.processedwebhook.receivedwebhook.processedwebhook.errorsession.stuckqueue.lane.enqueuequeue.lane.dequeuediagnostic.heartbeattool.loop
- OpenClaw
2026.3.23+ - Node.js
22.x - An OTLP HTTP/protobuf receiver
Compatibility notes:
- This repository is adapted to the post-
2026.3.23OpenClaw plugin entrypoint changes - It is validated against locally installed OpenClaw
2026.3.23-2 - Older OpenClaw versions should be upgraded first
Use the GTrace skill for managed installation. The release output still includes install.sh as the execution layer used by the skill, not as the primary user-facing entrypoint. For a standard OTLP receiver, follow the source-install path from BUILDING.md and then configure ~/.openclaw/openclaw.json manually.
For build, packaging, source install, and release workflow, see BUILDING.md.
If your agent environment already has the $openclaw-gtrace-install skill, use the skill as the recommended quick-install path.
Prompt template:
Use $openclaw-gtrace-install to install the OpenClaw OTEL plugin.
Parameters:
OSS_ENDPOINT=<your GTrace OSS endpoint>
DATAWAY_ENDPOINT=<your GTrace Dataway endpoint>
VERSION=latest
X_TOKEN=<your token>
TAGS=env=prod
Requirements:
- do not print X_TOKEN
- verify the install after completion
- if installation fails, return the failed step, the key error, and the next suggestion
To install a specific version, change VERSION to v0.6.7 or another published tag.
If you want to install files first and fill the config later, add:
NO_CONFIG=true
If you want to skip the immediate gateway restart, add:
NO_RESTART=true
For a standard OTLP receiver, complete the source install first, then use the manual configuration example below.
The manual JSON example below uses a standard OTLP HTTP/protobuf receiver.
Manual configuration is only needed when:
- you installed with
--no-config - you want to customize advanced fields
Minimal example in ~/.openclaw/openclaw.json:
{
"plugins": {
"allow": [
"openclaw-otel-plugin"
],
"load": {
"paths": [
"/Users/yourname/.openclaw/extensions/openclaw-otel-plugin"
]
},
"entries": {
"openclaw-otel-plugin": {
"enabled": true,
"config": {
"endpoint": "http://127.0.0.1:4318/otel",
"tracePath": "v1/traces",
"metricsPath": "v1/metrics",
"logsEnabled": false,
"logsPath": "v1/logs",
"headers": {
"Authorization": "Bearer <token>"
},
"sampleRate": 1,
"serviceName": "openclaw-otel-plugin",
"flushIntervalMs": 30000,
"rootSpanTtlMs": 600000,
"resourceAttributes": {
"agent_runtime": "openclaw",
"env": "prod"
}
}
}
}
}
}| Field | Default | Notes |
|---|---|---|
endpoint |
http://127.0.0.1:4318/otel |
Receiver base URL. Trailing / is removed automatically |
tracePath |
v1/traces |
Trace route appended to endpoint |
metricsPath |
v1/metrics |
Metrics route appended to endpoint |
logsEnabled |
false |
Logs are exported only when explicitly enabled |
logsPath |
v1/logs |
Logs route appended to endpoint |
protocol |
http/protobuf |
The only supported protocol |
serviceName |
openclaw-otel-plugin |
Exported as OTEL service.name |
headers |
unset | Fixed HTTP headers applied to traces, metrics, and logs |
sampleRate |
unset | Optional root sampler ratio in [0, 1] |
flushIntervalMs |
30000 |
Metrics export interval |
rootSpanTtlMs |
600000 |
Closes stale root/run spans after inactivity |
resourceAttributes |
{ "agent_runtime": "openclaw" } |
Fixed OTEL resource attributes; every --tag key=value is merged here |
Compatibility fields still accepted:
globalTags: compatibility alias merged intoresourceAttributes
Resource attributes are resolved in this order:
- runtime metadata discovered from OpenClaw state, when available
- resolved config resource attributes, including the default
agent_runtime, compatibility fields, and explicitresourceAttributes
Runtime metadata may contribute:
agent_versionruntime_environmentagent_idagent_name
{
"plugins": {
"entries": {
"openclaw-otel-plugin": {
"enabled": true,
"config": {
"endpoint": "http://<dataway-host>",
"tracePath": "v1/write/otel-llm",
"metricsPath": "v1/write/otel-metrics",
"logsEnabled": true,
"logsPath": "v1/write/otel-logs",
"headers": {
"X-Token": "<your-dataway-client_token>",
"To-Headless": "true"
},
"serviceName": "openclaw-otel-plugin",
"resourceAttributes": {
"agent_runtime": "openclaw",
"env": "prod",
"app_name":"openclaw-agent",
"app_id":"999999990000000000iuui"
}
}
}
}
}
}Notes:
- Keep
endpointas scheme + host + port only - Put the write routes in
tracePath,metricsPath, andlogsPath logsEnabledmust betrueif you want diagnostics logsheaders.X-Tokenshould be a Dataway client token
Check gateway logs:
tail -n 50 ~/.openclaw/logs/gateway.logExpected startup logs:
[otel-plugin] trace exporter enabled (http/protobuf) -> http://127.0.0.1:4318/otel/v1/traces
[otel-plugin] metric exporter enabled (http/protobuf) -> http://127.0.0.1:4318/otel/v1/metrics
[otel-plugin] log exporter disabled
If logs are enabled:
[otel-plugin] log exporter enabled (http/protobuf) -> http://127.0.0.1:4318/otel/v1/logs
[otel-plugin] trace export succeeded -> ...
[otel-plugin] metric export succeeded -> ...
[otel-plugin] log export succeeded -> ...
Then send a test message in OpenClaw and query by:
service.name = openclaw-otel-plugin- latest
trace_id
- The plugin enriches spans and logs with session, agent, provider, model, and preview fields derived from OpenClaw session snapshots
- Root and run spans are intentionally separate. The root span models the inbound request envelope, while
agent_runmodels the agent execution lifecycle. - When fine-grained runtime events are missing, the plugin can replay transcript state to backfill
thinking, model, and tool spans. - The plugin periodically scans active sessions on the
flushIntervalMscadence (default30s); session metrics are emitted as scan-time deltas and carrysession_idas a metric tag. gen_ai.agent.session.token.*andgen_ai.agent.session.trace.countrepresent session-level cumulative totals instead of being tied to individual run completion.gen_ai.agent.session.token.*is accumulated from runtimemodel.usageevents first, so it does not depend on transcriptmessage.usagebeing persisted.- Skill attribution prefers runtime tool identity, then falls back to session skill snapshots, transcript content, and local skill catalogs under
~/.openclaw/workspace/skills - Transcript-derived skill spans prefer actually invoked skills over merely mentioned skills
- If no skill identity can be inferred, the plugin will keep tool spans without fabricating a generic skill span.
- Tool loop diagnostics are attached to the active tool span when possible; critical loops mark the tool span as error
- Canonical query fields such as
session_id,session_key,tool_name,tool_call_id,provider_name, andrequest_modelare emitted for easier querying
- Check receiver reachability
- Check
endpointand signal paths - Check auth headers
- Check whether the plugin entry is enabled
- Check
gateway.logforenabled,succeeded, orfailedexporter lines - When debugging trace parent/child links or missing
run_id, enabletracePayloadDebugEnabled=trueto log the full trace export payload before OTLP export
- Set
logsEnabled=true - Make sure the receiver supports OTLP logs
- Check
logsPathand auth headers separately from trace and metrics routes
Custom fields must live under:
plugins.entries.openclaw-otel-plugin.config
Do not place these fields directly beside enabled:
endpointtracePathmetricsPathlogsEnabledlogsPathheaderssampleRateserviceNameflushIntervalMsrootSpanTtlMsglobalTagsresourceAttributes