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

fix: untraced only works with parent-based sampler #1412

Merged
merged 8 commits into from
Jan 12, 2023
Merged
Show file tree
Hide file tree
Changes from 2 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
14 changes: 13 additions & 1 deletion common/lib/opentelemetry/common/utilities.rb
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,9 @@ module Common
module Utilities
extend self

UNTRACED_KEY = Context.create_key('untraced')
private_constant :UNTRACED_KEY

STRING_PLACEHOLDER = ''.encode(::Encoding::UTF_8).freeze

# Returns nil if timeout is nil, 0 if timeout has expired,
Expand Down Expand Up @@ -83,8 +86,17 @@ def truncate_attribute_value(value, limit)
end
end

# Disables tracing within the provided block.
def untraced
OpenTelemetry::Trace.with_span(OpenTelemetry::Trace.non_recording_span(OpenTelemetry::Trace::SpanContext.new)) { yield } # rubocop:disable Style/ExplicitBlockArgument
Context.with_value(UNTRACED_KEY, true) do |ctx, _|
yield ctx
end
end

# Detects whether the current context has been set to disable tracing.
def untraced?(context = nil)
context ||= Context.current
!!context.value(UNTRACED_KEY)
end

# Returns a URL string with userinfo removed.
Expand Down
11 changes: 11 additions & 0 deletions common/test/opentelemetry/common/utilities_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,17 @@ def shutdown(timeout: nil); end

let(:common_utils) { OpenTelemetry::Common::Utilities }

describe '#untraced?' do
it 'returns true within an untraced block' do
assert_equal(true, common_utils.untraced { common_utils.untraced? })
end

it 'returns false outside an untraced block' do
common_utils.untraced {}
assert_equal(false, common_utils.untraced?)
end
end

describe '#utf8_encode' do
it 'happy path' do
str = 'pristine ¬'.encode(Encoding::UTF_8)
Expand Down
6 changes: 5 additions & 1 deletion sdk/lib/opentelemetry/sdk/trace/tracer.rb
Original file line number Diff line number Diff line change
Expand Up @@ -28,9 +28,13 @@ def start_root_span(name, attributes: nil, links: nil, start_timestamp: nil, kin
end

def start_span(name, with_parent: nil, attributes: nil, links: nil, start_timestamp: nil, kind: nil)
with_parent ||= Context.current
if Common::Utilities.untraced?(with_parent)
return super(name, with_parent: with_parent, attributes: attributes, links: links, start_timestamp: start_timestamp, kind: kind)
end

name ||= 'empty'
kind ||= :internal
with_parent ||= Context.current

@tracer_provider.internal_start_span(name, kind, attributes, links, start_timestamp, with_parent, @instrumentation_scope)
end
Expand Down
7 changes: 7 additions & 0 deletions sdk/test/opentelemetry/sdk/trace/tracer_test.rb
Original file line number Diff line number Diff line change
Expand Up @@ -192,6 +192,13 @@
_(span).wont_be :recording?
end

it 'returns a no-op span within an untraced block' do
tracer_provider.sampler = Samplers::ALWAYS_ON
span = OpenTelemetry::Common::Utilities.untraced { tracer.start_span('op') }
_(span.context.trace_flags).wont_be :sampled?
_(span).wont_be :recording?
end

it 'returns an unsampled span if sampler says record, but do not sample' do
tracer_provider.sampler = record_sampler
span = tracer.start_span('op', with_parent: context)
Expand Down