Skip to main content

Observability

The agent server exposes runtime metrics for scraping and emits a structured access log for every request, so you can answer "is it healthy, how busy is it, what's failing" without attaching a debugger.

Metrics

GET /api/v1/metrics

Returns server metrics in Prometheus text exposition format by default, or as JSON with ?format=json.

# Prometheus (default) — point a Prometheus/Grafana scraper here
curl http://localhost:8430/api/v1/metrics

# JSON — convenient for ad-hoc inspection or a custom dashboard
curl "http://localhost:8430/api/v1/metrics?format=json"

Prometheus response (Content-Type: text/plain; version=0.0.4):

# HELP wasmrun_agent_exec_total Total code executions by terminal result.
# TYPE wasmrun_agent_exec_total counter
wasmrun_agent_exec_total{result="success"} 12
wasmrun_agent_exec_total{result="error"} 1
wasmrun_agent_exec_total{result="timeout"} 0
# HELP wasmrun_agent_exec_duration_ms_sum Sum of execution wall-clock durations in milliseconds.
# TYPE wasmrun_agent_exec_duration_ms_sum counter
wasmrun_agent_exec_duration_ms_sum 4200
...
# HELP wasmrun_agent_sessions_active Currently active (non-expired) sessions.
# TYPE wasmrun_agent_sessions_active gauge
wasmrun_agent_sessions_active 3

JSON response (?format=json):

{
"exec_total": { "success": 12, "error": 1, "timeout": 0 },
"exec_duration_ms_sum": 4200,
"exec_duration_ms_count": 13,
"output_truncated_total": 0,
"sessions_created_total": 20,
"exec_rejected_total": { "concurrency": 0, "payload": 0, "unauthorized": 0 },
"sessions_active": 3,
"sessions_total": 3,
"exec_in_flight": 1,
"sessions_disk_bytes": 16384
}

Metrics reference

MetricTypeMeaning
wasmrun_agent_exec_total{result}counterExecutions by terminal result: success (ran to completion), error (failed to run), timeout
wasmrun_agent_exec_duration_ms_sumcounterSum of execution wall-clock durations (ms)
wasmrun_agent_exec_duration_ms_countcounterNumber of executions in the sum — pair with _sum for the average
wasmrun_agent_output_truncated_totalcounterExecutions whose captured output hit the --max-output cap
wasmrun_agent_sessions_created_totalcounterSessions created since startup
wasmrun_agent_exec_rejected_total{reason}counterRequests rejected before doing work, by reason: concurrency (429), payload (413), unauthorized (401)
wasmrun_agent_sessions_activegaugeActive (non-expired) sessions right now
wasmrun_agent_sessions_totalgaugeSessions tracked, including expired-but-not-yet-cleaned
wasmrun_agent_exec_in_flightgaugeExec workers currently running
wasmrun_agent_sessions_disk_bytesgaugeTotal on-disk footprint across active sessions (bytes)

Average execution duration is exec_duration_ms_sum / exec_duration_ms_count.

Authentication

When --auth is enabled, /metrics requires a valid API key like every other endpoint, and the scrape is limited to global aggregates — no per-tenant or per-session data — so one tenant cannot infer another's activity. A missing or invalid key returns 401 (and increments exec_rejected_total{reason="unauthorized"}).

Per-session breakdown (open mode only)

In open mode (no --auth), the JSON format adds a sessions array with each active session's disk footprint and configured memory cap:

{
"...": "...",
"sessions": [
{ "id": "a1b2c3...", "disk_bytes": 8192, "memory_cap_pages": 4096 }
]
}

memory_cap_pages is in WASM pages (64 KiB each); null means unlimited. This breakdown is not emitted in the Prometheus format (session ids would be unbounded-cardinality labels) and is withheld entirely when auth is enabled — leaving only the aggregate sessions_disk_bytes gauge.

Access Log

The server writes one structured key=value line to stderr for every request, always on:

ts=2026-06-13T11:18:55.354+00:00 id=d5aafbe6c56c32ec method=POST path=/api/v1/sessions status=200 dur_ms=1 tenant=-
FieldMeaning
tsRFC 3339 timestamp
idRequest id — also returned as the X-Request-Id response header
methodHTTP method
pathRequest path
statusHTTP status code
dur_msHandling duration in milliseconds
tenantAuthenticated tenant id, or - in open mode / before auth resolves

Running with -v, --verbose adds a request-received line (→ METHOD url (id=...)) ahead of each response line; the structured access line is emitted either way.

Request correlation

Every response carries an X-Request-Id header matching the id in the access log, so a client can tie a response back to its server-side log line:

curl -i http://localhost:8430/api/v1/metrics | grep -i x-request-id
# X-Request-Id: 37dffe5b315dcd30