Missing examples with reactive programming (reactor)
Hi,
Examples provided in Manual span creation and baggage propagation are only available with imperative programming. Is it possible to extend those examples to reactive programming ?
Zero-code instrumentation with opentelemetry agent specifies compatibility with reactor library https://github.com/open-telemetry/opentelemetry-java-instrumentation/blob/main/docs/supported-libraries.md#libraries--frameworks, however I didn't find any examples here or in https://opentelemetry.io/docs/ on how to do manual instrumentation on reactive code with reactor.
I would like to execute following actions in reactor operators
- Create span and make it current
- Inject attribute to current span
- Inject baggage and make it current
As for now, I can only "guess" how I should do in reactive programming, by "translating" imperative examples I have found with reactor equivalents.
For example I translate following imperative code
public String imperativeFoo() {
try (Scope scope1 = tracer.spanBuilder("foo").startSpan().makeCurrent()) {
Span.current().setAttribute("fooAttribute", "fooAttributeValue");
Baggage baggage = Baggage.current().toBuilder()
.put("fooBaggage", "fooBaggageValue")
.build();
try (Scope scope2 = baggage.makeCurrent()) {
return bar();
}
}
}
private String bar() {
// returns "bar:fooBaggageValue"
return "bar:" + Baggage.current().getEntryValue("fooBaggage");
}
into
public Mono<String> reactiveFoo() {
return Mono.using(
() -> tracer.spanBuilder("foo").startSpan().makeCurrent(),
scope1 ->
Mono.fromSupplier(() -> Baggage.current().toBuilder().put("fooBaggage", "fooBaggageValue").build())
.doOnNext(baggage -> Span.current().setAttribute("fooAttribute", "fooAttributeValue"))
.flatMap(baggage ->
Mono.using(
baggage::makeCurrent,
scope2 -> Mono.fromSupplier(this::bar))));
}
private String bar() {
// returns "bar:fooBaggageValue"
return "bar:" + Baggage.current().getEntryValue("fooBaggage");
}
But is it the right way to do it ? If yes, could you please add this example to the documentation ?
Did I miss some other documentation on it somewhere ?
Thanks
hi @ygiros! there are no docs, but check out the io.opentelemetry.instrumentation:opentelemetry-reactor-3.1 library which has some helpful utilities for propagating context in project reactor:
https://github.com/open-telemetry/opentelemetry-java-instrumentation/tree/main/instrumentation/reactor/reactor-3.1/library/src/main/java/io/opentelemetry/instrumentation/reactor/v3_1
Hi @trask !
Thanks for the reply and the link ! 👍
I've already found this library in my previous research but I'm not quite sure how I can make use of it for my case... There's unfortunately no documentation associated with the code so I don't understand how I'm supposed to use it ?
In my first message I should have been more specific that my main issue is on how to use correctly OpenTelemetry Baggage API with Reactor code. I didn't find any reference to Baggage in the https://github.com/open-telemetry/opentelemetry-java-instrumentation/tree/main/instrumentation/reactor/reactor-3.1/library/src/main/java/io/opentelemetry/instrumentation/reactor/v3_1 code. Few examples I've found during reasearch are always described with imperative code. I've tried multiple ways to inject Baggage with Reactor, and the using operator seems to be the only functionnal one from my perspective. But without any offical documentation I can't be sure that I'm doing it right.
Thats's why I'm asking if my previous example is valid ? If it is, I think it would be great to add it to the official documentation so that all the community can benefit from it 🙂
In reactive programming, I would avoid all calls to Span.current()/makeCurrent(), Baggage.current()/makeCurrent(), Context.current()/makeCurrent(). Instead pass the Context around explicitly, and store/retrieve Spans/Baggage into that.
I'm not quite sure to understand how to do it... 🤔 Can you modify my previous example to illustrate your point ?
Hi, Can you provide an example ?