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

Updating README for Consistent Probability Samplers #1501

Closed
wants to merge 19 commits into from
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
19 commits
Select commit Hold shift + click to select a range
f242459
Composite Samplers prototype
PeterF778 Aug 30, 2024
23690a4
Refactoring.
PeterF778 Aug 30, 2024
a8443c4
Refactoring, adding a new test case based on https://github.com/open-…
PeterF778 Sep 3, 2024
9b53416
Update consistent-sampling/src/main/java/io/opentelemetry/contrib/sam…
PeterF778 Sep 5, 2024
b3b57ac
Update consistent-sampling/src/main/java/io/opentelemetry/contrib/sam…
PeterF778 Sep 5, 2024
7c13e4a
Update consistent-sampling/src/main/java/io/opentelemetry/contrib/sam…
PeterF778 Sep 5, 2024
3308d4a
Update consistent-sampling/src/main/java/io/opentelemetry/contrib/sam…
PeterF778 Sep 5, 2024
49fd364
Update consistent-sampling/src/test/java/io/opentelemetry/contrib/sam…
PeterF778 Sep 5, 2024
7db19ea
Update consistent-sampling/src/main/java/io/opentelemetry/contrib/sam…
PeterF778 Sep 5, 2024
75201a9
Update consistent-sampling/src/main/java/io/opentelemetry/contrib/sam…
PeterF778 Sep 5, 2024
e017c45
Update consistent-sampling/src/main/java/io/opentelemetry/contrib/sam…
PeterF778 Sep 5, 2024
02c3411
Update consistent-sampling/src/main/java/io/opentelemetry/contrib/sam…
PeterF778 Sep 5, 2024
66cf1d7
Update consistent-sampling/src/test/java/io/opentelemetry/contrib/sam…
PeterF778 Sep 5, 2024
9a21ab1
Update consistent-sampling/src/main/java/io/opentelemetry/contrib/sam…
PeterF778 Sep 5, 2024
1d0ba27
Update consistent-sampling/src/main/java/io/opentelemetry/contrib/sam…
PeterF778 Sep 5, 2024
eb66327
Addressing code review suggestions.
PeterF778 Sep 5, 2024
03104e7
Generalizing CoinFlipSampler.
PeterF778 Sep 6, 2024
17aa757
Adding a test for low-resolution clock.
PeterF778 Sep 10, 2024
0cb1d0d
Updating README file
PeterF778 Oct 16, 2024
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
35 changes: 34 additions & 1 deletion consistent-sampling/README.md
Original file line number Diff line number Diff line change
@@ -1,8 +1,15 @@
# Consistent sampling

This component adds various Sampler implementations for consistent sampling as defined by
There are two major components included here.

## Original proposal implementation

The original specification for consistent probability sampling is defined by
<https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/trace/tracestate-probability-sampling.md>
and <https://github.com/open-telemetry/opentelemetry-specification/pull/2047>.
It supports sampling probabilities that are power of 2 (1, 1/2, 1/4, ...), and uses 8-bit `r-value` and 8-bit `p-value` in tracestate.

The implementation of this proposal is contained by the package `io/opentelemetry/contrib/sampler/consistent` in this repository and provides various Sampler implementations.

* **ConsistentSampler**:
abstract base class of all consistent sampler implementations below
Expand All @@ -23,6 +30,32 @@ and <https://github.com/open-telemetry/opentelemetry-specification/pull/2047>.
a rate limiting sampler based on exponential smoothing that dynamically adjusts the sampling
probability based on the estimated rate of spans occurring to satisfy a given rate of sampled spans

## Current proposal implementation

The current version of the specification for consistent probability sampling is described by
<https://github.com/open-telemetry/oteps/blob/main/text/trace/0235-sampling-threshold-in-trace-state.md>.
It uses 56 bits for representing _rejection threshold_, which corresponds to a much wider range of sampling probabilities than the original proposal.

The implementation of the current proposal is contained by the package `io/opentelemetry/contrib/sampler/consistent56` in this repository and provides implementation for a number of different Samplers.

