mirror of
https://github.com/coder/coder.git
synced 2026-10-16 14:48:56 +08:00
## What Implements the web terminal client half of the [Connection log collection and correlation RFC](https://www.notion.so/coderhq/Connection-log-collection-and-correlation-36ed579be5928025a56cd11fe58661fb) (`DEVEX-663`). Generates a per-session correlation ID and attaches it to the web terminal's requests and client logs so a single session can be traced end to end. > Stacked on #27671 (`DEVEX-659`, the coderd tracing middleware that reads the > `client_session_id` baggage). Review/merge that first. ## Changes **Session ID** - 16-byte value encoded as a 32-character hex string, per RFC requirement 1. Generated with the `generateConnectionSessionId` function added in #27935 - Minted once per web terminal session: on `TerminalPage` load and on `AgentsPage` terminal panel mount. Unlike the reconnection token, it is **not** persisted in the URL, so a reload (or a new tab) is a new session, matching the RFC's session definition. **Propagation** - **HTTP API request:** the reconnecting-pty signed-token request carries the ID via W3C baggage (`baggage: client_session_id=<hex>`), which the DEVEX-659 middleware reads. - **PTY WebSocket:** browsers cannot set the `baggage` header on a WebSocket handshake (the codebase already works around this for the session token), so the ID is sent as a `client_session_id` query parameter instead. The reconnecting-pty WebSocket handler reads and validates it and attaches it to the request and PTY logs. **Client logs** - The terminal's connection-error `console.error` logs now include `client_session_id`. **Telemetry:** the web terminal emits none today, so there is nothing to tag (confirmed with the issue reporter). ## Testing - `site`: unit tests for `generateSessionId` (format + uniqueness) and `terminalWebsocketUrl` (query param). Updated `TerminalPage.test.tsx` (mocks the generator to a fixed ID and asserts the WebSocket URL includes `client_session_id`). `tsc`, Biome, and the React Compiler check pass. - `coderd`: `go test ./coderd/tracing/...` and `go vet ./coderd/workspaceapps/...` pass; new `ValidSessionID` export reused by the PTY handler. <details> <summary>Design notes / decision log</summary> - **Session vs reconnection token.** The existing `reconnect` token is deliberately persisted in the URL to survive reloads. `client_session_id` is the opposite: a fresh value per page load, matching the RFC (a reload is a new session). They are separate identifiers. - **Per-request baggage, not a global axios default.** The frontend axios instance is a singleton shared by the whole app; a global `baggage` default would tag unrelated requests. The header is attached only to the terminal's signed-token request. - **WebSocket uses a query param.** Browser `WebSocket` cannot send custom headers, so baggage is impossible on the PTY handshake. The `client_session_id` query parameter is the counterpart, read server-side in `workspaceAgentPTY`. - **Server-side scope.** Reading the query param is localized to the web terminal's own WebSocket handler rather than broadening the shared tracing middleware to trust query params on every route. - **Validation.** Both the baggage and query-param paths validate the value as a 32-char hex string (`tracing.ValidSessionID`) before logging, to avoid logging arbitrary client-controlled input. - **AgentsPage compiler constraint.** `AgentsPage` is React Compiler optimized (no `useMemo`/`useCallback`), so the panel mints its ID with `useState` lazy init instead. - **Out of scope (other RFC tickets):** agent-side middleware, `connection_logs` columns, Tailnet state-change logging, and the CLI `CODER_TRACE_SESSION_ID` env var. </details> --- _Opened by Coder Agents on behalf of @aqandrew._ --------- Co-authored-by: Danielle Maywood <danielle@themaywoods.com>