feat(observability): parse client session_id out of JSON-encoded metadata.user_id#248
Merged
Merged
Conversation
…data.user_id
Claude Code (post 0.x) sends metadata.user_id as a stringified JSON
object — e.g. {"device_id":"…","session_id":"<uuid>","account_id":"…"} —
so the previous regex-only extractor returned a truncated blob starting
with "{\"device_id\":\"…" instead of the bare session UUID. Operators
running /status in Claude Code can now grep router logs by the UUID the
client shows them.
ClientSessionID now probes session_id / sessionId / conversation_id /
conversationId when the raw value parses as a JSON object, then falls
through to the existing regex + truncation behavior for non-JSON forms.
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.
Summary
Claude Code (post 0.x) sends
metadata.user_idas a stringified JSON object — e.g.{\"device_id\":\"...\",\"session_id\":\"<uuid>\",\"account_id\":\"...\"}. The previous extractor (shipped in #247) regex-matched on the raw string and, because that JSON is longer than 64 chars, returned a truncated blob starting with{\"device_id\":\"…instead of the bare session UUID. Result:client_session_idwas in the logs, but the value the user sees in Claude Code's/statusdidn't grep.This PR makes
ClientSessionIDtry JSON-parsing first when the raw value looks like a JSON object, probing the well-known session-id field names in order —session_id,sessionId,conversation_id,conversationId— and only falling through to the existing regex + truncation behavior when nothing matches.Test plan
go test ./internal/translate/... ./internal/proxy/... -count=1wv mr tcsession_id→ bare UUIDsessionId(camelCase) → bare UUIDclient_session_id=<bare-uuid>in prod logs (no leading{), matching/statusUUID in Claude Code.🤖 Generated with Claude Code