[ 
https://issues.apache.org/jira/browse/CAMEL-23349?page=com.atlassian.jira.plugin.system.issuetabpanels:comment-tabpanel&focusedCommentId=18082604#comment-18082604
 ] 

Bjorn Beskow commented on CAMEL-23349:
--------------------------------------

Thanks for your patience! I appreciate the design choices in [2]. It is in 
combination with [1] it becomes problematic for us.

Let me share a concrete example from my customer's codebase (slightly 
anonymized):

{code:java}
from("cxf:bean:InboundCxfEndpoint")
        .id(routeId)
        .process(extractCorrelationId) 
        .setHeader("OTEL_BAGGAGE_correlation_id").header("correlation_id")
        .setProperty("route", () -> routeId)
        .setProperty("endpoint", () -> appConfig.getUrl())
        .setProperty("receiver", () -> "SomeReceiver")
        .setProperty("messageType", () -> "SomeMessageType")
        .process(extractSender)
        .process(logReceived) // <- slf4j logging happens here, which should 
include Baggage
        .to("cxf:bean:OutboundCxfEndpoint")
        .process(payloadFilterProcessor) // <- slf4j logging happens here, 
which should include Baggage
        .process(logCompleted); // <- slf4j logging happens here, which should 
include Baggage
{code}

With camel.opentelemetry2.traceProcessors=true, logging includes Baggage 
correctly, but we get 13 spans instead of the expected 3 spans, which is not 
acceptable according to the business users.

I can't see how `excludePatterns` could help us here. It allows us to filter 
out the obviously irrelevant spans: 
`exclude-patterns="setHeader*,setProperty*,to*"` reduces the number of spans to 
8, but we cannot filter out the "process*" steps (since that brings us back to 
square one). Having `includePatterns` wouldn't help us either, would it? Am I 
missing something?

The best workaround we have found is to use a sub-route, which implies a new 
nested span for the sub-route and hence allows traceProcessors=false while 
still getting the Baggage available for logging:

{code:java}
from("cxf:bean:InboundCxfEndpoint")
        .id(routeId)
        .process(extractCorrelationId) 
        .setHeader("OTEL_BAGGAGE_correlation_id").header("correlation_id")
        .to("direct:runWithBaggage");
from("direct:runWithBaggage")
        .setProperty("route", () -> routeId)
        .setProperty("endpoint", () -> appConfig.getUrl())
        .setProperty("receiver", () -> "SomeReceiver")
        .setProperty("messageType", () -> "SomeMessageType")
        .process(extractSender)
        .process(logReceived) // <- slf4j logging happens here, which now 
include Baggage
        .to("cxf:bean:OutboundCxfEndpoint")
        .process(payloadFilterProcessor) // <- slf4j logging happens here, 
which now include Baggage
        .process(logCompleted); // <- slf4j logging happens here, which now 
include Baggage
{code}

This gives us 5 spans in total (the expected 3 spans + EVENT_SENT and 
EVENT_RECEIVED for the sub-route). This is considered acceptable (albeit not 
optimal) by the business.

[1] 
https://camel.apache.org/components/next/others/opentelemetry2.html#_baggage_customization
[2] 
https://camel.apache.org/manual/camel-4x-upgrade-guide-4_21.html#_camel_telemetry
 


> Camel OpenTelemetry2 programmatic baggage management
> ----------------------------------------------------
>
>                 Key: CAMEL-23349
>                 URL: https://issues.apache.org/jira/browse/CAMEL-23349
>             Project: Camel
>          Issue Type: Improvement
>          Components: camel-opentelemetry
>    Affects Versions: 4.18.1, 4.19.0
>            Reporter: Bjorn Beskow
>            Assignee: Pasquale Congiusti
>            Priority: Major
>             Fix For: 4.20.0
>
>
> With Camel OpenTelemetry2 and OpenTelemetry spring boot starter, most aspects 
> of Span Customization such as adding attributes, events and creating nested 
> spans can be done using the OpenTelemetry apis. Programmatically adding OTEL 
> baggage is however an exception. The typical use case for OTEL baggage is to 
> allow for small pieces of contextual data that need to travel with a request 
> across distributed service boundaries, independent of any single span. In our 
> business context, it is in the form of a "business correlation id" that is 
> captured from a header or from the message payload as the very first 
> processor of a boundary component, and should be available to all downstream 
> components.
> The OTEL api itself cannot easily be used to add baggage items to a Camel 
> route, due to `Scope` handling: Baggage must be added to a baggage scope, and 
> is visible and propagated during the lifetime of the scope. The OTEL api 
> looks like this:
> // Create baggage with an entry
> Baggage baggage = Baggage.current().builder()
>     .put("user-id", "12345")
>     .build();
> // Attach baggage to current context
> Context contextWithBaggage = Context.current().with(baggage);
> // Make it current (scoped)
> try (var scope = contextWithBaggage.makeCurrent())
> {   // Your code here - baggage is now active }
> Doing this in a processor, the scope instance must be kept open as long as 
> needed, typically until the end of the exchange. In theory, the following 
> simple albeit brittle solution should work:
>  
> Baggage baggage = Baggage.current().toBuilder()
>   .put("user-id", "12345")
>   .build();
> Context ctxWithBaggage = Context.current().with(baggage);
> Scope scope = ctxWithBaggage.makeCurrent();
> exchange.getExchangeExtension().addOnCompletion(new SynchronizationAdapter() {
>   @Override public void onDone(Exchange exchange)
> {     scope.close();   }
> });
> In practice however, this doesn't work. A (final) baggageScope is already 
> (automatically) created at the start of a Camel route execution, stored on 
> the exchange as part of a wrapped instance of 
> org.apache.camel.opentelemetry2.OpenTelemetrySpanAdapter and properly closed 
> at the end of the route. It is this baggageScope that is passed to the OTEL 
> propagator, not the scope created programmatically as in the example above. 
> Hence the programmatically added baggage entry will not be propagated.
> To my understanding, the simplest way to programmatically add baggage items 
> would be to allow for mutating the baggage scope stored in the 
> org.apache.camel.opentelemetry2.OpenTelemetrySpanAdapter. The required pieces 
> are already present, but would need to be exposed in a public API (currently, 
> both context, baggage and baggage scope are protected).



--
This message was sent by Atlassian Jira
(v8.20.10#820010)

Reply via email to