Telemetry · Metrics

Metrics — three counters and one histogram

Four instruments emitted via OTLP to <endpoint>/v1/metrics. Label keys align with matching trace span attributes (gen_ai.tool.name matches the tool span, nio.guard.* matches the OpenClaw tool-span guard attrs) so cross-signal queries use the same key names.

Instruments

InstrumentTypeUnitWhen recorded
nio.tool_use.countCounter{invocations}Each PreToolUse and PostToolUse (and TaskCreated / TaskCompleted if fired)
nio.turn.countCounter{turns}Each Stop / SubagentStop / SessionEnd (turn boundary)
nio.decision.countCounter{decisions}Each guard decision (allow / deny / ask)
nio.risk.scoreHistogram{score}Each guard evaluation; 0–1 distribution for avg / p50 / p99

Labels

Five label keys, used across the four instruments above. Each row below is a unique label.

AttributeDescriptionCaptured atPlatforms
gen_ai.tool.nameHost tool name (Bash, WebFetch, …); same key as the tool-span attributePreToolUse · PostToolUse · guard decisionall
nio.eventHook event firing this counter — PreToolUse / PostToolUse / TaskCreated / TaskCompletedPreToolUse · PostToolUse · TaskCreated · TaskCompletedall
nio.platformSource platform — claude-code / hermes / openclawevery metricall
nio.guard.decisionGuard verdict — allow / deny / askguard decisionall
nio.guard.risk_levelGuard risk level — low / medium / high / criticalguard decisionall

Label sets per instrument

InstrumentLabels
nio.tool_use.countgen_ai.tool.name · nio.event · nio.platform
nio.turn.countnio.platform
nio.decision.countnio.guard.decision · nio.guard.risk_level · gen_ai.tool.name · nio.platform
nio.risk.scoregen_ai.tool.name · nio.platform
Claude Code · Task → Agent

The user-facing Task tool (subagent dispatch) is reported as tool_name="Agent" in Claude Code hook payloads, so PreToolUse / PostToolUse counters use Agent as the gen_ai.tool.name label. The literal value Task only appears as a counter label when TaskCreated / TaskCompleted fire (Teammates / cloud-agent flows; never fired by the regular Task tool subagent on current Claude Code builds — see e2e-test/hook-subagent-e2e-task.md). OpenClaw and Hermes use their own native tool names.

Metrics have no local file — there is no metrics.jsonl. If collector.endpoint is empty, metrics drop on the floor (the meter provider returns null).