open-telemetry / opentelemetry-java-instrumentation

OpenTelemetry auto-instrumentation and instrumentation libraries for Java
https://opentelemetry.io
Apache License 2.0
1.94k stars 851 forks source link

Netty Instrumentation do not work well while propagate custom baggage #10780

Closed fredalxin closed 7 months ago

fredalxin commented 7 months ago

Describe the bug

I am using Spring Cloud Gateway and implemented a custom GlobalFilter.

Context serverContext = PropagateUtils.propagateServerHeaders(() -> proxyResponse.getStatusCode() == HttpStatus.OK.getRequestStatus() ? proxyResponse.getExtra() : null);

        AtomicBoolean mutated = new AtomicBoolean(false);
        try (Scope ignored = serverContext.makeCurrent()) {
            ServerHttpRequest.Builder mutate = exchange.getRequest().mutate();
            PropagateUtils.propagateClientHeaders((k, v) -> {
                mutate.headers(headers -> headers.set(k, v));
                mutated.compareAndSet(false, true);
            });
            if (mutated.get()) {
                return chain.filter(exchange.mutate().request(mutate.build()).build());
            } else {
                return chain.filter(exchange);
            }
        }

In my PropagateUtils method, I have implemented the extract() and inject() methods. Specifically in the extract() method, I added a custom value.

public <C> Context extract(Context serverContext, @Nullable C carrier, TextMapGetter<C> textMapGetter) {
    if (serverContext == null) {
        return Context.root();
    }
    if (textMapGetter == null) {
        return serverContext;
    }
    String baggageContent ="v1";
    if (StringUtils.isNotEmpty(baggageContent)) {
        Baggage baggage = Baggage.fromContext(serverContext);
        serverContext = serverContext.with(baggage.toBuilder().put("key", baggageContent).build());
    }
    return serverContext;
}

I issued a request using curl, which included the header "baggage: key=v2". However, evidently, after the above code, the "baggage" value in both my request header and context changed to "key=v1". The issue arises when, after the code interception by Netty, mainly HttpClientRequestTracingHandler, there are some problems with context.

For the first request, the context it obtained is empty, so it does not call W3CBaggagePropagator's inject() method, thus everything goes as planned. However, by the second request, the obtained context has become "baggage: key=v2", and thus, my header gets polluted.

Even more strangely, when I set some breakpoints in HttpServerResponseTracingHandler and HttpServerRequestTracingHandler, the next request returns to normal. So perhaps, in some scenarios, the code does not correctly clear the context or the channel's attribute (attr).

Steps to reproduce

  1. disable reactor-netty module (reactor-netty will rise another issue anyway)
  2. do some code shown as above in springcloud gateway's filter

Expected behavior

header should be "key=v1"

Actual behavior

header is "key=v2"

Javaagent or library instrumentation version

v1.25.0

Environment

JDK: 1.8 OS: macos

Additional context

No response

laurit commented 7 months ago

Firstly please try with the latest version, we are not going to provide any fixes for old versions such as v1.25.0. Secondly please provide a minimal sample application with instructions necessary for reproducing the issue.

github-actions[bot] commented 7 months ago

This has been automatically marked as stale because it has been marked as needing author feedback and has not had any activity for 7 days. It will be closed automatically if there is no response from the author within 7 additional days from this comment.