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

OpenTelemetry not working with RESTEasy reactive mode #22568

Closed
osbornk opened this issue Dec 31, 2021 · 8 comments · Fixed by #22671
Closed

OpenTelemetry not working with RESTEasy reactive mode #22568

osbornk opened this issue Dec 31, 2021 · 8 comments · Fixed by #22671

Comments

@osbornk
Copy link

osbornk commented Dec 31, 2021

Describe the bug

I am trying to setup OpenTelementry on two on Kotlin 1.6.10 and Quarkus 2.6.1. I have a trivial application that takes an input and then makes an HTTP call to another endpoint (on the same application).

If I use RESTEasy Reactive with a synchronous function it works fine. I get a full trace from the HTTP end.

Here is my server:

quarkus.opentelemetry.enabled=true 
quarkus.opentelemetry.propagators=b3,b3multi,tracecontext
quarkus.opentelemetry.tracer.sampler=on
quarkus.opentelemetry.tracer.sampler.parent-based=true
@Path("/hello")
class GreetingController(
    private val tracer: Tracer,

    @RestClient
    private val repeaterClient: RepeaterClient
) {
    @Path("sync")
    @POST
    @Produces(MediaType.TEXT_PLAIN)
    fun sync(name: String): String {
        val span = tracer.spanBuilder("inside sync").startSpan()

        try {
            val repeat = repeaterClient.sync(name)
            return "Hello $name $repeat - sync"
        } finally {
            span.end()
        }
    }

    @Path("async")
    @POST
    @Produces(MediaType.TEXT_PLAIN)
    fun async(name: String): Uni<String> {
        val span = tracer.spanBuilder("inside async").startSpan()

        try {
            return repeaterClient.async(name).onItem()
                .transform { repeat -> "Hello $name $repeat - async" } //.await().indefinitely()
        } finally {
            span.end()
        }
    }

    @Path("coroutine")
    @POST
    @Produces(MediaType.TEXT_PLAIN)
    suspend fun coroutine(name: String): String {
        val span = tracer.spanBuilder("inside coroutine").startSpan()

        try {
            val repeat = repeaterClient.coroutine(name)

            return "Hello $name $repeat - coroutine"
        } finally {
            span.end()
        }
    }
}

@Path("/repeat")
@RegisterRestClient(configKey = "repeater-api")
interface RepeaterClient {
    @Path("repeat")
    @POST
    fun sync(repeat: String): String

    @Path("repeat")
    @POST
    fun async(repeat: String): Uni<String>

    @Path("repeat")
    @POST
    suspend fun coroutine(repeat: String): String
}

@Path("repeat")
class RepeaterController(
    private val tracer: Tracer
) {
    @Path("repeat")
    @POST
    @Produces(MediaType.TEXT_PLAIN)
    fun repeat(repeat: String): String {
        val span = tracer.spanBuilder("inside repeat").startSpan()

        try {
            return repeat
        } finally {
            span.end()
        }
    }
}

If I call /hello/sync I get a single trace that includes the original HTTP POST, inside sync, the HTTP repeat client, the HTTP repeat POST server, and inside repeat.

If I call /hello/async, I get three traces. The first trace is a single space of the HTTP POST (hello/async). The second trace is inside async. And the third trace includes 3 spans the HTTP repeat client, the HTTP repeat POST server, and inside repeat

Using /hello/coroutine gave me the exact same results.

I previously tried Quarkus 2.5.x and it gave slightly different results. Instead of three traces, I got two traces. The first two traces were a single trace.

Expected behavior

I expect a single trace.

Actual behavior

My request is split into three different traces.

How to Reproduce?

No response

Output of uname -a or ver

Darwin MacBook-Pro 21.2.0 Darwin Kernel Version 21.2.0: Sun Nov 28 20:28:54 PST 2021; root:xnu-8019.61.5~1/RELEASE_X86_64 x86_64

Output of java -version

openjdk version "17.0.1" 2021-10-19

GraalVM version (if different from Java)

No response

Quarkus version or git rev

2.1.1-final

Build tool (ie. output of mvnw --version or gradlew --version)

Gradle 7.3

Additional information

No response

@quarkus-bot
Copy link

quarkus-bot bot commented Dec 31, 2021

@geoand
Copy link
Contributor

geoand commented Jan 3, 2022

Can you please attach a sample project that exhibits the problematic behavior? It would be a tremendous help...

@osbornk
Copy link
Author

osbornk commented Jan 3, 2022

Here you go:
https://github.com/osbornk/quarkus-otel

The test instructions are in the README.

An interesting thing I found is that this behavior seems to be specific to posting a HTTP body, such as raw text of JSON. When using query parameters, everything works fine. That is definitely a bit odd, but it is consisytent.

@geoand
Copy link
Contributor

geoand commented Jan 4, 2022

Thanks.

@radcortez I don't see where OTel is integrated with JAX-RS, so I can't really tell what's going on. Do you have any idea?

@radcortez
Copy link
Member

@geoand
Copy link
Contributor

geoand commented Jan 4, 2022

Since I have been doing the OTel integration work I can pick this up if you want :)

That would probably be best as I don't see any touch points with RESTEasy Reactive :).
FWIW, this looks like some kind of race condition

@osbornk
Copy link
Author

osbornk commented Jan 4, 2022

Thanks for looking into this and let me know if you need any further information or testing. I am pushing to introduce Quarkus on GraalVM at my company and this is basically the one last unsolved problem. We love OpenTelemetry.

@radcortez
Copy link
Member

Just to provide some feedback: I was able to reproduce the issue and found a problem in the way the context is retrieved for certain situations. I'll provide a fix soon.

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

Successfully merging a pull request may close this issue.

3 participants