user5671078
user5671078

Reputation:

How to get currentSpan for rabbitmq application with brave (java)?

My application is a spring-rabbitmq based application(neither spring-cloud nor spring-boot), requests were received from one queue and sent responses to another queue.

I want to use brave to trace the system by injecting Zipkin headers before sending messages and extracting Zipkin headers right after receiving messages.

The problem is In step3 of the following scenario, how can I get span1 before sending message?

Scenario:

step1, app -> mq (new created span1, root span, client)
step2, mq -> app (receive span1, server)
step3, app -> mq (**new created span2, child span of span1, client**)
step4, mq -> app (receive span2, server)

Code snippet before sending message:

     try{
        Span currentSpan = tracer.currentSpan();
        Span newSpan = null;
        if(currentSpan == null){
            newSpan = tracer.newTrace();
        }else{
            newSpan = tracer.newChild(currentSpan.context());
        }

        Map<String, String> strHeaders = new HashMap<String, String>();
        tracing.propagation().injector(Map<String, String>::put).inject(newSpan.context(),strHeaders);
        messageProperties.setHeader("zipkin.brave.tracing.headers", strHeaders);
        newSpan.name("send").kind(Kind.CLIENT).start().flush();
    }catch(Exception e){
        logger.warn("zipkin problem", e);
    }

In the above code, Span currentSpan = tracer.currentSpan(); , the currentSpan is always null.

Code snippet after receiving message:

    try{
        Map<String, Object> msgHeaders = messageProperties.getHeaders();
        Object headersObj = msgHeaders.get("zipkin.brave.tracing.headers");
        Map<String, String> strHeaders = null;
        if(headersObj != null){
            strHeaders = (HashMap<String, String>)headersObj;
        }
        TraceContextOrSamplingFlags result = tracing.propagation().extractor(Map<String, String>::get).extract(strHeaders);

        if(result.context() != null){
            Span clientSpan = tracer.joinSpan(result.context());
            clientSpan.name("receive").kind(Kind.SERVER).start().flush();
        }
    }catch(Exception e){
        logger.warn("zipkin problem", e);
    }

Brave configuration code:

@Configuration
public class BraveSpringConfiguration {
    private static final Logger logger = LoggerFactory.getLogger(BraveSpringConfiguration.class);

    /** Configuration for how to send spans to Zipkin */
    @Bean
    public Sender sender() {
        logger.debug("okhttpsender");
        return OkHttpSender.create("http://127.0.0.1:9411/api/v1/spans");
    }

    /** Configuration for how to buffer spans into messages for Zipkin */
    @Bean
    public Reporter<Span> reporter() {
        logger.debug("asyncreporter");
        return AsyncReporter.builder(sender()).build();
    }

    /** Controls aspects of tracing such as the name that shows up in the UI */
    @Bean
    public Tracing tracing() {
        logger.debug("one tracing");
        return Tracing.newBuilder()
            .localServiceName("spring-rabbitmq-brave")
            //// log4j2, import brave.context.log4j2.ThreadContextCurrentTraceContext;
            //.currentTraceContext(ThreadContextCurrentTraceContext.create()) // puts trace IDs into logs
            .currentTraceContext(MDCCurrentTraceContext.create()) // puts trace IDs into logs
            .sampler(Sampler.ALWAYS_SAMPLE) // always sampler
            .reporter(reporter())
            .build();
    }

    /** Controls aspects of tracing such as the name that shows up in the UI */
    @Bean
    public Tracer tracer() {
        logger.debug("one tracer");
        return tracing().tracer();
    }
}

Following are my references:

  1. https://github.com/openzipkin/brave/tree/master/brave#one-way-tracing

  2. https://github.com/openzipkin/brave/blob/master/brave/src/test/java/brave/features/async/OneWaySpanTest.java

  3. https://gist.github.com/adriancole/76d94054b77e3be338bd75424ca8ba30

Upvotes: 3

Views: 2245

Answers (1)

user5671078
user5671078

Reputation:

Problem solved. tracer.withSpanInScope(clientSpan) would do the work.

Note that, withSpanInScope(...) has not been called before sending messages .

Upvotes: 5

Related Questions