-
Notifications
You must be signed in to change notification settings - Fork 397
Fix losing original karafka trace after iterating through the messages with distributed_tracing on #4876
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
base: master
Are you sure you want to change the base?
Fix losing original karafka trace after iterating through the messages with distributed_tracing on #4876
Changes from 2 commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -53,6 +53,83 @@ | |
| expect(span).to_not have_error | ||
| expect(span.resource).to eq 'topic_a' | ||
| end | ||
|
|
||
| context 'when the message has tracing headers' do | ||
| let(:message) do | ||
| headers = {} | ||
| Datadog::Tracing.trace('producer') do |span, trace| | ||
| Datadog::Tracing::Contrib::Karafka.inject(trace.to_digest, headers) | ||
| end | ||
| metadata = ::Karafka::Messages::Metadata.new | ||
| metadata['offset'] = 412 | ||
| metadata[headers_accessor] = headers | ||
| raw_payload = rand.to_s | ||
|
|
||
| message = ::Karafka::Messages::Message.new(raw_payload, metadata) | ||
| allow(message).to receive(:timestamp).and_return(Time.now) | ||
| allow(message).to receive(:topic).and_return('topic_a') | ||
| message | ||
| end | ||
| let(:headers_accessor) do | ||
| ::Karafka::Messages::Metadata.members.include?(:raw_headers) ? 'raw_headers' : 'headers' | ||
| end | ||
|
|
||
| context 'when distributed tracing is enabled' do | ||
| it 'continues the span that produced the message' do | ||
| producer_trace_digest = Datadog::Tracing::Contrib::Karafka.extract(message.metadata[headers_accessor]) | ||
|
|
||
| consumer_span = nil | ||
| consumer_trace = nil | ||
|
|
||
| Datadog::Tracing.trace('consumer') do | ||
| consumer_span = Datadog::Tracing.active_span | ||
| consumer_trace = Datadog::Tracing.active_trace | ||
|
|
||
| topic = ::Karafka::Routing::Topic.new('topic_a', double(id: 0)) | ||
| messages = ::Karafka::Messages::Builders::Messages.call([message], topic, 0, Time.now) | ||
| expect(messages).to all(be_a(::Karafka::Messages::Message)) | ||
|
|
||
| # assert that the current trace re-set to the original trace after iterating the messages | ||
| expect(Datadog::Tracing.active_trace).to eq(consumer_trace) | ||
| expect(Datadog::Tracing.active_span).to eq(consumer_span) | ||
| end | ||
|
|
||
| expect(spans).to have(3).items | ||
|
|
||
| # assert that the message span is a continuation of the producer span | ||
| expect(span.parent_id).to eq producer_trace_digest.span_id | ||
| expect(span.trace_id).to eq producer_trace_digest.trace_id | ||
| end | ||
| end | ||
|
|
||
| context 'when distributed tracing is not enabled' do | ||
| let(:configuration_options) { {distributed_tracing: false} } | ||
|
|
||
| it 'does not continue the span that produced the message' do | ||
| consumer_span = nil | ||
| consumer_trace = nil | ||
|
|
||
| Datadog::Tracing.trace('consumer') do | ||
| consumer_span = Datadog::Tracing.active_span | ||
| consumer_trace = Datadog::Tracing.active_trace | ||
|
|
||
| topic = ::Karafka::Routing::Topic.new('topic_a', double(id: 0)) | ||
| messages = ::Karafka::Messages::Builders::Messages.call([message], topic, 0, Time.now) | ||
| expect(messages).to all(be_a(::Karafka::Messages::Message)) | ||
|
|
||
| # assert that the current trace re-set to the original trace after iterating the messages | ||
| expect(Datadog::Tracing.active_trace).to eq(consumer_trace) | ||
| expect(Datadog::Tracing.active_span).to eq(consumer_span) | ||
| end | ||
|
|
||
| expect(spans).to have(3).items | ||
|
|
||
| # assert that the message span is not continuation of the producer span | ||
| expect(span.parent_id).to eq(consumer_span.id) | ||
| expect(span.trace_id).to eq(consumer_trace.id) | ||
|
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In the other test, is consumer (the middle span, if I am understanding the logic correctly) expected to be a child of producer? Is that asserted somewhere?
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. In these tests, the
Hope that makes sense! 🙇 (*) we create spans from iterating the messages as the karafka integration patches
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more.
I think that this might not be clear enough from our tests... The messages are being iterated here: # this creates a new span
expect(messages).to all(be_a(::Karafka::Messages::Message))
# ...
# in these expectations, `span` refers to the span created from iterating the messages
expect(span.parent_id).to eq(consumer_span.id)
expect(span.trace_id).to eq(consumer_trace.id)
# because of these `let`s (from the beginning of the file)
let(:span) do
spans.find { |s| s.name == span_name }
end
let(:span_name) { Datadog::Tracing::Contrib::Karafka::Ext::SPAN_MESSAGE_CONSUME }
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Just updated the test with comments better expliciting the test intentions - please let me know if it's more clear now 🙇 note: I didn't add an explicit
Member
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Thanks, I think I understand what you are saying, but it's strange to me that the iterating span changed from being under the producer to being under the consumer but there is no relationship between the producer and the consumer. Might be a question outside the scope of this PR.
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Iterating the message does not really change any spans - it's continuing a trace that changes the parent/child relationship of spans.
Distributed tracing gets confusing quickly 😅
Contributor
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. just fyi: I found this issue describing a similar use-case, so I've included our own use-case there as well (along with an example & screenshots) |
||
| end | ||
| end | ||
| end | ||
| end | ||
|
|
||
| describe 'worker.processed' do | ||
|
|
||
Uh oh!
There was an error while loading. Please reload this page.