Spring micrometer tracing not honoring parentSpanId or converting `X-B3-spanId` recieved in headers to parentSpanId

954 views Asked by At

I'm using micrometer tracing with Brave as my vendor. I observed that micrometer is not honoring parentSpanId in any of the 3 below scenarios:

  1. When I create a nextSpan within the application, I expect the previous spanId to be present in MDC as parentSpanId.
  2. When my service is called by another service and the request Header contains X-B3-SpanId, I expect this ID to be available in MDC as parentSpanId.

But neither of these are happening.

Following is my application.properties file:

server.port=8085
spring.application.name=exampleApp

logging.pattern.console=%d{yyyy-MM-dd }, [[[%mdc]]] [%thread] %-5level %logger{36} - %msg%n

management.tracing.sampling.probability=0.0
management.tracing.propagation.type=B3_MULTI

logging.level.root=info

There's no customization on top of this and I am totally relying on the Spring Auto configuration of micrometer..

I tried adding the following property after reading the documentation here which read

List of fields that should be correlated with the logging context. That means that these fields would end up as key-value pairs in e.g. MDC.

management.tracing.baggage.correlation.fields=parentSpanId,X-B3-ParentSpanId,parentId

But I see no changes in MDC. How do I get this working?

2

There are 2 answers

0
Arun Gowda On BEST ANSWER

Micrometer is not honoring the property. This seems like bug in Micrometer. I have reported the same in github

However, I figured this could be configured by creating a spring bean.

import brave.baggage.BaggageFields;
import brave.baggage.CorrelationScopeConfig;
import brave.baggage.CorrelationScopeCustomizer;
import org.springframework.boot.autoconfigure.condition.ConditionalOnProperty;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.core.annotation.Order;


@Configuration
public class BraveConfig {

    @Bean
    CorrelationScopeCustomizer parentSpanIdCustomizer() {
        return (builder) -> builder.add(
                CorrelationScopeConfig.SingleCorrelationField.newBuilder(BaggageFields.PARENT_ID)
                        .name("parentSpanId").build());
    }
}

I have also customized the parentId to be added as parentSpanId in MDC.

This bean will be picked up by BraveAutoConfiguration#mdcCorrelationScopeDecoratorBuilder during autoconfiguration and customized accordingly.

5
Jonatan Ivanov On

When I create a nextSpan within the application, I expect the previous spanId to be present in MDC as parentSpanId.

This was an old behavior in Sleuth, I think we stopped doing this quite a while ago and go with the Brave default: traceId and spanId, see CorrelationScopeDecorator

As you already found out you need to create a CorrelationScopeCustomizer but you can do this in a simpler way:

@Bean
CorrelationScopeCustomizer parentIdCorrelationScopeCustomizer() {
    return builder -> builder.add(SingleCorrelationField.create(BaggageFields.PARENT_ID));
}

When my service is called by another service and the request Header contains X-B3-SpanId, I expect this ID to be available in MDC as parentSpanId.

I'm not sure how is this different to your previous point, if you do the above and create a child span, in its scope the MDC will contain the parentId.

Fields set in management.tracing.baggage.correlation.fields or management.tracing.baggage.remote-fields will be in the MDC if you create a baggage scope manually or a baggage is sent in the headers.