* **ConsistentSampler**
abstract base class for all consistent sampler implementations
* **ComposableSampler**:
interface used to build hierarchies of Samplers, see [Composite Samplers](https://github.com/open-telemetry/oteps/pull/250)
* **ConsistentAlwaysOffSampler**:
* **ConsistentAlwaysOnSampler**:
* **ConsistentAnyOfSampler**:
allows combining several consistent samplers; it samples when at least one of them would sample,
* **ConsistentParentBasedSampler**:
* **ConsistentFixedThresholdSampler**:
consistent probability sampler that uses a predefined sampling probability
* **ConsistentRateLimitingSampler**:
a rate limiting sampler based on exponential smoothing that dynamically adjusts the sampling
probability based on the estimated rate of spans occurring to satisfy a given rate of sampled spans
* **ConsistentRuleBasedSampler**
a sampler that performs stratified sampling by evaluating qualifying conditions and propagating the sampling decision from one of its delegate samplers


## Component owners

- [Otmar Ertl](https://github.com/oertl), Dynatrace
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.contrib.sampler.consistent56;

import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.trace.SpanKind;
import io.opentelemetry.context.Context;
import io.opentelemetry.sdk.trace.data.LinkData;
import java.util.List;

/** An interface for components to be used by composite consistent probability samplers. */
public interface ComposableSampler {

/**
* Returns the SamplingIntent that is used for the sampling decision. The SamplingIntent includes
* the threshold value which will be used for the sampling decision.
*
* <p>NOTE: Keep in mind, that in any case the returned threshold value must not depend directly
* or indirectly on the random value. In particular this means that the parent sampled flag must
* not be used for the calculation of the threshold as the sampled flag depends itself on the
* random value.
*/
SamplingIntent getSamplingIntent(
Context parentContext,
String name,
SpanKind spanKind,
Attributes attributes,
List<LinkData> parentLinks);

/** Return the string providing a description of the implementation. */
String getDescription();
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,13 @@

package io.opentelemetry.contrib.sampler.consistent56;

import static io.opentelemetry.contrib.sampler.consistent56.ConsistentSamplingUtil.getInvalidThreshold;

import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.trace.SpanKind;
import io.opentelemetry.context.Context;
import io.opentelemetry.sdk.trace.data.LinkData;
import java.util.List;
import javax.annotation.concurrent.Immutable;

@Immutable
Expand All @@ -19,8 +26,14 @@ static ConsistentAlwaysOffSampler getInstance() {
}

@Override
protected long getThreshold(long parentThreshold, boolean isRoot) {
return ConsistentSamplingUtil.getMaxThreshold();
public SamplingIntent getSamplingIntent(
Context parentContext,
String name,
SpanKind spanKind,
Attributes attributes,
List<LinkData> parentLinks) {

return () -> getInvalidThreshold();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,11 @@

import static io.opentelemetry.contrib.sampler.consistent56.ConsistentSamplingUtil.getMinThreshold;

import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.trace.SpanKind;
import io.opentelemetry.context.Context;
import io.opentelemetry.sdk.trace.data.LinkData;
import java.util.List;
import javax.annotation.concurrent.Immutable;

@Immutable
Expand All @@ -21,8 +26,14 @@ static ConsistentAlwaysOnSampler getInstance() {
}

@Override
protected long getThreshold(long parentThreshold, boolean isRoot) {
return getMinThreshold();
public SamplingIntent getSamplingIntent(
Context parentContext,
String name,
SpanKind spanKind,
Attributes attributes,
List<LinkData> parentLinks) {

return () -> getMinThreshold();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.contrib.sampler.consistent56;

import static io.opentelemetry.contrib.sampler.consistent56.ConsistentSamplingUtil.getInvalidThreshold;
import static io.opentelemetry.contrib.sampler.consistent56.ConsistentSamplingUtil.isValidThreshold;

import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.api.trace.SpanKind;
import io.opentelemetry.api.trace.TraceState;
import io.opentelemetry.context.Context;
import io.opentelemetry.sdk.trace.data.LinkData;
import java.util.List;
import java.util.stream.Collectors;
import java.util.stream.Stream;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;

/**
* A consistent sampler that queries all its delegate samplers for their sampling threshold, and
* uses the minimum threshold value received.
*/
@Immutable
final class ConsistentAnyOf extends ConsistentSampler {

private final ComposableSampler[] delegates;

private final String description;

/**
* Constructs a new consistent AnyOf sampler using the provided delegate samplers.
*
* @param delegates the delegate samplers
*/
ConsistentAnyOf(@Nullable ComposableSampler... delegates) {
if (delegates == null || delegates.length == 0) {
throw new IllegalArgumentException(
"At least one delegate must be specified for ConsistentAnyOf");
}

this.delegates = delegates;

this.description =
Stream.of(delegates)
.map(Object::toString)
.collect(Collectors.joining(",", "ConsistentAnyOf{", "}"));
}

@Override
public SamplingIntent getSamplingIntent(
Context parentContext,
String name,
SpanKind spanKind,
Attributes attributes,
List<LinkData> parentLinks) {

SamplingIntent[] intents = new SamplingIntent[delegates.length];
int k = 0;
long minimumThreshold = getInvalidThreshold();
for (ComposableSampler delegate : delegates) {
SamplingIntent delegateIntent =
delegate.getSamplingIntent(parentContext, name, spanKind, attributes, parentLinks);
long delegateThreshold = delegateIntent.getThreshold();
if (isValidThreshold(delegateThreshold)) {
if (isValidThreshold(minimumThreshold)) {
minimumThreshold = Math.min(delegateThreshold, minimumThreshold);
} else {
minimumThreshold = delegateThreshold;
}
}
intents[k++] = delegateIntent;
}

long resultingThreshold = minimumThreshold;

return new SamplingIntent() {
@Override
public long getThreshold() {
return resultingThreshold;
}

@Override
public Attributes getAttributes() {
AttributesBuilder builder = Attributes.builder();
for (SamplingIntent intent : intents) {
builder = builder.putAll(intent.getAttributes());
}
return builder.build();
}

@Override
public TraceState updateTraceState(TraceState previousState) {
for (SamplingIntent intent : intents) {
previousState = intent.updateTraceState(previousState);
}
return previousState;
}
};
}

@Override
public String getDescription() {
return description;
}
}

This file was deleted.

This file was deleted.

Loading
Loading