feat: Propagate OTel tracing context from client to server through websocket#173
Closed
feat: Propagate OTel tracing context from client to server through websocket#173
Conversation
…bsocket Add server-side trace context extraction and span creation so that distributed traces flow end-to-end through River websocket connections. Changes: - Add TransportMessageTracingGetter to extract traceparent/tracestate from incoming TransportMessages (counterpart to existing Setter) - Extract trace context in ServerSession._open_stream_and_call_handler and create a SERVER span that is a child of the client's CLIENT span - Run handler within the extracted context so downstream code inherits the trace - Update and expand tests to verify server spans, trace propagation, span attributes, and independent traces for concurrent RPCs
Collaborator
Author
|
Superseded by a simpler approach that propagates OTel context (traceparent, tracestate, baggage) via standard HTTP headers on the WebSocket upgrade request, rather than per-RPC tracing. ~ written by Zerg 👾 |
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.
Why
The River Python library already injects OpenTelemetry trace context (
traceparent/tracestate) into outgoingTransportMessages on the client side, but the server never extracts this context or creates corresponding server-side spans. This means distributed traces are broken across the websocket boundary — the server has no visibility into which client trace initiated a given RPC.What changed
src/replit_river/rpc.pyTransportMessageTracingGetter— the extraction counterpart to the existingTransportMessageTracingSetter. Implements the OTelGetterprotocol to readtraceparentandtracestatefrom aTransportMessage.tracingfield.src/replit_river/server_session.py_open_stream_and_call_handler(), the server now extracts the incoming trace context from the first message of each stream usingTraceContextTextMapPropagator.extract().SERVERspan (namedriver.server.<method_type>.<service>.<procedure>) that is a child of the client'sCLIENTspan, with attributes for service name, procedure name, method type, stream ID, and client ID._run_handler_with_tracing(), so any downstream OTel instrumentation within the handler automatically inherits the correct parent trace.tests/v1/test_opentelemetry.pytest_rpc_trace_propagation— verifies same trace ID, parent-child relationship, span kindstest_subscription_trace_propagation— verifies propagation for subscriptionstest_upload_trace_propagation— verifies propagation for uploadstest_stream_trace_propagation— verifies propagation for bidirectional streamstest_server_span_has_attributes— verifies span attributes on the server spantest_multiple_rpcs_have_independent_traces— verifies independent RPCs get independent tracesTest plan
All 67 existing tests pass, including the 6 new trace propagation tests:
Key verifications in the new tests:
trace_idparent.span_idmatches client span'sspan_idSpanKind.CLIENT, server spans haveSpanKind.SERVERriver.*attributesRevertibility
This change is safe to revert — it only adds new behavior (server-side span creation) without modifying the wire protocol or any existing client behavior.
~ written by Zerg 👾