3

so I'm playing aroung with Jaeger and OpenTracing to trace the requests between my Spring Boot microservices. I have setup all necessary configurations and added the dependency:

<dependency>
    <groupId>io.opentracing.contrib</groupId>
    <artifactId>opentracing-spring-jaeger-web-starter</artifactId>
    <version>2.0.3</version>
</dependency>

So far all works fine. I see all the traces and spans in my Jaeger UI, no problem.

But now I have the challenge to add new spans to a specific trace, that is already finished. Think of it like this. A client calls one of the services and the tracing starts. After the work is done, I see the trace in my Jaeger UI. But now the invoking clients wants to add some additional tracing data to the specific trace. Like tracing information from other service, that are not within the scope of my microservices. I've added a filter so I can extract the trace id and send it to the client. Now the client does a request containing the additional trace information and the trace id. These informationa should then be added as an additional span in the already finished trace.

Now to my question. Is there a way to create a span and add it to a trace with only having the trace id as a String?

I've tried Zipkin and I could just do:

Span span = new SpanBuilder()
                .name(someName)
                .traceId(traceId)
                .parentId(traceId)
                .id(someId)
                .kind(Kind.CLIENT)
                .build()

That span could then be added by doing a POST request to my zipkin server on port 9411 which did the magic of adding this span to the trace with the given id.

Using OpenTracing I can do:

Span span = tracer.buildSpan(someName)
                .asChildOf(**traceSpan**)
                .withStartTimestamp(someTime)
                .ignoreActiveSpan()
                .start();

Unfortunately this approach needs the trace in form of a span to create the new span as a child of that trace. Given the fact that I can only provide the trace id, I don't know how to get the needed span of that trace. Do I really need to make a call to my the Jaeger query to get the trace span needed or is there another approach I haven't been thinking of?

Would really like to get some help on this.

Cheers!

Spark
  • 31
  • 1
  • 2
  • You need to implement injector https://opentracing.io/docs/overview/inject-extract/#propagation-example – rkosegi Mar 12 '20 at 11:26
  • I'm not quite sure how. Isn't an injector just to inject information into the current span context? – Spark Mar 16 '20 at 14:43

2 Answers2

1

You need to send the trace-id from one server into another. I'll list here one way to implement a code that actually works assuming you already has an original span created at service 1 and a tracer instance (JaegerTracer) created.

First, you need to get the span-id from the span at your service1:

JaegerSpan span = tracer.buildSpan("service1")
String spanId = span.context().toTraceId()

Now, you can propagate this string (spanId) to your other services. Ex: If you are using http/post or kafka, there are some protocols to follow ex: w3c . But in an root way

import io.jaegertracing.internal.JaegerSpan;
import io.jaegertracing.internal.JaegerSpanContext;
import io.jaegertracing.internal.propagation.TextMapCodec;
import io.jaegertracing.internal.propagation.TextMapCodec.Builder;
//...
// assuming you've extracted your trace-id as string from your messaging system
// kafka header, http header, grpc metadata, wherever...
TextMap carrier = new TextMapAdapter(Map.of("uber-trace-id", traceId));
TextMapCodec codec = New Builder().build();

// I guess this line answer your question (get spanContext from trace-id)
JaegerSpanContext sc = codec.extract(carrier);
JaegerSpan sp = tracer.buildSpan("service2").asChildOf(sc).start();
Totalys
  • 445
  • 2
  • 10
  • 25
0

like what @Totalys says , but need some modification the value associate with the key "uber-trace-id" should be the context().toString() instead of context().toTraceId

  • This does not provide an answer to the question. Once you have sufficient [reputation](https://stackoverflow.com/help/whats-reputation) you will be able to [comment on any post](https://stackoverflow.com/help/privileges/comment); instead, [provide answers that don't require clarification from the asker](https://meta.stackexchange.com/questions/214173/why-do-i-need-50-reputation-to-comment-what-can-i-do-instead). - [From Review](/review/late-answers/30256210) – Matthew Kerian Nov 04 '21 at 21:30