Hacktoberfest 2026: le issue che i maintainer hanno segnato per ottobre, aperte e adatte ai principianti. Sfoglia le issue Hacktoberfest

gRPC server instrumentations (grpc-1.5, armeria-grpc) don't make extracted W3C baggage current in the handler

Aperta
#12,654 0 commenti 0 reazioni 0 assegnatari Vedi su GitHub

I maintainer di solito rispondono entro 1 giorno

Nessuno ha ancora preso questa issue.

Valutazione

Difficoltà
3/5
Tempo stimato
1-2 giorni
Idoneità per principianti
78/100
Tipo di issue
Bug
Chiarezza
Specificata chiaramente
Stato di attività
Attiva
Stack tecnologico
grpc, java
Ambito
observability

Direzione di ricerca

Start with the extraction and activation paths in dd-java-agent/instrumentation/grpc-1.5/.../TracingServerInterceptor.java and the corresponding armeria-grpc-0.84 file, then run the GrpcServerBaggageTest reproduction. Compare them with HttpServerDecorator and JettyServerAdvice; done means inbound baggage is current in the unary handler and is reinjected on outbound calls while trace propagation still works.

Scritto dal modello di indicizzazione a partire dal testo della issue.

Descrizione

comp: context propagation inst: grpc type: feature request
Tracer Version(s)

1.56.0, 1.66.0 (observed); master at 02d50d2 (code reading)

Java Version(s)

17.0.13

JVM Vendor

Eclipse Adoptium / Temurin

Bug Report

gRPC server instrumentations (grpc-1.5 and armeria-grpc-0.84) extract inbound W3C baggage but don't make it current while the service runs. As a result:

  • Baggage.current() (OTel API, DD_TRACE_OTEL_ENABLED=true) is empty inside the handler.
  • Downstream calls from the handler carry no baggage header, even though the trace context (x-datadog-*, traceparent) propagates fine.

The baggage.* span tags still show up on the grpc.server span, which makes the loss easy to miss.

Root cause. Both TracingServerInterceptors call the deprecated AgentPropagation.extractContextAndGetSpanContext (internal-api, v1.66.0 L33-L38).

  • That helper extracts the full Context and then returns only the span context, so the extracted Baggage element is discarded.
  • The interceptor then runs next.startCall(...) and every listener callback under activateSpan(span), which is a span-only context.
  • The tags appear anyway because BaggagePropagator.extract also copies the baggage onto the extracted TagContext (v1.66.0 L130-L138).

Call sites:

HTTP servers don't have this problem. They were moved to full-context extraction in #8820: HttpServerDecorator.extract returns the whole Context, and e.g. JettyServerAdvice attaches parentContext.with(span) (v1.66.0 L32-L61).

Observed (dd-java-agent 1.56.0 and 1.66.0; Armeria 1.33.4 and 1.41.0). An agent-less client sends baggage: jtbd=ap.curl,user.id=u1 plus x-datadog-* headers to a relay server, whose handler logs Baggage.current() and makes one outbound OkHttp call:

relay server Baggage.current() in handler (OTel bridge on) baggage header on the relay's outbound call baggage.jtbd tag on server span trace joins
Armeria GrpcService {} none yes yes
Jetty 11 servlet {jtbd=ap.curl, user.id=u1} jtbd=ap.curl,user.id=u1 yes yes

The result was the same with the OTel bridge unset, apart from the Baggage.current() column, which the bridge feeds. I did not run a grpc-java (Netty) server in that harness. For grpc-1.5, the unit test below reproduces the same loss.

Other callers of the deprecated helper (master at 02d50d2, non-test code). I found these by reading the code and have not reproduced them. They look like they have the same shape: extract, keep only the span context, then activate a span-only context.

  • RPC: sofarpc-5.0 (ProviderProxyInvokerInstrumentation)
  • Messaging consumers: kafka-clients-0.11 and kafka-clients-3.8 (TracingIterator), aws-java-sqs-1.0 and aws-java-sqs-2.0 (TracingIterator), javax-jms-1.1 (JMSMessageConsumerInstrumentation, DatadogMessageListener), rabbitmq-amqp-2.7 (RabbitDecorator), google-pubsub-1.116 (PubSubDecorator)
  • API shims: opentracing-0.31 / 0.32 (OTTracer), opentelemetry-0.3 (OtelContextPropagators)

I've seen #11286 and the note there that W3C baggage was initially scoped to HTTP. gRPC carries baggage as an HTTP/2 header, and these servers already extract and tag it, so it seemed worth reporting on its own. Please relabel as a feature request if that fits your conventions better.

Expected Behavior

When a gRPC server span is started from extracted headers, the rest of the extracted context (W3C baggage) is current for the whole call, as it is for HTTP servers. In particular:

  • Baggage.current() in the service implementation returns the inbound members.
  • Outbound calls made from the handler re-inject the baggage header.
Reproduction Code

Minimal Spock test against grpc-1.5. The same shape against an Armeria GrpcService fails the same way.

class GrpcServerBaggageTest extends InstrumentationSpecification {
  def "inbound baggage is current in unary handler"() {
    setup:
    Map<String, String> seen = null
    def greeter = new GreeterGrpc.GreeterImplBase() {
        @Override
        void sayHello(Helloworld.Request req, StreamObserver<Helloworld.Response> obs) {
          seen = Baggage.fromContext(Context.current())?.asMap()
          obs.onNext(Helloworld.Response.newBuilder().setMessage("hi").build())
          obs.onCompleted()
        }
      }
    def name = InProcessServerBuilder.generateName()
    def server = InProcessServerBuilder.forName(name).addService(greeter).directExecutor().build().start()
    def md = new Metadata()
    md.put(Metadata.Key.of("baggage", Metadata.ASCII_STRING_MARSHALLER), "user.id=abc123")
    def channel = InProcessChannelBuilder.forName(name)
      .intercept(MetadataUtils.newAttachHeadersInterceptor(md)).directExecutor().build()

    when:
    GreeterGrpc.newBlockingStub(channel).sayHello(Helloworld.Request.newBuilder().setName("x").build())

    then:
    seen == ["user.id": "abc123"]   // on master: seen == null (a span is current, baggage is not)

    cleanup:
    channel.shutdownNow(); server.shutdownNow()
  }
}
Lingua principale
Java
Stelle
737
Fork
361
Merge medio
3g 13h
PR unite (30g)
181

Preparare l'ambiente

Come iniziare

  1. Leggi tutta la issue e poi la guida ai contributi del progetto.
  2. Commenta sulla issue per dire che te ne occupi tu — evita che due persone facciano lo stesso lavoro.
  3. Fai un fork del repository e lavora su un branch.
  4. Apri una pull request che faccia riferimento al numero della issue.

Altre issue di DataDog/dd-trace-java

Tutte le issue di DataDog/dd-trace-java

Issue simili

Altre issue su Java

Ricevi le nuove issue nella tua casella

Un breve riepilogo di issue GitHub adatte ai principianti.