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

Rename ParentOrElse to ParentBased and generalize to support all cases #1577

Merged
merged 12 commits into from
Aug 28, 2020
107 changes: 90 additions & 17 deletions sdk/tracing/src/main/java/io/opentelemetry/sdk/trace/Samplers.java
Original file line number Diff line number Diff line change
Expand Up @@ -147,14 +147,47 @@ public static Sampler alwaysOff() {
* whether or not to sample. If there is no parent, the Sampler uses the provided Sampler delegate
* to determine the sampling decision.
*
* @param delegateSampler the {@code Sampler} which is used to make the sampling decisions if the
* parent does not exist.
* @param root the {@code Sampler} which is used to make the sampling decisions if the parent does
* not exist.
* @return a {@code Sampler} that follows the parent's sampling decision if one exists, otherwise
* following the delegate sampler's decision.
* following the root sampler's decision.
* @since 0.7.0
*/
public static Sampler parentOrElse(Sampler delegateSampler) {
return new ParentOrElse(delegateSampler);
public static Sampler parentBased(Sampler root) {
return new ParentBased(root);
}

/**
* Returns a {@link Sampler} that always makes the same decision as the parent {@link Span} to
* whether or not to sample. If there is no parent, the Sampler uses the provided Sampler delegate
* to determine the sampling decision.
*
* @param root the required {@code Sampler} which is used to make the sampling decisions if the
* parent does not exist.
* @param remoteParentSampled the optional {@code Sampler} which is used to make the sampling
* decisions if the remote parent exist and is sampled.
* @param remoteParentNotSampled the optional {@code Sampler} which is used to make the sampling
* decisions if the remote parent exist and is not sampled.
* @param localParentSampled the optional {@code Sampler} which is used to make the sampling
* decisions if the local parent exist and is sampled.
* @param localParentNotSampled the optional {@code Sampler} which is used to make the sampling
* decisions if the local parent exist and is not sampled.
* @return a {@code Sampler} that follows the parent's sampling decision if one exists, otherwise
* following the root sampler and other optional sampler's decision.
* @since 0.8.0
*/
public static Sampler parentBased(
dengliming marked this conversation as resolved.
Show resolved Hide resolved
Sampler root,
Sampler remoteParentSampled,
Sampler remoteParentNotSampled,
Sampler localParentSampled,
Sampler localParentNotSampled) {
return new ParentBased(
root,
remoteParentSampled,
remoteParentNotSampled,
localParentSampled,
localParentNotSampled);
}

/**
Expand Down Expand Up @@ -214,11 +247,36 @@ public String getDescription() {
}

@Immutable
static class ParentOrElse implements Sampler {
private final Sampler delegateSampler;
static class ParentBased implements Sampler {
private final Sampler root;
private Sampler remoteParentSampled = alwaysOn();
private Sampler remoteParentNotSampled = alwaysOff();
private Sampler localParentSampled = alwaysOn();
private Sampler localParentNotSampled = alwaysOff();

dengliming marked this conversation as resolved.
Show resolved Hide resolved
ParentBased(Sampler root) {
this.root = root;
}

ParentOrElse(Sampler delegateSampler) {
this.delegateSampler = delegateSampler;
ParentBased(
Sampler root,
Sampler remoteParentSampled,
Sampler remoteParentNotSampled,
Sampler localParentSampled,
Sampler localParentNotSampled) {
this.root = root;
if (remoteParentSampled != null) {
this.remoteParentSampled = remoteParentSampled;
}
if (remoteParentNotSampled != null) {
this.remoteParentNotSampled = remoteParentNotSampled;
}
if (localParentSampled != null) {
this.localParentSampled = localParentSampled;
}
if (localParentNotSampled != null) {
this.localParentNotSampled = localParentNotSampled;
}
}

// If a parent is set, always follows the same sampling decision as the parent.
Expand All @@ -231,19 +289,34 @@ public SamplingResult shouldSample(
Kind spanKind,
ReadableAttributes attributes,
List<Link> parentLinks) {
if (parentContext.isValid()) {
if (parentContext.getTraceFlags().isSampled()) {
return EMPTY_RECORDED_AND_SAMPLED_SAMPLING_RESULT;
}
return EMPTY_NOT_SAMPLED_OR_RECORDED_SAMPLING_RESULT;
if (!parentContext.isValid()) {
return this.root.shouldSample(
parentContext, traceId, name, spanKind, attributes, parentLinks);
}

if (parentContext.isRemote()) {
return parentContext.getTraceFlags().isSampled()
? this.remoteParentSampled.shouldSample(
parentContext, traceId, name, spanKind, attributes, parentLinks)
: this.remoteParentNotSampled.shouldSample(
parentContext, traceId, name, spanKind, attributes, parentLinks);
}
return this.delegateSampler.shouldSample(
parentContext, traceId, name, spanKind, attributes, parentLinks);
return parentContext.getTraceFlags().isSampled()
? this.localParentSampled.shouldSample(
parentContext, traceId, name, spanKind, attributes, parentLinks)
: this.localParentNotSampled.shouldSample(
parentContext, traceId, name, spanKind, attributes, parentLinks);
}

@Override
public String getDescription() {
return String.format("ParentOrElse{%s}", this.delegateSampler.getDescription());
return String.format(
"ParentBased{root:%s,remoteParentSampled:%s,remoteParentNotSampled:%s,localParentSampled:%s,localParentNotSampled:%s}",
this.root.getDescription(),
this.remoteParentSampled.getDescription(),
this.remoteParentNotSampled.getDescription(),
this.localParentSampled.getDescription(),
this.localParentNotSampled.getDescription());
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -87,7 +87,7 @@
public abstract class TraceConfig {
// These values are the default values for all the global parameters.
// TODO: decide which default sampler to use
private static final Sampler DEFAULT_SAMPLER = Samplers.parentOrElse(Samplers.alwaysOn());
private static final Sampler DEFAULT_SAMPLER = Samplers.parentBased(Samplers.alwaysOn());
private static final int DEFAULT_SPAN_MAX_NUM_ATTRIBUTES = 32;
private static final int DEFAULT_SPAN_MAX_NUM_EVENTS = 128;
private static final int DEFAULT_SPAN_MAX_NUM_LINKS = 32;
Expand Down
Loading