# Voyage observability — local Docker Compose stack A version-pinned local-development stack for inspecting Voyage v4.1 metrics emitted by `hooks/scripts/otel-export.mjs`. Two complementary paths: | Mode | env var | Pull/push | Container that scrapes | |------|---------|-----------|------------------------| | Prometheus textfile | `VOYAGE_EXPORT_MODE=textfile` | voyage writes `voyage.prom` to `./voyage-textfile/`, node-exporter scrapes | `node-exporter` | | OTLP/HTTP | `VOYAGE_EXPORT_MODE=otlp` | voyage POSTs to `http://localhost:4318/v1/metrics` | `otel-collector` (re-exposed as Prometheus on `:8889`) | Both modes feed Prometheus → Grafana. ## Quickstart ```bash cd examples/observability mkdir -p voyage-textfile docker compose up -d ``` Endpoints (all bound to `localhost`): | Service | URL | |---------|-----| | Prometheus UI | http://localhost:9090 | | Grafana UI | http://localhost:3000 (anonymous Viewer enabled; admin/admin) | | OTLP/HTTP receiver | http://localhost:4318/v1/metrics | | Node Exporter | http://localhost:9100/metrics | | OTel Collector Prometheus exporter | http://localhost:8889/metrics | Stop with `docker compose down`. Add `-v` to wipe Prometheus + Grafana volumes. ## Activating Voyage export In another terminal, set one of the env vars before invoking a Voyage command: ```bash # Path A — textfile mode export VOYAGE_EXPORT_MODE=textfile export VOYAGE_TEXTFILE_DIR="$(pwd)/voyage-textfile" # Path B — OTLP mode export VOYAGE_EXPORT_MODE=otlp export VOYAGE_OTEL_ENDPOINT=http://localhost:4318/v1/metrics export VOYAGE_OTEL_ALLOW_PRIVATE=1 # required: localhost is loopback (RFC1122) ``` The Stop hook (wired in `hooks/hooks.json`) will run `hooks/scripts/otel-export.mjs` automatically at session-end. See `docs/observability.md` for the full env-var matrix and security notes. ## Pinned versions (per research/01) | Component | Image | Pinned to | |-----------|-------|-----------| | Prometheus | `prom/prometheus` | `v3.0.1` | | Node Exporter | `prom/node-exporter` | `v1.10.2` | | Grafana | `grafana/grafana` | `11.4.0` | | OTel Collector (contrib) | `otel/opentelemetry-collector-contrib` | `0.115.0` | These are reference versions for the v4.1 release window; bump only after re-testing the full smoke flow. ## Limitations - Stop-hook export runs at *normal* session end. If Claude Code exits via crash or hard kill, the final metrics for that session are not flushed. Use `--resume` on next start to recover plan/progress state; metrics for the unflushed session will be missing from Prometheus. - The `VOYAGE_OTEL_ALLOW_PRIVATE=1` escape hatch enables sending to RFC1918 addresses (home-lab use). It is **off by default** so accidental internal-network exfiltration is blocked. See `docs/observability.md`. - This stack is for *local development*. Do not expose ports `:9090` / `:3000` / `:4318` outside loopback — Grafana ships with anonymous viewer access enabled and admin/admin credentials.