Skip to content
Browse docs
On this page

Observability

For deployment and a verified test path, use Configure observability. For one task's progress and result, use Observe agent work.

Holon keeps telemetry work bounded:

  • completed spans enter an in-memory recent ring;
  • selected slow, failed, cancelled, or sampled traces may be retained in diagnostics.sqlite;
  • optional OTLP export uses a bounded non-blocking queue;
  • OpenMetrics exposes a fixed set of label-free holon_* series.

Exporter or collector failure does not block turns, tools, persistence, or delivery. Exporter drop and failure counters identify degraded telemetry.

Export traces with OTLP/HTTP

The configuration object is runtime.observability.otlp in <HOLON_HOME>/config.json:

{
  "enabled": true,
  "endpoint": "http://127.0.0.1:4318/v1/traces",
  "queue_capacity": 1024,
  "batch_size": 128,
  "batch_interval_ms": 1000,
  "timeout_ms": 5000
}
FieldContract
enabledEnables the optional exporter; disabled by default
endpointExplicit HTTP or HTTPS trace endpoint, required when enabled
queue_capacityBound on the non-blocking export queue
batch_sizeExport batch size
batch_interval_msBatch interval in milliseconds
timeout_msExport request timeout in milliseconds
credential_profileOptional credential-store profile used for bearer authentication
headersStatic non-secret headers; do not combine an authorization header with credential_profile

Restart the daemon after changing OTLP settings. Store collector tokens with holon config credentials set --kind bearer_token --stdin PROFILE; reference the profile rather than writing the token into configuration.

The baseline Collector configuration at docs/website/assets/observability/otel-collector.yaml accepts OTLP/HTTP JSON on port 4318 and uses the debug exporter. It listens on 0.0.0.0; restrict its bind address or network access for your deployment.

Scrape protected OpenMetrics

PropertyValue
RouteGET /api/control/runtime/metrics
AuthenticationSame control-plane authentication as other /api/control/* routes
Content typeapplication/openmetrics-text; version=1.0.0; charset=utf-8
Terminator# EOF
CardinalityFixed series-count ceiling, no labels

Trace IDs, agent IDs, model names, URLs, error text, and other high-cardinality values never become metric labels. Keep the control endpoint on loopback or a private network. Do not embed its bearer token in dashboard JSON or scrape configuration text.

The baseline docs/website/assets/observability/prometheus.yaml reads the token from /run/secrets/holon-control-token, scrapes 127.0.0.1:7878, and loads rules from /etc/prometheus/holon-alerts.yaml. These are deployment paths to configure, not files Holon installs automatically.

Install the dashboard and alerts

The setup guide contains installation and validation steps. The maintained assets are:

AssetContents
docs/website/assets/observability/grafana-dashboard.jsonUptime, turn p50/p95/p99, projection-gate pressure, diagnostics writer queue/drops/failures, and OTLP queue/export/drop/failure panels
docs/website/assets/observability/holon-alerts.yamlBaseline Prometheus alert rules

Alert thresholds are starting points, not universal service-level objectives. Tune turn latency and alert duration for the observed workload.

Diagnose telemetry failures

SignalWhat it distinguishes
holon_process_uptime_secondsReachable scrape target and process age
holon_otlp_exporter_failed_batches_totalCollector, credentials, TLS, or endpoint failures
holon_otlp_exporter_dropped_spans_totalLost exported telemetry under pressure
holon_otlp_exporter_queue_depthPending export backlog
holon_diagnostics_writer_dropped_traces_totalDropped local retention work
holon_diagnostics_writer_failures_totalLocal diagnostic persistence failures

Local trace retention is independent of OTLP export. Use holon debug trace --search MESSAGE_OR_TURN_ID, then holon debug trace TRACE_ID for a matching retained trace. Sampling and retention policy determine whether one exists. See the diagnosis workflow before changing or restarting telemetry services.

Runtime performance snapshots

GET /api/control/runtime/performance returns a protected JSON snapshot of process-lifetime performance counters. Restarting the daemon resets these counters; snapshot comparisons should use the same process lifetime.

Metric groups

GroupExamples
turn.*turn.total, turn.context_build, turn.provider_round, turn.tool_execution, turn.cleanup
provider.*provider.request_build, provider.round_total, provider.retry
tool.executionCumulative tool timing
storage.*storage.append_event, storage.persist_state
projection.agent_state.*Task, timer, WorkItem, wait, and external-trigger projection work
projection.agents_listAgent-list projection time
http.*Per-route HTTP timing
scheduler.*scheduler.poll.all, .message, .idle, .stopped, and other scheduler phases

The snapshot includes additional subsystem counters. The table is a guide to families, not an exhaustive registry.

Metric fields

FieldMeaning
nameMetric identifier
countRecorded calls
total_msCumulative elapsed milliseconds
max_msMaximum recorded duration
avg_msMean duration
p50_ms, p95_ms, p99_msHistogram-derived duration percentiles
total_bytes, avg_bytesOptional byte totals and mean for metrics recording byte counts

Capture before/after snapshots for a reproducible operation rather than restarting solely to clear metrics. A high idle-poll count can be normal when no agents have runnable work.