Skip to content

Stamp the browser session ID and name onto telemetry events - #456

Merged
masnwilliams merged 2 commits into
mainfrom
hypeship/telemetry-browser-session-id
Oct 15, 2026
Merged

masnwilliams merged 2 commits into
mainfrom
hypeship/telemetry-browser-session-id

Conversation

@masnwilliams

@masnwilliams masnwilliams commented Oct 13, 2026 •

Copy link
Copy Markdown
Contributor

Summary

Browser telemetry exported over OTLP carries kernel.telemetry_session_id and kernel.instance_name, but neither appears anywhere in the public browser API, so exported records can't be joined back to the browser session that produced them.

This lets the control plane tell the instance which browser session owns the capture, and stamps that identity onto every event:

  • PUT/PATCH /telemetry accept a new optional browser_session: {id, name} block (echoed in TelemetryState.config).
  • TelemetrySession stamps each non-empty field into source.metadata as session_id / session_name, next to telemetry_session_id. The OTLP converter already passes metadata through under kernel., so exported log records now carry kernel.session_id and kernel.session_name. The live stream and S2 storage pick them up too.
  • The identity is stamped per event, not as an OTLP resource attribute. A pooled instance serves more than one browser session over its life, and the resource is fixed when the exporter is built. A reconfigure switches the stamp for every event published after it.
  • PUT semantics: full replace, so an omitted block clears the identity. PATCH semantics: per-field merge, so an omitted field is unchanged and "" clears it. A PATCH that carries only browser_session updates the identity without touching capture. The control plane uses this to keep the name current after a rename.

Metadata copy in publishLocked

publishLocked used to write telemetry_session_id into the producer's metadata map in place. The CDP monitor reuses one navMeta map across events, so a stamp written after a reconfigure would also rewrite envelopes already in the ring or in flight to the exporter. With a per-lease browser session ID, that would mislabel earlier events. The stamps now go on a copy of the map, so an envelope keeps the identity it was published under.

Compatibility

  • Older control planes don't send the block, so behavior is unchanged: no session_id / session_name stamps.
  • /telemetry decodes without DisallowUnknownFields, so older images ignore the block when a newer control plane sends it.
  • The control-plane change that sends the block is a separate PR in the platform repo. It can merge before or after this one.

Tests

go test -race $(go list ./... | grep -v /e2e$) passes. go vet ./... is clean.

  • lib/telemetry: identity stamped on every event. Unset fields are omitted. A reconfigure for a new browser session stamps the new ID while the telemetry session ID stays the same. An earlier envelope that shares the producer's metadata map keeps its original identity, and the producer map is not mutated. A new session after a stop carries only its own identity.
  • cmd/api/api: PUT stamps and echoes the identity. A PUT on a running session switches to the new browser session. A PUT without the block clears it. A PATCH merges per field, leaves categories alone, and an empty name clears.
  • lib/events: session_id / session_name metadata maps to kernel.session_id / kernel.session_name on the OTLP record.

E2E tests were not run (they need Docker images).


Note

Medium Risk
Changes telemetry API semantics and event metadata stamping on a hot path; incorrect copy/merge behavior could mislabel exported records, though tests cover PUT/PATCH and reconfigure cases.

Overview
Adds optional browser_session: {id, name} on PUT/PATCH /telemetry so the control plane can tag which browser session owns a capture. Non-empty fields are echoed in TelemetryState.config and stamped on every published event as session_id / session_name in source.metadata (alongside telemetry_session_id), so the live stream, S2 storage, and OTLP export expose kernel.session_id and kernel.session_name.

PUT replaces the identity wholesale (omitted block clears it); PATCH merges per field without touching categories, and a PATCH that only sets browser_session skips reconcile. publishLocked now clones producer metadata before stamping so reused maps and in-flight events keep the identity they had at publish time after reconfigure or lease switches on pooled instances.

Reviewed by Cursor Bugbot for commit ccb0932. Bugbot is set up for automated code reviews on this repo. Configure here.

Accept a browser_session {id, name} block on PUT/PATCH /telemetry and stamp
each non-empty field onto every published event's source metadata as
session_id / session_name. OTLP export passes metadata through, so exported
log records carry kernel.session_id and kernel.session_name.

The identity is per-event rather than an OTLP resource attribute because a
pooled instance serves more than one browser session; a reconfigure switches
the stamp for subsequent events. publishLocked now stamps a copy of the
producer's metadata map, so an envelope already on the bus keeps the identity
it was published under.
Regenerate lib/oapi/oapi.go from the merged openapi.yaml.
@masnwilliams
masnwilliams merged commit 1c749e6 into main Oct 15, 2026
12 checks passed
@masnwilliams
masnwilliams deleted the hypeship/telemetry-browser-session-id branch October 15, 2026 00:39
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.

2 participants