Skip to content

feat(gax): Implement trace context extraction and injection interceptors#12310

Open
westarle wants to merge 1 commit intogoogleapis:mainfrom
westarle:trace-propagation-interceptors
Open

feat(gax): Implement trace context extraction and injection interceptors#12310
westarle wants to merge 1 commit intogoogleapis:mainfrom
westarle:trace-propagation-interceptors

Conversation

@westarle
Copy link
Copy Markdown
Contributor

@westarle westarle commented Mar 30, 2026

@westarle westarle requested a review from a team as a code owner March 30, 2026 15:56
Copy link
Copy Markdown
Contributor

@gemini-code-assist gemini-code-assist bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Code Review

This pull request introduces OpenTelemetry trace propagation for both gRPC and HTTP/JSON callables. It adds new interceptors, GrpcTracePropagationInterceptor and HttpJsonTracePropagationInterceptor, which inject W3C trace context into request headers when OpenTelemetry is detected on the classpath. The PR also updates various callable implementations to wrap call executions within an ApiTracer.Scope and provides a concrete implementation of the inScope method in SpanTracer. Review feedback suggests adding debug-level logging when OpenTelemetry classes or methods are unavailable to improve observability during troubleshooting.

Comment on lines +63 to +65
// OpenTelemetry API is not available
isOpentelemetryAvailable = false;
}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

medium

Catching ClassNotFoundException and silently ignoring it can make debugging difficult if OpenTelemetry is expected to be available but isn't. Consider logging this exception at a debug level to provide more insight into why OpenTelemetry might not be found.

@westarle westarle force-pushed the trace-propagation-interceptors branch from 7dfaa9f to 65a795f Compare March 30, 2026 18:23
@Override
public void start(ClientCall.Listener<RespT> responseListener, Metadata headers) {
try {
TextMapPropagator propagator = W3CTraceContextPropagator.getInstance();
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think we can extract this logic to a common place such as SpanTracer.injectTracerId(). Call it in GrpcClientCalls and HttpJsonClientCallImpl where we have access to both ApiTracer and request headers.

This avoids creating interceptors for both transports and reuse similar logics.

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks a lot better now!

@westarle westarle force-pushed the trace-propagation-interceptors branch 3 times, most recently from 9eafa4f to 5017179 Compare April 1, 2026 04:25
@westarle westarle requested a review from blakeli0 April 1, 2026 05:22

@Override
public void injectTraceContext(java.util.Map<String, String> carrier) {
if (!isOpenTelemetryAvailable()) {
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We can assume OpenTelemetry is available here now. There would be compilation errors if SpanTracerFactory is passed in but OpenTelemetry is not available.

clientCall.start(
new ResponseObserverAdapter(),
HttpJsonMetadata.newBuilder().build().withHeaders(context.getExtraHeaders()));
HttpJsonClientCalls.getMetadataWithTraceContext(httpJsonContext));
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It looks good but we haven't fully implemented traces for Streaming calls yet. It may not be easy to test it.

</parent>

<dependencies>
<dependency>
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I don't think opentelemetry dependency is needed now since the logic is wrapped in SpanTracer. Same comment for the pom in httpjson.

@westarle westarle force-pushed the trace-propagation-interceptors branch from 5017179 to b020910 Compare April 2, 2026 02:55
@@ -196,6 +196,9 @@ default void requestSent() {}
default void batchRequestSent(long elementCount, long requestSize) {}
;

/** Extract the trace context from the tracer and add it to the given headers map. */
default void injectTraceContext(java.util.Map<String, String> carrier) {}
Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We should implement this in CompositeTracer now that #12321 is merged.

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