Skip to content

[processor/tailsampling] add sampling_strategy with root-only mode and stateful-policy guard#46701

Closed
carsonip wants to merge 9 commits into
open-telemetry:mainfrom
carsonip:tailsampling-sampling-strategy-enum
Closed

[processor/tailsampling] add sampling_strategy with root-only mode and stateful-policy guard#46701
carsonip wants to merge 9 commits into
open-telemetry:mainfrom
carsonip:tailsampling-sampling-strategy-enum

Conversation

@carsonip
Copy link
Copy Markdown
Contributor

@carsonip carsonip commented Mar 5, 2026

Description

Alternative to #46613

This PR adds a new tail sampling processor config, sampling_strategy, to support root-span-triggered decisioning while preserving classic tail-sampling behavior as the default.

Motivation:

  • Some workloads benefit from making a decision as soon as the root span arrives instead of waiting for timer-driven evaluation.
  • A strategy-based config makes decision timing/data semantics explicit and extensible.
  • Root-only decision mode should reject stateful evaluators to avoid incompatible behavior.

Implementation details:

  • Adds sampling_strategy to config/schema/docs with two modes:
    • full-trace-way-out (default): classic tail sampling from accumulated trace data.
    • root-span-only-way-in: decide immediately on root span arrival using root-span-only trace data.
  • Root-only mode processing behavior:
    • trace IDs are not scheduled into timer decision batches,
    • decision is executed immediately when root span is observed,
    • root-triggering batch is merged in memory and released directly,
    • decision_wait / decision_wait_after_root_received do not drive decisions.
  • Adds IsStateful() to samplingpolicy.Evaluator and implements it across built-in policies/combinators.
  • Enforces root-only compatibility during policy loading:
    • when sampling_strategy=root-span-only-way-in, evaluators reporting IsStateful()==true are rejected.
  • Keeps strategy identifiers non-exported to the package:
    • private typed enum + private constants.

Behavior notes:

  • full-trace-way-out remains the default behavior.
  • In root-span-only-way-in, policies that require non-root span data are not meaningful.
  • Stateful evaluators are blocked in root-only mode by validation at policy construction time.

Link to tracking issue

Fixes #46600

Testing

  • Added/updated unit tests for sampling strategy and root-only behavior.
  • Added/updated tests for IsStateful() behavior in evaluators/combinators.
  • Added/updated tests for root-only mode stateful-policy rejection.
  • Ran go test ./... in processor/tailsamplingprocessor.

Documentation

  • Updated processor/tailsamplingprocessor/README.md for sampling_strategy and mode semantics.

Made with Cursor

carsonip added 8 commits March 3, 2026 21:32
When sample_on_root_span_only is enabled and a root span arrives, evaluate immediately and avoid appending that root-triggering batch to tail storage. For sampled traces, merge the current batch in memory with any previously buffered spans and release once; add a regression test to verify append/take behavior.

Assisted-by: ChatGPT
Made-with: Cursor
Resolve tailsamplingprocessor conflict by keeping root-only immediate decision path and avoiding appending the root-triggering batch before release.

Made-with: Cursor
…ng_strategy

Introduce a string enum sampling_strategy to describe decision timing semantics explicitly, with full-trace-way-out as default and root-span-only-way-in for immediate root-based decisions. Update processor logic, schema, docs, and tests to use the new strategy and validate unsupported values.

Assisted-by: ChatGPT 5.3
Made-with: Cursor
Add IsStateful() to the samplingpolicy.Evaluator interface and implement it across all tail sampling evaluators while keeping the previous stateful semantics based on evaluator-held state across evaluations.

Made-with: Cursor
…fulness

Enforce root-span-only-way-in compatibility at policy construction time by rejecting evaluators that report IsStateful(), so statefulness stays defined by policy implementations and extensions without duplicating policy rules in config validation.

Made-with: Cursor
Remove newTracesProcessor fallback for empty sampling_strategy and update direct Config literals in tests/benchmarks/fuzz to set full-trace-way-out explicitly, keeping validation strict while relying on default config initialization in production paths.

Made-with: Cursor
Keep sampling_strategy as a typed enum but make the type and constants package-private so they are not exported outside tailsamplingprocessor, while preserving strict validation and existing behavior.

Made-with: Cursor
@carsonip carsonip changed the title [processor/tailsampling] replace sample_on_root_span_only with sampling_strategy [processor/tailsampling] add sampling_strategy with root-only mode and stateful-policy guard Mar 5, 2026
Document sampling_strategy in the existing flat option-list style and describe both values inline with clearer behavior semantics for decision timing and root-only evaluation scope.

Made-with: Cursor
@carsonip
Copy link
Copy Markdown
Contributor Author

carsonip commented Mar 9, 2026

Superseded by #46762

@carsonip carsonip closed this Mar 9, 2026
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.

[processor/tailsampling] Optimize performance by adjusting policy evaluation timing

1 participant