Víctor Herraiz
Víctor Herraiz

Reputation: 1279

How to initialize micrometer/brave baggate field (spring boot 3)

I already manage to do so in Spring Boot 2.7.x but is a little bit different in Spring Boot 3.

I added the following to initialize the baggage field if there is no related HTTP header


public class FAPIAutoConfiguration {

    private static final BaggageField FIELD = BaggageField.create("x-fapi-interaction-id");

    @Bean
    TracingCustomizer fapiTracingCustomizer(UniqueIdGenerator generator) {
        return builder -> builder
            .alwaysSampleLocal()
            .addSpanHandler(new SpanHandler() {
                @Override
                public boolean begin(TraceContext context, MutableSpan span, TraceContext parent) {
                    var value = FIELD.getValue(context);
                    if (value == null || value.trim().isEmpty()) {
                        FIELD.updateValue(context, generator.next());
                    }
                    return super.begin(context, span, parent);
                }
            });
    }

    @Bean
    BaggagePropagationCustomizer fapiBaggagePropagationCustomizer() {
        return builder -> builder.add(BaggagePropagationConfig.SingleBaggageField.remote(FIELD));
    }

}

The problems is that I do not know if this is even the best solution or if .alwaysSampleLocal() has a negative performance impact. Without .alwaysSampleLocal() the initialization only happens from time to time.

Upvotes: 0

Views: 2963

Answers (1)

Piotr
Piotr

Reputation: 185

If your service is only handling http requests i believe it can be achieved by using spring filters

@Component
public class BaggageFieldFilter extends OncePerRequestFilter {
    private Tracer tracer;

    private static final String field = "baggage";

    BaggageFieldFilter(Tracer tracer) {
        this.tracer = tracer;
    }

    @Override
    protected void doFilterInternal(HttpServletRequest request, HttpServletResponse response, FilterChain filterChain) throws ServletException, IOException {
        if(tracer.getBaggage(field) == null) {
            tracer.createBaggage(field, "value");
        }
        filterChain.doFilter(request, response);
    }
}

If you are using Webflux similiar code can be developed with WebFilter. This solution will not cover cases where baggage field is not present and application is listening for events(kafka, rabbitmq) or application runs scheduler. In those cases more development is required.

Upvotes: 0

Related Questions