-
Notifications
You must be signed in to change notification settings - Fork 169
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
fix: Propagate context from async producer #538
fix: Propagate context from async producer #538
Conversation
@plantfansam do you have a sample app and/or screenshots of this in action? |
@arielvalentin I'll get some screenshots and/or try to set up an example app today. |
@arielvalentin I updated the PR with a |
@plantfansam we have a docker-compose file in the top level directory. Is there a reason not to add the example directory there? https://github.com/open-telemetry/opentelemetry-ruby-contrib/blob/main/docker-compose.yml |
OpenTelemetry.propagation.inject(headers) | ||
super | ||
# If context is unset, try to inject headers injected by async producer | ||
ctx = if OpenTelemetry::Trace.current_span == OpenTelemetry::Trace::Span::INVALID |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
🤔 would checking if this is a recording?
span be more appropriate?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I think so: 00cd9e8.
Now, logic is: if there's already a span recording when we produce, use that as context; otherwise try to extract context from headers.
There's maybe an edge case where the active span when #producer
runs has been sampled out, but produce is being called with headers:
with a trace context indicating a sampled in parent. Should we (info-level) log a warning in that circumstance?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Should we (info-level) log a warning in that circumstance?
What would the info log message say?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sorry, I totally missed this @robbkidd! I've changed the code a bit since I made this comment so I don't think a log is necessary...
...umentation/ruby_kafka/test/opentelemetry/instrumentation/ruby-kafka/patches/producer_test.rb
Outdated
Show resolved
Hide resolved
...umentation/ruby_kafka/test/opentelemetry/instrumentation/ruby-kafka/patches/producer_test.rb
Outdated
Show resolved
Hide resolved
...umentation/ruby_kafka/test/opentelemetry/instrumentation/ruby-kafka/patches/producer_test.rb
Show resolved
Hide resolved
Not conceptually, no, I just can't validate it with ex-instrumentation-ruby_kafka:
<<: *base
working_dir: /app/instrumentation/ruby_kafka/example
depends_on:
- kafka
- jaeger
...
jaeger:
image: jaegertracing/all-in-one
ports:
- "16686:16686"
- "4318:4318" # open up this port for OTLP export |
Does that mean you are not able to use the other examples with podman? |
Yeah, when run from the root of the repo, that is the case (e.g. |
Ok that's good to know. Would you mind writing up an issue for that? |
Calling @robbkidd for exploratory testing! |
I'd like to add a few more tests to this this morning to ensure that all args passed properly from |
...tion/ruby_kafka/test/opentelemetry/instrumentation/ruby-kafka/patches/async_producer_test.rb
Outdated
Show resolved
Hide resolved
instrumentation/ruby_kafka/lib/opentelemetry/instrumentation/ruby_kafka/patches/producer.rb
Show resolved
Hide resolved
instrumentation/ruby_kafka/lib/opentelemetry/instrumentation/ruby_kafka/patches/producer.rb
Outdated
Show resolved
Hide resolved
…uby_kafka/patches/producer.rb Co-authored-by: Francis Bogsanyi <francis.bogsanyi@shopify.com>
I'd like to marinate on this one for a couple days, but I think that any
"... send"
spans generated fromruby-kafka
'sAsyncProducer
'sdo_loop
method will be root spans. This is because we do not explicitly pass context betweenAsyncProducer#perform
andProducer#perform
. To demonstrate, consider the traces generated by this code excerpted fromruby_kafka.rb
:Traces for async message production without new patch
"Hello async" parent span has no child spans
"... send" span is parent of consumer span, but does not point to "Hello async" as its parent
Traces for async message production with new patch
Background
Some background on how
AsyncProducer
works (AFAICT): theAsyncProducer
has a background thread that watches an instance variable called@queue
.#produce
shoves stuff onto@queue
, which the background thread handles (i.e. calls@producer.produce
).Strategy
This PR attempts to get the correct parent on
"... send"
spans by:headers
duringAsyncProducer#produce
Producer#produce
and use it as the parent for the...send
span (we only do this if the current span isINVALID
, indicating thatProducer#produce
is running in the context ofdo_loop
).We could, alternatively, patch
AsyncProducer#producer
to push the current OpenTelemetry context onto@queue
when it's adding messages to them, then pop that off the@queue
indo_loop
, but then we'd have to overwrite the method signature forperform
which I don't really want to do. It almost feels appropriate to use a propagator to pass context between these two methods, but maybe that's Friday afternoon talking.Thoughts? Feelings? Warnings?