spring-bootapache-kafkaopen-telemetrydistributed-tracing

Create an open-telemetry span using trace-id and span-id in Java


I'm using open-telemetry to trace my applications and have a few microservices and Kafka broker in my distributed system. I'm using Java/spring-boot and in the HTTP Headers sending the traceparent(Ex: 00-8652a752089f33e2659dff28d683a18f-7359b90f4355cfd9-01).

I tried below code in the server(Kafka consumer) but always this create a span with a different trace id. But I need the span nested to the parent trace.

@GetMapping(value = "/second")
  public String sencondTest(@RequestHeader(value = "traceparent") String traceparent){
    try {
      Tracer tracer = openTelemetry.getTracer("cloud.events.second");

      TextMapGetter<ExtractModel> getter = new TextMapGetter<>() {
        @Override
        public String get(ExtractModel carrier, String key) {
          if (carrier.getHeaders().containsKey(key)) {
            return carrier.getHeaders().get(key);
          }
          return null;
        }

        @Override
        public Iterable<String> keys(ExtractModel carrier) {
          return carrier.getHeaders().keySet();
        }
      };

      ExtractModel model = new ExtractModel();
      model.addHeader("traceparent", traceparent);
      Context extractedContext = openTelemetry.getPropagators().getTextMapPropagator()
              .extract(Context.current(), model, getter);

      try (Scope scope = extractedContext.makeCurrent()) {
        // Automatically use the extracted SpanContext as parent.
        Span serverSpan = tracer.spanBuilder("CloudEvents Server")
                .setSpanKind(SpanKind.SERVER)
                .startSpan();
        try {

          Thread.sleep(150);
        } finally {
          serverSpan.end();
        }
      }

    } catch (InterruptedException e) {
      throw new RuntimeException(e);
    }

    return "Server Received!";
  }

I read the documentation and that didn't help. Is there any way to achieve this? any suggestion will help.


Solution

  • Found the solution. When we configuring the OpenTelemetrySdk need to set W3CTraceContextPropagator in Context Propagators.

    // Use W3C Propagator(to extract span from HTTP headers) since we use the W3C specifications
    TextMapPropagator textMapPropagator = W3CTraceContextPropagator.getInstance();
    
    OpenTelemetrySdk openTelemetrySdk = OpenTelemetrySdk.builder()
            .setTracerProvider(tracerProvider)
            .setPropagators(ContextPropagators.create(textMapPropagator))
            .buildAndRegisterGlobal();
    

    Posted the solution for future users.;-)