-
Notifications
You must be signed in to change notification settings - Fork 150
Composite Samplers prototype #1443
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
Changes from all commits
f242459
23690a4
a8443c4
9b53416
b3b57ac
7c13e4a
3308d4a
49fd364
7db19ea
75201a9
e017c45
02c3411
66cf1d7
9a21ab1
1d0ba27
eb66327
03104e7
17aa757
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
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 |
---|---|---|
@@ -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.
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -7,6 +7,14 @@ | |
|
||
import static io.opentelemetry.contrib.sampler.consistent56.ConsistentSamplingUtil.calculateSamplingProbability; | ||
import static io.opentelemetry.contrib.sampler.consistent56.ConsistentSamplingUtil.checkThreshold; | ||
import static io.opentelemetry.contrib.sampler.consistent56.ConsistentSamplingUtil.getInvalidThreshold; | ||
import static io.opentelemetry.contrib.sampler.consistent56.ConsistentSamplingUtil.getMaxThreshold; | ||
|
||
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; | ||
|
||
public class ConsistentFixedThresholdSampler extends ConsistentSampler { | ||
|
||
|
@@ -18,7 +26,7 @@ protected ConsistentFixedThresholdSampler(long threshold) { | |
this.threshold = threshold; | ||
|
||
String thresholdString; | ||
if (threshold == ConsistentSamplingUtil.getMaxThreshold()) { | ||
if (threshold == getMaxThreshold()) { | ||
thresholdString = "max"; | ||
} else { | ||
thresholdString = | ||
|
@@ -41,7 +49,18 @@ public String getDescription() { | |
} | ||
|
||
@Override | ||
protected long getThreshold(long parentThreshold, boolean isRoot) { | ||
return threshold; | ||
public SamplingIntent getSamplingIntent( | ||
Context parentContext, | ||
String name, | ||
SpanKind spanKind, | ||
Attributes attributes, | ||
List<LinkData> parentLinks) { | ||
|
||
return () -> { | ||
if (threshold == getMaxThreshold()) { | ||
return getInvalidThreshold(); | ||
} | ||
Comment on lines
+60
to
+62
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Please comment, I had to go review https://github.com/open-telemetry/opentelemetry-java-contrib/blob/main/consistent-sampling/src/main/java/io/opentelemetry/contrib/sampler/consistent56/ConsistentSamplingUtil.java to understand that Why does the Util package distinguish Max and Invalid? (Why aren't they a single value, maybe?) There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This probably requires a cleanup. The prototype currently uses |
||
return threshold; | ||
}; | ||
} | ||
} |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
This looks and feels like what the OTel Trace SDK
TraceIdRatioBased
sampler wants to be. 👍