1

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

PatPanda
  • 3,644
  • 9
  • 58
  • 154

1 Answers1

3

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

badger
  • 2,908
  • 1
  • 13
  • 32