-
Notifications
You must be signed in to change notification settings - Fork 242
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
feat: bunny instrumentation #566
feat: bunny instrumentation #566
Conversation
f8cca1c
to
70bede2
Compare
instrumentation/bunny/lib/opentelemetry/instrumentation/bunny/patches/queue.rb
Outdated
Show resolved
Hide resolved
instrumentation/bunny/lib/opentelemetry/instrumentation/bunny/patch_helpers.rb
Outdated
Show resolved
Hide resolved
instrumentation/bunny/lib/opentelemetry/instrumentation/bunny/patch_helpers.rb
Outdated
Show resolved
Hide resolved
4e329e3
to
ddca4ca
Compare
Thanks for the feedback, I pushed a round of fixes which should address all your comments. |
8d88c3c
to
7c74a3d
Compare
@fbogsany rebased and adopted to latest main changes. Let me know if you have any other comments or concerns. |
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.
LGTM. Did you want to take a final look @fbogsany or @robertlaurin?
instrumentation/bunny/opentelemetry-instrumentation-bunny.gemspec
Outdated
Show resolved
Hide resolved
instrumentation/bunny/lib/opentelemetry/instrumentation/bunny/version.rb
Outdated
Show resolved
Hide resolved
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.
Looks good, just a couple questions.
instrumentation/bunny/lib/opentelemetry/instrumentation/bunny/patches/channel.rb
Outdated
Show resolved
Hide resolved
OpenTelemetry.propagation.inject(properties[:headers]) | ||
end | ||
|
||
super |
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.
Similar to the above, it looks like a uncaught_exception_handler could be provided that raises the exception, in which case we would not capture that event here either.
Not being familiar with rabbitmq, is this call to super
intentionally not being wrapped with the trace block for any particular reason?
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.
super
only enqueues the message into the internal worker pool in this case and the actual consumer call is wrapped into a process span, which should handle the exception in this case.
instrumentation/bunny/test/opentelemetry/instrumentation/bunny/patches/queue_test.rb
Outdated
Show resolved
Hide resolved
instrumentation/bunny/lib/opentelemetry/instrumentation/bunny/patch_helpers.rb
Outdated
Show resolved
Hide resolved
instrumentation/bunny/lib/opentelemetry/instrumentation/bunny/patches/channel.rb
Outdated
Show resolved
Hide resolved
# This method is called when rabbitmq pushes messages to subscribed consumers | ||
def handle_frameset(basic_deliver, properties, content) | ||
OpenTelemetry::Instrumentation::Bunny::PatchHelpers.with_receive_span(self, tracer, basic_deliver, properties) do | ||
properties[:headers] ||= {} | ||
OpenTelemetry.propagation.inject(properties[:headers]) | ||
end | ||
|
||
super | ||
end |
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.
It looks to me like this method wraps consumers, so we can wrap a process
span around it:
# This method is called when rabbitmq pushes messages to subscribed consumers | |
def handle_frameset(basic_deliver, properties, content) | |
OpenTelemetry::Instrumentation::Bunny::PatchHelpers.with_receive_span(self, tracer, basic_deliver, properties) do | |
properties[:headers] ||= {} | |
OpenTelemetry.propagation.inject(properties[:headers]) | |
end | |
super | |
end | |
# This method is called when rabbitmq pushes messages to subscribed consumers | |
def handle_frameset(basic_deliver, properties, content) | |
OpenTelemetry::Instrumentation::Bunny::PatchHelpers.with_process_span(self, tracer, basic_deliver, properties) do | |
super | |
end | |
end |
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.
Hmm, this is interesting because you're also wrapping the Consumer.call
. Maybe we should just not wrap handle_frameset
? We don't have to have a receive
span in every case - the process
span is much more interesting.
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.
The handle_frameset submits the message to a worker pool, so there is a time between receiving the message and eventually processing it in a consumer thread.
Should that time be part of process or receive or not be tracked at all?
module Bunny | ||
module Patches | ||
# The Queue module contains the instrumentation patch the Queue#pop method. | ||
module Queue |
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.
Is Queue
typically used directly by clients or is it only used internally? It feels like we're going to end up with nested process
spans in some cases, but I may be misunderstanding the gem.
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.
.pop
can be used by clients http://rubybunny.info/articles/queues.html#fetching_messages_when_needed_pull_api
instrumentation/bunny/lib/opentelemetry/instrumentation/bunny/patches/queue.rb
Outdated
Show resolved
Hide resolved
instrumentation/bunny/lib/opentelemetry/instrumentation/bunny/patch_helpers.rb
Outdated
Show resolved
Hide resolved
7c74a3d
to
eb89528
Compare
f7781c3
to
404c012
Compare
Thank you for the all the feedback, I made a couple of changes to be more spec compliant around receive vs. process. Now the push & pull api are modelled as https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/semantic_conventions/messaging.md#batch-receiving.
|
94c9615
to
7dcf39a
Compare
@fbogsany could I get another review? :-) |
🤦 sorry! 👀 now. |
@fbogsany friendly ping :-) |
🤦 👀 |
instrumentation/bunny/opentelemetry-instrumentation-bunny.gemspec
Outdated
Show resolved
Hide resolved
instrumentation/bunny/lib/opentelemetry/instrumentation/bunny/version.rb
Outdated
Show resolved
Hide resolved
Thanks @johanneswuerbach - sorry this took so long to review and merge 😞 |
No worries, we are all busy people. Thank you for working on this 🙇 |
parent_context = OpenTelemetry.propagation.extract(properties[:tracer_receive_headers]) | ||
|
||
# link to the producer context | ||
producer_context = OpenTelemetry.propagation.extract(properties[:headers]) |
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.
@johanneswuerbach shouldn't this be .extract(properties[:headers] || {})
?
If I have two services A & B. The first service is instrumented but the second one is not, then I get this exception in service A:
Uncaught exception from consumer #<Bunny::Consumer:70980 @channel_id=2 @queue=amq.gen-p2ZzQp6h4r6QWdCBIC4Pgg> @consumer_tag=bunny-1629126993000-738472400850>: #<NoMethodError: undefined method `[]' for nil:NilClass> @ /home/indrek/.rvm/gems/ruby-2.7.2@admin/gems/opentelemetry-api-1.0.0.rc2/lib/opentelemetry/context/propagation/text_map_getter.rb:16:in `get'
I think that's because properties[:headers]
is nil
when receiving a message from a service that is not using OTEL.
EDIT: I pinged the wrong person initially.
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.
Yes, that seems possible. Could you create a separate issue for this?
Basic instrumentation for bunny based on the existing ruby_kafka instrumentation.
The instrumentation provides:
This basic instrumentation should also be sufficient when using higher level libraries based on bunny like https://github.com/jondot/sneakers