feat(sampler-composite): add ComposableAnnotatingSampler and ComposableRuleBasedSampler#6305
Conversation
Codecov Report✅ All modified and coverable lines are covered by tests. Additional details and impacted files@@ Coverage Diff @@
## main #6305 +/- ##
==========================================
+ Coverage 95.48% 95.49% +0.01%
==========================================
Files 363 365 +2
Lines 11563 11594 +31
Branches 2669 2673 +4
==========================================
+ Hits 11041 11072 +31
Misses 522 522
🚀 New features to boost your workflow:
|
|
FWIW, the though, without the line-breaks and indentation. I have not added a representation of the |
| private readonly rules: SamplingRule[]; | ||
| private readonly description: string; | ||
|
|
||
| constructor(rules: SamplingRule[]) { |
There was a problem hiding this comment.
Not sure if this is the good reference but I read ComposableSampler gets 2 params:
- the rules
- span kind (optional)
I the span kind is provided the getSamplingIntent logic changes a bit. From the docs
For calculating the SamplingIntent, if the Span kind matches the specified kind,
or the specified kind is not given, the sampler goes through the list in the provided
order and calls SpanMatches on Predicates passing the same arguments as
received. If a call returns true, the result is as returned by GetSamplingIntent called
on the corresponding Composable - no other Predicates are evaluated. If the
SpanKind does not match, or none of the calls to SpanMatches yield true, the result
is obtained by calling GetSamplingIntent on ConsistentAlwaysOffSampler.
There was a problem hiding this comment.
As we discussed, the specifics from the OTEPs changed in some cases when making it to the spec. https://opentelemetry.io/docs/specs/otel/trace/sdk/#composablerulebased says:
Required parameters:
rules - A list of (Predicate, ComposableSampler) pairs, where Predicate is a function that evaluates whether a rule applies
Hence no separate span kind argument. Note that the predicate (type SamplingPredicate does get the spanKind, along with other arguments for its decision).
| toString(): string; | ||
| } | ||
|
|
||
| export type SamplingPredicate = ( |
There was a problem hiding this comment.
(same thing about the reference The docs define a SpanMatches method in the predicate. So its defined as an interface rather than a function. My guess is by having
interface SamplingPredicate {
spanMatches: (...args: Parameters<Sampler['shouldSample']>) => boolean;
}implementors are able to provide a predicate that holds state...
Writing that last sentence I realised this can be achieved using closures so you can ignore my comment.
There was a problem hiding this comment.
Same answer as above. The language that made it into the spec is where Predicate is a function that evaluates whether a rule applies.
In #5839 the initial work adding composable samplers, specified by:
That PR added most of the described composable samplers, all but
This PR adds those final two built-in composable samplers defined by the spec.
The main motivating reason for adding these is: the rule-based composable sampler is the intended path towards supporting a way to have instrumentation skip some some routes, e.g. an HTTP /healthcheck route.
See https://opentelemetry.io/blog/2025/declarative-config/#health-check-exclusion