micrometerspring-micrometermicrometer-tracing

Propagate new micrometer tracing context to Reactor Mono


Processing the message from SQS - which has initial traceId in the message and wanted to use the same traceId while processing the message, but unable to reset the traceId in the tracing context. we need traceId to reset to initial traceId for debugging through the splunk log.

TraceContext tc = tracer.traceContextBuilder()
        .traceId(message.getTraceId()) //traceId0
        .spanId(tracer.currentTraceContext().context().spanId())
        .sampled(tracer.currentTraceContext().context().sampled())
        .parentId(tracer.currentTraceContext().context().parentId())
        .build();
LOGGER.info("tracing log -> test"); //new traceId - traceId1

try (var sc = tracer.currentTraceContext().newScope(tc)) {
    LOGGER.info("tracing log -> test"); //traceId0
    return Mono.deferContextual(contextView -> {
        LOGGER.info("tracing log -> test"); //traceId1
        return switch (message.getEvent()) {
            case ADD_EVENT ->
                    add(message.get(), message.getTraceId()).contextCapture(); //traceId1
            case REMOVE_EVENT ->
                    remove(message.get(), message.getTraceId()).contextCapture(); //traceId1
            default -> {
                LOGGER.warn("not supported '{}' ", message);
                yield just(true);
            }
        };
    }).contextWrite(Context.of(TraceContext.class, tc)).contextCapture();
}

Trying to set the traceId0 for all the logging after initiating the newScope. Please help in resolving the issue.


Solution

  • Retrieved the current observation and modified the tracing context before executing business logic and manually end the span on finally.

    final String spanId = tracer.currentTraceContext().context().spanId();
    //setting custom traceId
    final SpanContext spanContext = SpanContext.create(txnId, spanId, TraceFlags.getDefault(), TraceState.getDefault());
    
    final TraceContext traceContext = OtelTraceContext.fromOtel(spanContext);
    final Span span = tracer.spanBuilder().setParent(traceContext).start();
    CurrentTraceContext.Scope scope = tracer.currentTraceContext().newScope(traceContext);
    
    //ObservedContext is always present and updating the tracing context with parent transaction id
    Observation.Context context = observationRegistry.getCurrentObservation().getContext();
    final TracingObservationHandler.TracingContext tracingContext = new TracingObservationHandler.TracingContext();
    tracingContext.setSpanAndScope(span, scope);
    context.put(TracingObservationHandler.TracingContext.class, tracingContext);
    
    ....business logic......
    
    tracer.currentSpan().end();