2727import io .opentelemetry .api .common .AttributeKey ;
2828import io .opentelemetry .api .trace .Span ;
2929import io .opentelemetry .context .Context ;
30+ import io .opentelemetry .context .Scope ;
3031import io .opentelemetry .javaagent .instrumentation .hypertrace .netty .v4_0 .AttributeKeys ;
3132import io .opentelemetry .javaagent .instrumentation .hypertrace .netty .v4_0 .DataCaptureUtils ;
3233import java .nio .charset .Charset ;
3334import java .util .HashMap ;
3435import java .util .Map ;
36+
37+ import io .opentelemetry .javaagent .instrumentation .hypertrace .netty .v4_0 .client .OtelHttpClientRequestTracingHandler ;
3538import org .hypertrace .agent .core .config .InstrumentationConfig ;
3639import org .hypertrace .agent .core .instrumentation .HypertraceSemanticAttributes ;
3740import org .hypertrace .agent .core .instrumentation .buffer .BoundedBuffersFactory ;
@@ -57,47 +60,55 @@ public void channelRead(ChannelHandlerContext ctx, Object msg) {
5760 ctx .fireChannelRead (msg );
5861 return ;
5962 }
60- Span span = Span .fromContext (context );
6163
62- if (msg instanceof HttpRequest ) {
63- HttpRequest httpRequest = (HttpRequest ) msg ;
6464
65- Map < String , String > headersMap = headersToMap ( httpRequest );
66- if ( instrumentationConfig . httpHeaders (). request ()) {
67- headersMap . forEach ( span :: setAttribute );
68- }
69- // used by blocking handler
70- channel . attr ( AttributeKeys . REQUEST_HEADERS ). set ( headersMap );
65+ // Store the server context in our ThreadLocal for later use by client handlers
66+ // This is CRITICAL for proper context propagation to client spans
67+ OtelHttpClientRequestTracingHandler . storeServerContext ( context );
68+
69+ try ( Scope ignored = context . makeCurrent ()) {
70+ Span span = Span . fromContext ( context );
7171
72- CharSequence contentType = DataCaptureUtils .getContentType (httpRequest );
73- if (instrumentationConfig .httpBody ().request ()
74- && contentType != null
75- && ContentTypeUtils .shouldCapture (contentType .toString ())) {
72+ if (msg instanceof HttpRequest ) {
73+ HttpRequest httpRequest = (HttpRequest ) msg ;
7674
77- CharSequence contentLengthHeader = DataCaptureUtils .getContentLength (httpRequest );
78- int contentLength = ContentLengthUtils .parseLength (contentLengthHeader );
75+ Map <String , String > headersMap = headersToMap (httpRequest );
76+ if (instrumentationConfig .httpHeaders ().request ()) {
77+ headersMap .forEach (span ::setAttribute );
78+ }
79+ // used by blocking handler
80+ channel .attr (AttributeKeys .REQUEST_HEADERS ).set (headersMap );
7981
80- String charsetString = ContentTypeUtils .parseCharset (contentType .toString ());
81- Charset charset = ContentTypeCharsetUtils .toCharset (charsetString );
82+ CharSequence contentType = DataCaptureUtils .getContentType (httpRequest );
83+ if (instrumentationConfig .httpBody ().request ()
84+ && contentType != null
85+ && ContentTypeUtils .shouldCapture (contentType .toString ())) {
8286
83- // set the buffer to capture response body
84- // the buffer is used byt captureBody method
85- Attribute <BoundedByteArrayOutputStream > bufferAttr =
86- ctx .channel ().attr (AttributeKeys .REQUEST_BODY_BUFFER );
87- bufferAttr .set (BoundedBuffersFactory .createStream (contentLength , charset ));
87+ CharSequence contentLengthHeader = DataCaptureUtils .getContentLength (httpRequest );
88+ int contentLength = ContentLengthUtils .parseLength (contentLengthHeader );
8889
89- channel .attr (AttributeKeys .CHARSET ).set (charset );
90+ String charsetString = ContentTypeUtils .parseCharset (contentType .toString ());
91+ Charset charset = ContentTypeCharsetUtils .toCharset (charsetString );
92+
93+ // set the buffer to capture response body
94+ // the buffer is used byt captureBody method
95+ Attribute <BoundedByteArrayOutputStream > bufferAttr =
96+ ctx .channel ().attr (AttributeKeys .REQUEST_BODY_BUFFER );
97+ bufferAttr .set (BoundedBuffersFactory .createStream (contentLength , charset ));
98+
99+ channel .attr (AttributeKeys .CHARSET ).set (charset );
100+ }
90101 }
91- }
92102
93- if ((msg instanceof HttpContent || msg instanceof ByteBuf )
94- && instrumentationConfig .httpBody ().request ()) {
95- Charset charset = channel .attr (AttributeKeys .CHARSET ).get ();
96- if (charset == null ) {
97- charset = ContentTypeCharsetUtils .getDefaultCharset ();
103+ if ((msg instanceof HttpContent || msg instanceof ByteBuf )
104+ && instrumentationConfig .httpBody ().request ()) {
105+ Charset charset = channel .attr (AttributeKeys .CHARSET ).get ();
106+ if (charset == null ) {
107+ charset = ContentTypeCharsetUtils .getDefaultCharset ();
108+ }
109+ DataCaptureUtils .captureBody (
110+ span , channel , AttributeKeys .REQUEST_BODY_BUFFER , msg , null , charset );
98111 }
99- DataCaptureUtils .captureBody (
100- span , channel , AttributeKeys .REQUEST_BODY_BUFFER , msg , null , charset );
101112 }
102113
103114 ctx .fireChannelRead (msg );
0 commit comments