Skip to content

Conversation

@anuraaga
Copy link
Contributor

Previous PRs have focused on the composable versions of existing samplers. This adds one of the new ones, ComposableRuleBased.

https://opentelemetry.io/docs/specs/otel/trace/sdk/#composablerulebased

Though technically a similar one has been in contrib for a while - IIUC, the agent uses it now adays so would be good to confirm the general usability from a javaagent perspective too /cc @jaydeluca

@anuraaga anuraaga requested a review from a team as a code owner October 23, 2025 07:43
this.rules = rules.toArray(new SamplingRule[0]);

StringBuilder description = new StringBuilder("ComposableRuleBasedSampler{[");
if (this.rules.length > 0) {
Copy link
Contributor Author

@anuraaga anuraaga Oct 23, 2025

Choose a reason for hiding this comment

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

I considered whether empty should be an error, but I could conceive of cases that update the rules dynamically in a sort of "default-to-deny-all, sometimes accept something" type of situation. If making empty an error, that's still implementable though with an explicit catch-all and drop rule, so open to thoughts.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will go with it for now but realized that this is probably something to just confirm on the spec

import java.util.List;

/** A builder for a composable rule-based sampler. */
public final class ComposableRuleBasedSamplerBuilder {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

This is just an initial implementation. Presumably this should have at least a few helpers on it, addAttributePattern for example

* Returns a description of the {@link SamplingPredicate}. This may be displayed on debug pages or
* in the logs.
*/
String getDescription();
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Thought long on whether this should be a FunctionalInterface, but I felt just like Sampler, this is too important to not require

Copy link
Member

Choose a reason for hiding this comment

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

What are you thoughts on Sampler#getDescription() and this? I've always seen Sampler#getDescription() and thought it unnecessary because:

  1. Its not used anywhere in the SDK
  2. Its just like Object#toString(), but you're forced to implement it

Maybe the point you're making is that its important to have a human readable description of the sampler for things like OpenTelemetrySdk#toString(), and so its good to force sampler to print a description?

If so, I don't necessarily disagree, but then I would have liked to have getDescription() on all SDK plugin interfaces (i.e. SpanExporter, SpanProcessor, etc).

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah it's a good point that with discipline, it's enough to implement toString sensibly at least in the SDK implementations, that was generally the case in zipkin. I can imagine a world without Sampler#getDescription() working out fine. But that isn't the world - for this, it feels to me we can't implement Sampler#getDescription() properly without ensuring predicates do the same. We could still suggest strongly to implement toString for use there if it seems better though.

Copy link
Member

@jack-berg jack-berg Oct 30, 2025

Choose a reason for hiding this comment

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

Yeah I've definitely run into that problem with OpenTelemetrySdk#toString() having sub-optimal results unless every sub-component follows the convention of a useful toString() implementation. In retrospect I wish we would have had getDescription be required on all SDK extension plugin interfaces.

I don't have a strong opinion here. I lean slightly towards relying on toString() because we missed the boat on getDescription() elsewhere, but don't feel strongly. Requiring getDescription will improve the string output for this narrow part of the codebase, which is worth something.

Copy link
Contributor Author

Choose a reason for hiding this comment

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

Sounds good, I removed getDescription - always good to err on the side of less API. I added a javadoc strongly recommending toString instead.

@codecov
Copy link

codecov bot commented Oct 23, 2025

Codecov Report

✅ All modified and coverable lines are covered by tests.
✅ Project coverage is 90.17%. Comparing base (18780a3) to head (65ad8e7).
⚠️ Report is 16 commits behind head on main.

Additional details and impacted files
@@            Coverage Diff            @@
##               main    #7787   +/-   ##
=========================================
  Coverage     90.17%   90.17%           
- Complexity     7189     7216   +27     
=========================================
  Files           814      819    +5     
  Lines         21730    21767   +37     
  Branches       2129     2133    +4     
=========================================
+ Hits          19594    19629   +35     
- Misses         1467     1468    +1     
- Partials        669      670    +1     

☔ View full report in Codecov by Sentry.
📢 Have feedback on the report? Share it here.

🚀 New features to boost your workflow:
  • ❄️ Test Analytics: Detect flaky tests, report on failures, and find test suite problems.

@jack-berg
Copy link
Member

Though technically a similar one has been in contrib for a while - IIUC, the agent uses it now adays so would be good to confirm the general usability from a javaagent perspective too

Best way for these to be usable in the agent is to drive the declarative configuration implementation of this, which includes:

At that point, users would be able to define complex composable samplers in YAML and use them in the agent without an agent extension.

@anuraaga
Copy link
Contributor Author

Thanks @jack-berg - agree that it sounds like a good idea to get new samplers into configuration. I raised some PR/issues there to see if we can move forward. At the same time, I guess we can get this in to have the SDK side moving as well.

Copy link
Member

@jack-berg jack-berg left a comment

Choose a reason for hiding this comment

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

Couple minor comments but looks good overall. Thanks!

import java.util.List;

/** A predicate for a composable sampler, indicating whether a set of sampling arguments matches. */
public interface SamplingPredicate {
Copy link
Member

Choose a reason for hiding this comment

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

The spec seems incomplete in that it lists a rule as a predicate, ComposableSampler pair, but fails to describe what parameters the predicate can operate on. I think including all the parameters of ComposableSampler#getSamplingINtent is the natural choice.

open-telemetry/opentelemetry-specification#4701

* Returns a description of the {@link SamplingPredicate}. This may be displayed on debug pages or
* in the logs.
*/
String getDescription();
Copy link
Member

Choose a reason for hiding this comment

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

What are you thoughts on Sampler#getDescription() and this? I've always seen Sampler#getDescription() and thought it unnecessary because:

  1. Its not used anywhere in the SDK
  2. Its just like Object#toString(), but you're forced to implement it

Maybe the point you're making is that its important to have a human readable description of the sampler for things like OpenTelemetrySdk#toString(), and so its good to force sampler to print a description?

If so, I don't necessarily disagree, but then I would have liked to have getDescription() on all SDK plugin interfaces (i.e. SpanExporter, SpanProcessor, etc).

Copy link
Contributor Author

@anuraaga anuraaga left a comment

Choose a reason for hiding this comment

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

Thanks @jack-berg sorry for the delay

* Returns a description of the {@link SamplingPredicate}. This may be displayed on debug pages or
* in the logs.
*/
String getDescription();
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Yeah it's a good point that with discipline, it's enough to implement toString sensibly at least in the SDK implementations, that was generally the case in zipkin. I can imagine a world without Sampler#getDescription() working out fine. But that isn't the world - for this, it feels to me we can't implement Sampler#getDescription() properly without ensuring predicates do the same. We could still suggest strongly to implement toString for use there if it seems better though.

this.rules = rules.toArray(new SamplingRule[0]);

StringBuilder description = new StringBuilder("ComposableRuleBasedSampler{[");
if (this.rules.length > 0) {
Copy link
Contributor Author

Choose a reason for hiding this comment

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

Will go with it for now but realized that this is probably something to just confirm on the spec

Copy link
Member

@jack-berg jack-berg left a comment

Choose a reason for hiding this comment

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

Let me know where you land on getDescription(). I'm happy to merge either way.

Thanks!

@jack-berg jack-berg merged commit dfdc85f into open-telemetry:main Oct 31, 2025
29 checks passed
@otelbot
Copy link
Contributor

otelbot bot commented Oct 31, 2025

Thank you for your contribution @anuraaga! 🎉 We would like to hear from you about your experience contributing to OpenTelemetry by taking a few minutes to fill out this survey.

the-clam pushed a commit to the-clam/opentelemetry-java that referenced this pull request Nov 6, 2025
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants