feat(claude-otel-collector): dedicated collector for Claude Code telemetry#104
Conversation
…metry, scraped by Prometheus Single-replica OTel collector wrapper chart: OTLP HTTP ingest, prometheus exporter on 8889 (pod-annotation scraped), bundled edge route to otlp-http. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
There was a problem hiding this comment.
Pull request overview
Introduces a new wrapper Helm chart (claude-otel-collector) to run a dedicated OpenTelemetry Collector instance for ingesting Claude Code telemetry via OTLP/HTTP and exposing Prometheus-scrapable metrics, keeping this traffic isolated from the shared collector.
Changes:
- Added a new
claude-otel-collectorwrapper chart that configures OTLP/HTTP ingest and a Prometheus exporter endpoint for scraping. - Added an OpenShift edge route for external OTLP/HTTP access to the collector.
- Registered the new chart package in
release-pleaseconfiguration for automated Helm releases.
Reviewed changes
Copilot reviewed 3 out of 3 changed files in this pull request and generated 2 comments.
| File | Description |
|---|---|
| release-please-config.json | Registers the new chart for release-please Helm releases. |
| charts/claude-otel-collector/values.yaml | Collector configuration (receivers/exporters/pipeline), scrape annotations, and OpenShift route wiring. |
| charts/claude-otel-collector/Chart.yaml | Declares the wrapper chart metadata and dependencies (opentelemetry-collector, openshift-routes). |
💡 Add Copilot custom instructions for smarter, more guided reviews. Learn how to get started.
| # Claude Code metric attributes (user.email, model, session.id...) | ||
| # arrive as resource attributes and must become Prometheus labels | ||
| resource_to_telemetry_conversion: | ||
| enabled: true | ||
| service: |
| name: infra-claude-otel | ||
| port: otlp-http | ||
| tls: | ||
| termination: edge | ||
| insecureEdgeTerminationPolicy: Redirect |
CptSchnitz
left a comment
There was a problem hiding this comment.
two points that are not really blocking:
| jaeger: null | ||
| zipkin: null | ||
| prometheus: null |
There was a problem hiding this comment.
pretty sure you can just omit those. no need for null.
There was a problem hiding this comment.
The nulls are load-bearing here because of Helm value coalescing: omitting a key doesn't remove it — it inherits the upstream chart's default. The upstream opentelemetry-collector chart ships default jaeger/zipkin/prometheus receivers (and grpc under otlp), so without null they come back in the rendered config. Setting them to null is the upstream chart's documented way to remove default components. Easy to see with helm template: the coalesce.go warnings are exactly these nulls deleting chart defaults.
| - "https://*" | ||
| endpoint: ${env:MY_POD_IP}:4318 | ||
| exporters: | ||
| debug: null |
There was a problem hiding this comment.
same as above, you can just remove
There was a problem hiding this comment.
Same as above — these nulls delete the upstream chart's default traces/logs pipelines (and debug exporter). Omitting them would leave the collector running two extra default pipelines wired to the debug exporter.
|
Addressed the review — point by point: 1. Real DNS domain ✅ done. 2. resource/filter/transform processors — agreed as follow-up. Once we have a few weeks of real data we'll allowlist the labels the dashboard actually uses and drop the noisy ones ( 3. Nulls — replied inline: they're required by Helm value coalescing (omitting inherits the upstream chart defaults; 4. Route authentication (Copilot's point, worth a human decision): the OTLP ingest route is currently unauthenticated — worst case is junk-metric injection, not data exposure. Cheapest mitigation is an IP allowlist on the route ( |
|
Closing the route-auth question: access is controlled at the network layer — the routes are reachable only over the org VPN, same as every other org route. No application-layer auth needed; recorded in the ADR. (The other review points — env-specific overlay files instead of the base conditional, deduped resources, 2 prod replicas — are addressed in MapColonies/site-values#252, commit a61d6d1, deployed and verified: both prod pods scraped as separate targets.) |
What
New wrapper chart
claude-otel-collector: a dedicated, single-purpose OpenTelemetry Collector that ingests Claude Code telemetry pushed from developer laptops and exposes it for Prometheus to scrape (native pull mode).Per infra review of the previous remote-write approach (MapColonies/site-values#246):
infra-otel), which serves airgapped networks.Design
opentelemetry-collector0.111.0 (same asotel-collectors) + orgopenshift-routeschart.prometheusexporter on 8889 withresource_to_telemetry_conversion(user_email/model/session_id become labels). The exporter's accumulator converts Claude Code's delta-temporality sums to cumulative.otlp-httpnamed port; unused pipelines/ports (traces, logs, jaeger, zipkin, debug) disabled.Verified
Installed from this branch into infra-dev and verified end-to-end: real Claude Code session → route → collector → pod-annotation scrape →
claude_code_*series queryable in dev Prometheus with all dashboard-25255 labels.Companion PR: MapColonies/site-values (helmfile release
infra-claude-otel).🤖 Generated with Claude Code