javatracezipkinbrave

Java Brave Zipkin: TraceId unchanged for each different http requests


Small tracing question regarding Java and Brave/Zipkin please.

I am having a very small program, using Java 11 and Brave with versions as follow:

        <dependency>
            <groupId>io.opentracing.brave</groupId>
            <artifactId>brave-opentracing</artifactId>
            <version>1.0.0</version>
        </dependency>
        <dependency>
            <groupId>io.zipkin.reporter2</groupId>
            <artifactId>zipkin-sender-okhttp3</artifactId>
            <version>2.16.3</version>
        </dependency>

The goal is very simple, I am the client, I have a list of N different request payloads to send N times to a server API. (There in no API on the server which I do not control to accept all of them at once, and the question is not about that 😛 )

As I would like to leverage tracing technologies, as a client, I would like to send the N requests, since each are different and unique, with N different traceId.

In order to do so, I tried:

private static Iterator<String> sendRequestPayloadToServerWithDifferentTraceId(Iterator<String> requestsPayload) {
        List<String> linkedList = new LinkedList<>();
        while (requestsPayload.hasNext()) {
            final OkHttpSender        sender   = OkHttpSender.newBuilder().endpoint("https://zipkin-server:9411/api/v2/spans").build();
            final AsyncReporter<Span> reporter = AsyncReporter.builder(sender).build();
            final Tracing             tracing  = Tracing.newBuilder().localServiceName("client").addSpanHandler(ZipkinSpanHandler.create(reporter)).build();
            tracing.tracer().startScopedSpan("parentSpan");
            final var span = tracing.tracer().currentSpan();
            span.tag("key", "firstBiz");

            tracing.tracer().startScopedSpanWithParent("childSpan", tracing.tracer().currentSpan().context());
            final var childSpan = tracing.tracer().currentSpan();
            childSpan.tag("key", "secondBiz");
            childSpan.finish();

            String requestPayload = requestsPayload.next();
            final WebClient webClient = WebClient.create().mutate().defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE, HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE).clientConnector(new ReactorClientHttpConnector(HttpClient.create().wiretap(true).protocol(HttpProtocol.H2))).build();
            LOGGER.info("sending the request! requestPayload={} TraceId={}, SpanId={}", requestPayload, span.context().traceIdString(), childSpan.context().traceIdString());
            final String response = webClient.post().uri("https://the-bsiness-server/api/someAPI").header("X-B3-TraceId", span.context().traceIdString()).header("X-B3-SpanId", childSpan.context().traceIdString()).body(BodyInserters.fromValue(requestPayload)).retrieve().bodyToMono(String.class).block();
            if (!"".equals(response)) {
                linkedList.add("OK");
            }
        }
        return linkedList.iterator();
    }

Unfortunately, no matter how many requests, while I am expecting to see N different traceId, I am always seeing only one same traceId.

I am having a hard time understanding. May I ask what is the proper way to get one unique/different trace per requests, resulting in N different requests please?

Thank you


Solution

  • I did a little bit refactor in your code, pay attention to flush and close applied on Reporter (hint: reporter is async). also the logic for creating tracing object transferred before while loop and we use BraveTracer as tracer

      private static Iterator<String> sendRequestPayloadToServerWithDifferentTraceId(
          Iterator<String> requestsPayload) {
    
        List<String> linkedList = new LinkedList<>();
    
        final OkHttpSender sender = OkHttpSender.create("http://localhost:9411/api/v2/spans");
    
        AsyncReporter<Span> reporter = AsyncReporter.create(sender);
        Tracing tracing = Tracing
            .newBuilder()
            .localServiceName("client")
            .sampler(Sampler.create(1.0f))
            .addSpanHandler(ZipkinSpanHandler.create(reporter))
            .build();
    
    
        while (requestsPayload.hasNext()) {
          BraveTracer tracer = BraveTracer.create(tracing);
          BraveSpan parent = tracer
              .buildSpan("parent")
              .withTag("key", "firstBiz")
              .start();
    
          BraveSpan child = tracer
              .buildSpan("child")
              .withTag("key", "secondBiz")
              .asChildOf(parent)
              .start();
    
          child.finish();
    
          String requestPayload = requestsPayload.next();
          final WebClient webClient =
              WebClient.create()
                  .mutate()
                  .defaultHeader(HttpHeaders.CONTENT_TYPE, MediaType.APPLICATION_JSON_VALUE,
                  HttpHeaders.ACCEPT, MediaType.APPLICATION_JSON_VALUE).clientConnector(
                  new ReactorClientHttpConnector(
                      HttpClient.create().wiretap(true).protocol(HttpProtocol.HTTP11))).build();
          final String response = webClient.post().uri("http://localhost:8081/api")
              .header("X-B3-TraceId", parent.unwrap().context().traceIdString())
              .header("X-B3-SpanId", child.unwrap().context().traceIdString())
              .body(BodyInserters.fromValue(requestPayload)).retrieve().bodyToMono(String.class)
              .block();
          if (!"".equals(response)) {
            linkedList.add("OK");
          }
          parent.finish(); // important
        }
    
        reporter.flush(); // important
        reporter.close(); // important
        return linkedList.iterator();
      }
    

    add the following dependency:

    <dependency>
      <groupId>io.zipkin.brave</groupId>
      <artifactId>brave</artifactId>
      <version>5.13.7</version>
    </dependency>
    

    after the above changes I was able to get a trace id per request, result: enter image description here