ktg-plugin-marketplace/plugins/voyage/examples/observability
Kjell Tore Guttormsen 48543f63c2 feat(voyage): add examples/observability/ Docker Compose stack — version-pinned per research/01
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.
2026-05-09 09:50:13 +02:00
..
docker-compose.yml feat(voyage): add examples/observability/ Docker Compose stack — version-pinned per research/01 2026-05-09 09:50:13 +02:00
grafana-datasource.yml feat(voyage): add examples/observability/ Docker Compose stack — version-pinned per research/01 2026-05-09 09:50:13 +02:00
otel-collector-config.yaml feat(voyage): add examples/observability/ Docker Compose stack — version-pinned per research/01 2026-05-09 09:50:13 +02:00
prometheus.yml feat(voyage): add examples/observability/ Docker Compose stack — version-pinned per research/01 2026-05-09 09:50:13 +02:00
README.md feat(voyage): add examples/observability/ Docker Compose stack — version-pinned per research/01 2026-05-09 09:50:13 +02:00

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 --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.