Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Missing examples with reactive programming (reactor) #591

Open
ygiros opened this issue Jan 31, 2025 · 4 comments
Open

Missing examples with reactive programming (reactor) #591

ygiros opened this issue Jan 31, 2025 · 4 comments

Comments

@ygiros
Copy link

ygiros commented Jan 31, 2025

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

@trask
Copy link
Member

trask commented Jan 31, 2025

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

@ygiros
Copy link
Author

ygiros commented Feb 4, 2025

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 🙂

@trask
Copy link
Member

trask commented Feb 20, 2025

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.

@ygiros
Copy link
Author

ygiros commented Mar 3, 2025

I'm not quite sure to understand how to do it... 🤔
Can you modify my previous example to illustrate your point ?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

2 participants