Skip to content

feat(claude-otel-collector): dedicated collector for Claude Code telemetry#104

Merged
CptSchnitz merged 1 commit into
masterfrom
feat/claude-otel-collector
Jul 16, 2026
Merged

feat(claude-otel-collector): dedicated collector for Claude Code telemetry#104
CptSchnitz merged 1 commit into
masterfrom
feat/claude-otel-collector

Conversation

@razbroc

@razbroc razbroc commented Jul 9, 2026

Copy link
Copy Markdown
Contributor

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):

  • Traffic stays off the common collector (infra-otel), which serves airgapped networks.
  • No Prometheus configuration changes — no remote-write receiver flag; discovery via standard pod annotations.

Design

  • Wraps upstream opentelemetry-collector 0.111.0 (same as otel-collectors) + org openshift-routes chart.
  • OTLP HTTP receiver (4318) → prometheus exporter on 8889 with resource_to_telemetry_conversion (user_email/model/session_id become labels). The exporter's accumulator converts Claude Code's delta-temporality sums to cumulative.
  • Single replica, autoscaling off: the exporter accumulates counters in pod memory; multiple replicas would split them.
  • Pod annotations point scraping at 8889 (trade-off: the collector's own 8888 self-metrics are not scraped for this instance).
  • Bundled edge route → otlp-http named port; unused pipelines/ports (traces, logs, jaeger, zipkin, debug) disabled.
  • Registered in release-please config.

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

…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>
Copilot AI review requested due to automatic review settings July 9, 2026 13:09

Copilot AI left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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-collector wrapper 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-please configuration 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.

Comment on lines +58 to +62
# 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:
Comment on lines +79 to +83
name: infra-claude-otel
port: otlp-http
tls:
termination: edge
insecureEdgeTerminationPolicy: Redirect

@CptSchnitz CptSchnitz left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

two points that are not really blocking:

  1. i would consider using processors like resource, filter and transform to remove labels, drop metrics, and change them so they fit your needs. it might be a process, not right now.
  2. when you actually deploy it at helm chart or wherever you want, give it an actual domain with DNS so its easy to use.

Comment on lines +42 to +44
jaeger: null
zipkin: null
prometheus: null

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

pretty sure you can just omit those. no need for null.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same as above, you can just remove

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

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.

@razbroc

razbroc commented Jul 13, 2026

Copy link
Copy Markdown
Contributor Author

Addressed the review — point by point:

1. Real DNS domain ✅ done. claude-metric-collector.mapcolonies.net (record created) is now set as the prod route host with the org wildcard cert, mirroring the prometheus route pattern — in the site-values overlay where env-specific hosts live: MapColonies/site-values@14b554d on PR #252. Dev keeps the router-default host since the *.mapcolonies.net cert wouldn't match an apps.* hostname.

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 (os_version, host_arch, ...). This also addresses Copilot's cardinality comment; user_email itself is a deliberate product decision (the dashboard's purpose is per-user attribution).

3. Nulls — replied inline: they're required by Helm value coalescing (omitting inherits the upstream chart defaults; null is the upstream-documented way to remove them).

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 (haproxy.router.openshift.io/ip_whitelist) if we know the org egress CIDRs; the collector also supports bearer-token auth extensions if we want something stronger. @CptSchnitz — preference?

@CptSchnitz
CptSchnitz merged commit 964b7cc into master Jul 16, 2026
23 checks passed
@CptSchnitz
CptSchnitz deleted the feat/claude-otel-collector branch July 16, 2026 11:19
@razbroc

razbroc commented Jul 16, 2026

Copy link
Copy Markdown
Contributor Author

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

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

4 participants