Point Claude Code's telemetry at the local collector - #69
Merged
Conversation
`authbridge exec --with-claude-otel` gives the hosted command the variables that make Claude Code export traces: CLAUDE_CODE_ENABLE_TELEMETRY, CLAUDE_CODE_ENHANCED_TELEMETRY_BETA, the OTEL_* transport settings, and OTEL_EXPORTER_OTLP_ENDPOINT built from httpEndpoint in ~/.config/rossoctl/otel-config.yaml. Reading that record rather than assuming a port means the flag fails, naming `otel collect`, when no collector has been started here — a child pointed at an absent collector drops spans silently. --otel-endpoint overrides the endpoint with a full URL, for a collector this host did not start; the record is then not read at all. It sets one of the variables --with-claude-otel turns on, so passing it alone is an error rather than an implied opt-in. The scheme is checked by prefix before url.Parse, because a bare host:port otherwise fails with "first path segment in URL cannot contain colon", which describes the parser instead of naming the fix. The recorded httpEndpoint is now 127.0.0.1:4318 rather than 0.0.0.0:4318. The receiver still binds the wildcard inside the container, where loopback would be unreachable through a published port, but the recorded value is consumed as a destination: it becomes an OTEL_EXPORTER_OTLP_ENDPOINT, and an exporter sending to http://0.0.0.0:4318 relies on the platform reinterpreting it. The rewrite also runs on read, so a record written before this change still yields a usable URL. The environment is layered onto host.env, which is nil when no forward proxy runs and means "inherit" to exec.Cmd. It is expanded first: appending to the nil would have given the child only these variables, with no PATH. An already-exported variable is kept and reported, as the proxy and CA settings are. Also ignores mlflow.db, the backing store `mlflow server` writes into the working directory. Assisted by Claude. Signed-off-by: Ed Snible <snible@us.ibm.com>
1 task
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Adds
authbridge exec --with-claude-otel, which gives the hosted command the variables that make Claude Code export traces to a local collector:rossoctl otel collect rossoctl authbridge exec --with-claude-otel --config ./authbridge.yaml -- claudeOTEL_EXPORTER_OTLP_ENDPOINTis built fromhttpEndpointin~/.config/rossoctl/otel-config.yaml; the rest are static. Reading that record rather than assuming a port means the flag fails, namingotel collect, when no collector has been started here.--otel-endpoint <url>overrides the endpoint for a collector this host did not start, and then the record is not read at all. It requires--with-claude-otel, since it sets one of the variables that flag turns on.Also changes the recorded
httpEndpointto127.0.0.1:4318from0.0.0.0:4318. The receiver still binds the wildcard inside the container — loopback there is unreachable through a published port — but the recorded value is consumed as a destination, andhttp://0.0.0.0:4318is not one. The rewrite runs on read too, so existing records still work.Plus a
.gitignoreentry formlflow.db.Verified end to end: a child launched with the flag POSTed a span to its own
$OTEL_EXPORTER_OTLP_ENDPOINT/v1/tracesand the running collector logged it.Assisted by Claude.