Step 14 of v4.1 — local-development observability stack with version-pinned container images: - prom/prometheus:v3.0.1 - prom/node-exporter:v1.10.2 (textfile collector enabled) - grafana/grafana:11.4.0 - otel/opentelemetry-collector-contrib:0.115.0 Two complementary export paths from voyage hooks/scripts/otel-export.mjs: - VOYAGE_EXPORT_MODE=textfile → node-exporter textfile collector - VOYAGE_EXPORT_MODE=otlp → otel-collector OTLP/HTTP receiver (:4318) Both feed Prometheus → Grafana. Files: examples/observability/docker-compose.yml examples/observability/otel-collector-config.yaml examples/observability/prometheus.yml examples/observability/grafana-datasource.yml examples/observability/README.md Verified manifest expected_paths (5 files). docker compose config validation runs in Step 16 with proper skip-pattern when docker is unavailable. |
||
|---|---|---|
| .. | ||
| docker-compose.yml | ||
| grafana-datasource.yml | ||
| otel-collector-config.yaml | ||
| prometheus.yml | ||
| README.md | ||
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
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:
# 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_OTLP_ENDPOINT=http://localhost:4318/v1/metrics
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
--resumeon next start to recover plan/progress state; metrics for the unflushed session will be missing from Prometheus. - The
VOYAGE_OTEL_ALLOW_PRIVATE=1escape hatch enables sending to RFC1918 addresses (home-lab use). It is off by default so accidental internal-network exfiltration is blocked. Seedocs/observability.md. - This stack is for local development. Do not expose ports
:9090/:3000/:4318outside loopback — Grafana ships with anonymous viewer access enabled and admin/admin credentials.