Skip to content

Commit ae0bbe0

Browse files
author
tamsin johnson
committed
feat: Add Bunny configuration for context propagation_style (open-telemetry#526)
open-telemetry/oteps#220 recommends: > For each message it accounts for, the "Deliver" or "Receive" span SHOULD link to the message's creation context. In addition, if it is possible the creation context MAY be set as a parent of the "Deliver" or "Receive" span. But also acknolwedges: > open-telemetry/opentelemetry-specification#454 To instrument pull-based "Receive" operations as described in this document, it is necessary to add links to spans after those spans were created. The reason for this is, that not all messages are present at the start of a "Receive" operations, so links to related contexts cannot be added at the start of the span. Our "Receive" spans do not link to the message's creation context, and indeed it doesn't seem possible to do so. Likewise for setting the parent. In lieu of a specification layer solution, this proposes adding a configuration flag so that users can opt-in to setting the "Send" context as parent for the "Process" span. This comes at the cost of a continuous trace including the "Send"-"Receive"-"Process" spans, with "Receive" orphaned from both "Send" and "Process". This doesn't attempt to reproduce the "none" `propagation_style` included in `sidekiq` instrumentation and other similar gems. If this is an interesting direction, we could consider implementing it.
1 parent 0f868b7 commit ae0bbe0

3 files changed

Lines changed: 38 additions & 2 deletions

File tree

instrumentation/bunny/lib/opentelemetry/instrumentation/bunny/instrumentation.rb

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,8 @@ class Instrumentation < OpenTelemetry::Instrumentation::Base
2121
defined?(::Bunny)
2222
end
2323

24+
option :propagation_style, default: :link, validate: %i[link child none]
25+
2426
private
2527

2628
def require_patches

instrumentation/bunny/lib/opentelemetry/instrumentation/bunny/patch_helpers.rb

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -34,7 +34,12 @@ def self.destination_name(exchange, routing_key)
3434

3535
def self.extract_context(properties)
3636
# use the receive span as parent context
37-
parent_context = OpenTelemetry.propagation.extract(properties[:tracer_receive_headers])
37+
parent_context =
38+
if Bunny::Instrumentation.instance.config[:propagation_style] == :child
39+
OpenTelemetry.propagation.extract(properties[:headers])
40+
else
41+
OpenTelemetry.propagation.extract(properties[:tracer_receive_headers])
42+
end
3843

3944
# link to the producer context
4045
producer_context = OpenTelemetry.propagation.extract(properties[:headers])

instrumentation/bunny/test/opentelemetry/instrumentation/bunny/patches/queue_test.rb

Lines changed: 30 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@
1212

1313
describe OpenTelemetry::Instrumentation::Bunny::Patches::Queue do
1414
let(:instrumentation) { OpenTelemetry::Instrumentation::Bunny::Instrumentation.instance }
15+
let(:config) { {} }
1516
let(:exporter) { EXPORTER }
1617
let(:spans) { exporter.finished_spans }
1718

@@ -30,7 +31,7 @@
3031
# Clear spans
3132
exporter.reset
3233

33-
instrumentation.install
34+
instrumentation.install(config)
3435
end
3536

3637
after do
@@ -72,5 +73,33 @@
7273
process_span = spans.find { |span| span.name == ".#{queue_name} process" }
7374
_(process_span).must_be_nil
7475
end
76+
77+
describe 'when propagation_style is child' do
78+
let(:config) { { propagation_style: :child } }
79+
80+
it 'maintains a continuous trace' do
81+
queue.publish('Hello, opentelemetry!')
82+
83+
queue.pop { |_delivery_info, _metadata, _payload| break }
84+
85+
send_span = spans.find { |span| span.name == ".#{queue_name} send" }
86+
process_span = spans.find { |span| span.name == ".#{queue_name} process" }
87+
88+
_(process_span.parent_span_id).must_equal(send_span.span_id)
89+
_(process_span.trace_id).must_equal(send_span.trace_id)
90+
end
91+
92+
it 'propagates baggage' do
93+
ctx = OpenTelemetry::Baggage.set_value('testing_baggage', 'it_worked')
94+
95+
OpenTelemetry::Context.with_current(ctx) do
96+
queue.publish('Hello, opentelemetry!')
97+
end
98+
99+
queue.pop do |_delivery_info, _metadata, _payload|
100+
_(OpenTelemetry::Baggage.value('testing_baggage')).must_equal('it_worked')
101+
end
102+
end
103+
end
75104
end
76105
end unless ENV['OMIT_SERVICES']

0 commit comments

Comments
 (0)