Bjorn Beskow created CAMEL-23349:
------------------------------------

             Summary: 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.19.0, 4.18.1
            Reporter: Bjorn Beskow


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) baggage scope 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 that scope that is passed to the OTEL propagator, 
not the scope created programmatically as in the example above.

Hence 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