Rune Box docs

Observability

`runeward serve` and `runeward controller` expose Prometheus metrics and structured logs, and usage telemetry is opt-in and off by default.

Metrics

The control plane serves GET /metrics on the same listener as the REST API and dashboard. When an API token or RBAC is configured, /metrics needs the token too, so give the scraper a bearer credential. The job_name must contain runeward for the RunewardTargetDown alert to match:

scrape_configs:
  - job_name: runeward
    metrics_path: /metrics
    static_configs:
      - targets: ["localhost:8080"]
Metric Type Labels Meaning
runeward_actions_total counter tool, verdict Governed actions by tool and verdict
runeward_actions_duration_seconds histogram tool Duration of executed governed actions
runeward_sandboxes_created_total counter none Sandboxes created since start
runeward_usage_tokens_total counter profile Model tokens reported via the usage API
runeward_usage_cost_usd_total counter profile Spend (USD) reported via the usage API
runeward_build_info gauge version Always 1; carries the version label
  • verdict is allow, deny, require-approval or error.
  • A label series appears after its first event. A fresh process shows only runeward_build_info and runeward_sandboxes_created_total.
  • The histogram also exposes _bucket (with le), _sum and _count series.

Grafana dashboard

Import deploy/grafana/runeward-dashboard.json via Dashboards → New → Import, and pick your Prometheus datasource for the DS_PROMETHEUS input. Panels: deny ratio, require-approval rate, action rate by verdict, top tools, p95 duration per tool, sandbox creation and build info.

Alerts

Add deploy/prometheus/runeward-alerts.yaml to prometheus.yml, then validate and reload:

rule_files:
  - /etc/prometheus/rules/runeward-alerts.yaml
promtool check rules deploy/prometheus/runeward-alerts.yaml
curl -X POST http://localhost:9090/-/reload
Alert Severity Fires when Indicates
RunewardDenySpike warning deny ratio > 50% for 10m Bad actor or too-strict policy
RunewardHighActionLatency warning p95 duration for a tool > 30s for 10m Backend, sandbox or downstream degraded
RunewardNoActivity info action rate == 0 for 30m Idle, or agents cannot reach the control plane
RunewardTargetDown critical up for a .*runeward.* job == 0 for 5m Control plane down or unreachable

Structured logs

Both services log to stderr via Go's log/slog.

Variable Values Default
RUNEWARD_LOG_FORMAT text, json text
RUNEWARD_LOG_LEVEL debug, info, warn, error info
RUNEWARD_LOG_FORMAT=json RUNEWARD_LOG_LEVEL=info runeward --config-dir examples serve
{"time":"2026-07-04T11:28:37Z","level":"INFO","msg":"request","method":"POST","path":"/v1/citadels","status":200,"duration_ms":142}

/metrics and /healthz are excluded from the access log.

Telemetry

Telemetry is off by default. It runs only when both variables are set, pointing at a collector you control:

export RUNEWARD_TELEMETRY=1
export RUNEWARD_TELEMETRY_ENDPOINT=https://your-collector.example/ingest
  • A truthy DO_NOT_TRACK (convention) always keeps it off.
  • Each service start sends one JSON event with version, os, arch and non-identifying properties, such as whether the dashboard is enabled. No hostnames, paths, profile contents, IDs or device identifier.
  • Sends are best-effort with a 2-second timeout and never block or fail the process.
  • Every serve and controller startup logs the telemetry state.

Written from docs/observability.md at commit 1ee29ff4ab36. Rune Box is open source under Apache-2.0.