← knowledge.oriz.in

Langfuse Cloud chosen as OTEL observability backend for Claude Code + OpenCode

decision agent-toolingobservabilityotellangfusedecision

Langfuse observability — 2026-07-06

Decision

Adopt Langfuse Cloud Hobby tier as the OTEL sink for both Claude Code and OpenCode. Wired via two OpenTelemetry standard env vars per agent; values resolve through the existing .env → user env → process.env sync chain, so secrets never appear in repo.

Why Langfuse (vs LangSmith vs others)

How it works

.env (encrypted)                              # LANGFUSE_PUBLIC_KEY, LANGFUSE_SECRET_KEY, LANGFUSE_OTEL_HEADERS
  ↓ scripts/sync-env-to-system-env.ps1        # Windows Scheduled Task, logon + 09:00 daily
user-scope Windows env vars
  ↓ inherited by every new process
Claude Code  → reads OTEL_EXPORTER_OTLP_ENDPOINT  +  OTEL_EXPORTER_OTLP_HEADERS  → POSTs traces
OpenCode     → reads OTEL_EXPORTER_OTLP_ENDPOINT  +  OTEL_EXPORTER_OTLP_HEADERS  → POSTs traces
              ↓
        Langfuse Cloud Hobby project

Three config layers, additive only:

  1. repos/private/agent-configs/agents/claude/settings.json — env block adds:

    • OTEL_EXPORTER_OTLP_ENDPOINT: ${env:OTEL_EXPORTER_OTLP_ENDPOINT} — same env-expansion pattern used for ANTHROPIC_AUTH_TOKEN on the canonical line 14; the actual URL is in user env, derived by sync-env per region.
    • OTEL_EXPORTER_OTLP_HEADERS: ${env:OTEL_EXPORTER_OTLP_HEADERS} — secret via env expansion; no manual base64.
  2. repos/private/agent-configs/agents/opencode/opencode.json — NO explicit env block added. OpenCode inherits OTEL_EXPORTER_OTLP_* from the launching shell (Windows env propagation), so the same user-env values land there too.

  3. .env.example — new "Langfuse" section at the tail:

    • LANGFUSE_HOST= (user sets their region: https://us.cloud.langfuse.com or https://eu.cloud.langfuse.com)
    • LANGFUSE_PUBLIC_KEY=
    • LANGFUSE_SECRET_KEY=
    • LANGFUSE_BASE_URL is also accepted as an alias for LANGFUSE_HOST (matches Langfuse SDK docs naming).

Region handling (added 2026-07-06 after first activation)

Langfuse region-routes accounts since 2025. The regional direct host (us.cloud.langfuse.com or eu.cloud.langfuse.com) is the documented production endpoint per https://langfuse.com/docs; using the regional host removes any cross-region redirect from the OTEL path and is faster. Avoid hardcoding the generic https://cloud.langfuse.com because it redirects at the gateway layer and adds an avoidable hop.

scripts/sync-env-to-system-env.ps1 automatically appends /api/public/otel to LANGFUSE_HOST (or LANGFUSE_BASE_URL) and exports OTEL_EXPORTER_OTLP_ENDPOINT to user env. Both CC and OpenCode pick it up via shell env inheritance (CC additionally has ${env:...} expansion in its env block; OpenCode relies on default shell propagation), so a single .env change lights up the entire fleet.

Verification

scripts/verify-langfuse-otel.ps1 posts a minimal OTLP-shaped trace to https://cloud.langfuse.com/api/public/otel/v1/traces using creds from user env, prints HTTP status + trace ID, exits non-zero on failure. Run after signup to confirm the chain is wired.

Known gaps (out of scope this commit)

Activation checklist (user-side)

scripts/sync-env-to-system-env.ps1 (extended 2026-07-06) auto-derives BOTH OTEL_EXPORTER_OTLP_HEADERS (from LANGFUSE_PUBLIC_KEY:LANGFUSE_SECRET_KEY base64) AND OTEL_EXPORTER_OTLP_ENDPOINT (from LANGFUSE_HOST or LANGFUSE_BASE_URL + /api/public/otel). The user does NOT pre-compute anything.

  1. Sign up at https://langfuse.com (free, no card). Email or GitHub OAuth. Note the regional host Langfuse returns (e.g. https://us.cloud.langfuse.com or https://eu.cloud.langfuse.com).
  2. Create a project (e.g. "chirag127-fleet").
  3. Settings → API Keys → Create new key pair → copy both pk-lf-… and sk-lf-….
  4. Paste three values into local .env (gitignored, encrypted to .env.enc via sops):
    • LANGFUSE_HOST=https://<us|eu>.cloud.langfuse.com (the regional host, NOT the generic cloud.langfuse.com)
    • LANGFUSE_PUBLIC_KEY=pk-lf-…
    • LANGFUSE_SECRET_KEY=sk-lf-…
  5. pwsh C:\d\ws\scripts\sync-env-to-system-env.ps1 -Verbose — propagates LANGFUSE_* to user env AND auto-derives both OTEL_* user-scope env vars.
  6. pwsh C:\d\ws\scripts\verify-langfuse-otel.ps1 -Verbose — confirms HTTP 200 with traceId.
  7. Run Claude Code / OpenCode as usual — traces appear in the Langfuse dashboard at the regional host, under the project.

Cross-refs