Skip to content

[Single Span Sampling] Span Sampler#2098

Merged
marcotc merged 6 commits into
feature-single-span-samplingfrom
single-span-sampler
Jul 5, 2022
Merged

[Single Span Sampling] Span Sampler#2098
marcotc merged 6 commits into
feature-single-span-samplingfrom
single-span-sampler

Conversation

@marcotc

@marcotc marcotc commented Jun 20, 2022

Copy link
Copy Markdown
Member

Follow up from #2095

This PR adds a new Single Span Sampling class that ties up all the previous Single Span Sampling work.

This class alters span tags when spans are finished, based on the provided rules.

At this moment, this is functionally a no-op, as the interface to configure rules will be done in a following PR.

@marcotc marcotc added the core Involves Datadog core libraries label Jun 20, 2022
@marcotc
marcotc requested a review from a team June 20, 2022 21:20
@marcotc marcotc self-assigned this Jun 20, 2022
Comment thread spec/datadog/tracing/tracer_spec.rb
return if trace_op.sampled?

# Return as soon as one rule returns non-nil
# DEV: `all?{|x|x.nil?}` is faster than `any?{|x|!x.nil?}`

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Cool! I don't know about all?{|x|x.nil?} is faster than any?{|x|!x.nil?}

@ivoanjo ivoanjo left a comment

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

👍 Looks reasonable!

Comment thread lib/datadog/tracing/sampling/span/sampler.rb Outdated
Comment thread lib/datadog/tracing/tracer.rb
Comment on lines +348 to +349
events.span_finished.subscribe do |event_span, event_trace_op|
sample_span(event_trace_op, event_span)

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: There's a bit of a trade-off here in terms of where logic lives, but have you considered having the logic of "we don't even call the span sampler if the trace has already been sampled" here?

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I like hiding the logic that is specific to Single Span Sampling away, inside the @span_sampler. I see it as the tracer doesn't now, it just calls the @span_sampler and the sampler has to figure it out, as the tracer doesn't really care.

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I guess. All these components are quite inter-related anyway -- e.g. the span sampler "knows" things about the tracer and traces, e.g. when traces are going to be sampled anyway or not. +1 if you prefer this option I think it's reasonable; we can always adjust laster.

Comment on lines +473 to 478
def sample_span(trace_op, span)
begin
@span_sampler.sample!(trace_op, span)
rescue StandardError => e
Datadog.logger.warn { "Failed to sample span: #{e.class.name} #{e} at #{Array(e.backtrace).first}" }
end

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Minor: On the other hand of the spectrum of "what should live in the Tracer class vs the Sampler", would it make sense to have the error handling live inside the sampler?

Since the Tracer is already quite complex, I think having the lower-level component being resilient would free a bit the Tracer to care more about orchestration. (On the other hand, it seems like a common pattern to have all the begin/rescues in the Tracer so... up to you as usual :D ).

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I can move this to the sampler, yeah, it seems good to hide it there.

Comment thread spec/datadog/tracing/tracer_spec.rb
Comment on lines +25 to +61
context 'with matching rules' do
let(:rules) { [Datadog::Tracing::Sampling::Span::Rule.new(match_all, sample_rate: 1.0, rate_limit: 3)] }

context 'a kept trace' do
before { trace_op.keep! }

it_behaves_like 'does not modify span'
end

context 'a rejected trace' do
before { trace_op.reject! }

it 'sets mechanism, rule rate and rate limit metrics' do
sample!

expect(span_op.get_metric('_dd.span_sampling.mechanism')).to eq(8)
expect(span_op.get_metric('_dd.span_sampling.rule_rate')).to eq(1.0)
expect(span_op.get_metric('_dd.span_sampling.max_per_second')).to eq(3)
end

context 'multiple rules' do
let(:rules) do
[
Datadog::Tracing::Sampling::Span::Rule.new(match_all, sample_rate: 1.0, rate_limit: 3),
Datadog::Tracing::Sampling::Span::Rule.new(match_all, sample_rate: 0.5, rate_limit: 2),
]
end

it 'applies the first matching rule' do
sample!

expect(span_op.get_metric('_dd.span_sampling.mechanism')).to eq(8)
expect(span_op.get_metric('_dd.span_sampling.rule_rate')).to eq(1.0)
expect(span_op.get_metric('_dd.span_sampling.max_per_second')).to eq(3)
end
end
end

Copy link
Copy Markdown
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

More of a duplication thing, but these tests are a lot more about the matcher/rule than the Sampler. It's not particularly bad, but perhaps it's not worth asserting that every metric gets set, for instance, since we already have test coverage for that.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Always a though judgment call, let me see how it looks with more simplified checks.

Copy link
Copy Markdown
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I removed a few of the internal assumptions.

@marcotc
marcotc force-pushed the single-span-parser branch 3 times, most recently from e5ba346 to de3b4a3 Compare June 30, 2022 19:24
Base automatically changed from single-span-parser to feature-single-span-sampling June 30, 2022 19:37
@marcotc
marcotc force-pushed the single-span-sampler branch from 2b23264 to 8dc706f Compare June 30, 2022 19:46
@marcotc
marcotc merged commit 6a1889a into feature-single-span-sampling Jul 5, 2022
@marcotc
marcotc deleted the single-span-sampler branch July 5, 2022 23:01
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

core Involves Datadog core libraries

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants