openclaw-telemetry
v0.11.0
Published
Call-home telemetry reporter for OpenClaw AI workers. Phones imprints (status, model, token usage, errors, browser health, host health) to your 8Examples telemetry endpoint every 10 minutes.
Maintainers
Readme
openclaw-telemetry
Call-home telemetry reporter for OpenClaw AI workers. Installs globally, asks where home is once, then runs a background job that phones in one imprint every 10 minutes: status, model, token usage, errors, browser health, and host health.
Install and run
npm install -g openclaw-telemetry
openclaw-telemetryFirst run asks three questions:
Telemetry URL [https://8examples.com/openclaw/telemetry]:
Access key (oct_...): <token from your 8Examples admin>
Claw name (e.g. openclaw1): openclaw1then starts the background job. Config is saved to
~/.openclaw-telemetry/config.json (mode 600), so subsequent runs start
straight away.
openclaw-telemetry once # send a single imprint now
openclaw-telemetry usage-check # preview newly discovered model-call usage
openclaw-telemetry status # daemon state + last sends
openclaw-telemetry stop # stop the background job
openclaw-telemetry setup # change URL / key / claw nameAdmins issue access keys from the Fleet tab at 8examples.com/account.
Zero-prompt installs
Set the environment instead and no config file or prompt is needed — this is how managed OpenClaw containers run it by default:
OPENCLAW_TELEMETRY_TOKEN=oct_... # required
OPENCLAW_TELEMETRY_CLAW=openclaw1 # or CLAW_USERNAME
OPENCLAW_TELEMETRY_URL=https://8examples.com/openclaw/telemetry # optional, this is the defaultEnvironment variables beat the config file key by key.
What it sends
In addition to the health imprint below, the reporter reads completed
assistant calls from ~/.openclaw/agents/*/sessions/*.jsonl and sends one
exactly-once usage record per call: model, input/output, cache read/write, and
the original timestamp. A durable byte-offset checkpoint keeps normal scans
cheap, while a stable usageId lets the receiver deduplicate retries,
container restarts, and renamed reset/deleted transcripts.
POST <url> with Authorization: Bearer <key>:
{
"claws": [
{
"claw": "openclaw1",
"at": "2026-08-13T12:00:00.000Z",
"status": "ok",
"model": "claude-fable-5",
"tokens": { "input": 12000, "output": 3400 },
"errors": [],
"note": "free text",
"host": {
"hostname": "openclaw-vm",
"platform": "linux 6.8.0",
"arch": "x64",
"uptimeHours": 12.5,
"load": [0.1, 0.2, 0.15],
"memFreeMB": 2048,
"memTotalMB": 8192
},
"browser": { "ok": true, "bin": "chromium", "url": "https://example.com/", "ms": 850 },
"portmap": { "ok": true, "url": "https://openclaw1.fusenv.com", "status": 200, "ms": 120 },
"agent": { "name": "openclaw-telemetry", "version": "0.8.0", "latest": "0.8.0", "upToDate": true }
}
]
}Letting the claw speak for itself
The reporter merges ~/.openclaw-telemetry/status.json into every imprint,
so the worker (or anything else on the machine) can keep it current:
{
"status": "ok",
"model": "claude-fable-5",
"tokens": { "input": 12000, "output": 3400 },
"errors": [],
"note": "processed 14 bookings today",
"extra": { "queueDepth": 0 }
}status may be ok, warn, or error; it drives the color of the claw's
tile on the fleet dashboard.
Browser health check
Every imprint also exercises the machine's web browser: the reporter uses
OpenClaw's configured browser path first, then searches PATH and Playwright's
shared browser cache for Chromium, Chrome, Brave, or Edge,
headless-loads a page that should always work — https://example.com/ by
default — and verifies HTML comes back within 30 seconds. The result is
reported as the browser field above; a failure (no binary, launch error,
timeout, or an empty page) also appends a browser: ... line to errors,
which turns the claw's tile amber unless the claw has set its own status.
OPENCLAW_TELEMETRY_BROWSER=off # disable the check
OPENCLAW_TELEMETRY_BROWSER=/usr/bin/chromium # or force a specific binary
OPENCLAW_TELEMETRY_BROWSER_URL=https://... # load this page insteadRun openclaw-telemetry browser-check to print the discovery/launch result
without sending an imprint.
Portmap check
Each claw instance is expected to be reachable at its own subdomain —
<claw>.fusenv.com — for inbound webhooks (e.g. phone-gateway pings). Every
imprint verifies that mapping actually routes: the reporter requests
https://<claw>.fusenv.com and treats any HTTP answer except 404 as
mapped (tunnel and wildcard-DNS catch-alls answer 404; a real claw gateway
answers 200/401/…). No response at all (NXDOMAIN, timeout, TLS failure)
also fails the check. The result is reported as the portmap field; a
failure appends a portmap: ... line to errors, turning the tile amber
until the tunnel ingress + DNS record exist.
OPENCLAW_TELEMETRY_PORTMAP=off # disable the check
OPENCLAW_TELEMETRY_PORTMAP=claw7.example.com # check this hostname instead
OPENCLAW_TELEMETRY_PORTMAP_DOMAIN=example.com # keep <claw>. but change the domainRun openclaw-telemetry portmap-check to print the result without sending
an imprint.
Gateway pipeline check
A container can be "healthy" — gateway ready, channel polling — while every
customer message dies at dispatch. This happened for real after the
OpenClaw 2.0 (2026.8.1) upgrade: pending legacy migrations made each inbound
error with Legacy workspace setup state requires migration while every
other signal looked fine. Each imprint therefore scans the gateway's own log
(/tmp/openclaw/openclaw-<date>.log, last 15 minutes) plus the durable
stability bundles under ~/.openclaw/logs/stability/ for:
- inbound messages erroring at dispatch (
outcome=error) — reported with the last error text and the ok/error dispatch counts - pending legacy migrations (
... requires migration) - plugin capability-consent blocks (
requires capability consent) - gateway startup failures (
Gateway failed to start, stability bundles) - channels held down by the crash-loop breaker (
autostart suppressed) - degraded secret resolution (
SECRETS_DEGRADED— rides along as an error line without failing the check, since model calls can still succeed)
A failing pipeline sets the imprint's default status to error (a status
the claw wrote about itself still wins) and adds a gateway: ... line to
errors; the full result rides along as the gateway field. The paging
kinds are message-dispatch-failing, gateway-blocked and
channel-suppressed — the first one is the "customers are messaging into a
void" page.
OPENCLAW_TELEMETRY_GATEWAY=off # disable the check
OPENCLAW_TELEMETRY_GATEWAY_LOG_DIR=/some/dir # log dir overrideRun openclaw-telemetry gateway-check to print the result without sending
an imprint.
Managed configuration check
A managed claw is handed credentials by its control plane, and its
openclaw.json is what turns each credential into a working route. The two
halves drift apart silently: openclaw doctor --fix deletes keys it does not
recognise as its own, and a provisioner that reconciles owner edits then keeps
the deletion forever. The claw keeps answering while a route someone is paying
for is simply gone.
This reports the one condition that cannot be deleted out of existence: a credential in the environment with no route to use it.
| Finding | Means |
| --- | --- |
| gateway-route-missing | MODEL_GATEWAY_KEY is set but models.providers.gateway is gone, so the claw is billing providers directly |
| gateway-bypassed | the gateway provider exists but no model reference routes through it |
| phone-hook-missing | PHONE_GATEWAY_API_KEY is set but no enabled /hooks/phone mapping exists, so phone-gateway callbacks are dropped |
Findings ride along in the imprint under managed, are added to errors, and
page like the other serious conditions. A claw that was never handed these
credentials reports nothing, so self-hosted installs stay quiet.
openclaw-telemetry managed-config-checkSet OPENCLAW_TELEMETRY_MANAGED_CONFIG=off to skip it.
Version reporting
agent.version in each imprint is the version actually running on the claw.
The reporter also asks the npm registry for the latest published
openclaw-telemetry and adds agent.latest and agent.upToDate, so the
fleet dashboard can show at a glance which claws still run an old release.
If the registry cannot be reached, the two fields are simply omitted — a
flaky npm is not a claw problem.
OPENCLAW_TELEMETRY_REGISTRY=off # skip the lookup
OPENCLAW_TELEMETRY_REGISTRY=https://registry.example.com # private mirrorRun openclaw-telemetry version-check to print
{ "running": ..., "latest": ..., "upToDate": ... } without sending an
imprint.
Surviving reboots
The daemon does not install itself as a system service. Add one line to cron if you want it back after a reboot:
@reboot /usr/bin/env openclaw-telemetry startLicense
MIT
