Skip to content

Commit e466431

Browse files
authored
consistent sampler prototypes using 56 bits of randomness (#1063)
1 parent 27e17fd commit e466431

21 files changed

+2086
-1
lines changed

consistent-sampling/build.gradle.kts

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@ plugins {
44
}
55

66
description = "Sampler and exporter implementations for consistent sampling"
7-
otelJava.moduleName.set("io.opentelemetry.contrib.sampler.consistent")
7+
otelJava.moduleName.set("io.opentelemetry.contrib.sampler")
88

99
dependencies {
1010
api("io.opentelemetry:opentelemetry-sdk-trace")
Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.contrib.sampler.consistent56;
7+
8+
import javax.annotation.concurrent.Immutable;
9+
10+
@Immutable
11+
final class ConsistentAlwaysOffSampler extends ConsistentSampler {
12+
13+
ConsistentAlwaysOffSampler(RandomValueGenerator randomValueGenerator) {
14+
super(randomValueGenerator);
15+
}
16+
17+
@Override
18+
protected long getThreshold(long parentThreshold, boolean isRoot) {
19+
return 0;
20+
}
21+
22+
@Override
23+
public String getDescription() {
24+
return "ConsistentAlwaysOffSampler";
25+
}
26+
}
Lines changed: 28 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,28 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.contrib.sampler.consistent56;
7+
8+
import static io.opentelemetry.contrib.sampler.consistent56.ConsistentSamplingUtil.getMaxThreshold;
9+
10+
import javax.annotation.concurrent.Immutable;
11+
12+
@Immutable
13+
final class ConsistentAlwaysOnSampler extends ConsistentSampler {
14+
15+
ConsistentAlwaysOnSampler(RandomValueGenerator randomValueGenerator) {
16+
super(randomValueGenerator);
17+
}
18+
19+
@Override
20+
protected long getThreshold(long parentThreshold, boolean isRoot) {
21+
return getMaxThreshold();
22+
}
23+
24+
@Override
25+
public String getDescription() {
26+
return "ConsistentAlwaysOnSampler";
27+
}
28+
}
Lines changed: 56 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,56 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.contrib.sampler.consistent56;
7+
8+
import static java.util.Objects.requireNonNull;
9+
10+
import javax.annotation.concurrent.Immutable;
11+
12+
/**
13+
* A consistent sampler composed of two consistent samplers.
14+
*
15+
* <p>This sampler samples if both samplers would sample.
16+
*/
17+
@Immutable
18+
final class ConsistentComposedAndSampler extends ConsistentSampler {
19+
20+
private final ConsistentSampler sampler1;
21+
private final ConsistentSampler sampler2;
22+
private final String description;
23+
24+
ConsistentComposedAndSampler(
25+
ConsistentSampler sampler1,
26+
ConsistentSampler sampler2,
27+
RandomValueGenerator randomValueGenerator) {
28+
super(randomValueGenerator);
29+
this.sampler1 = requireNonNull(sampler1);
30+
this.sampler2 = requireNonNull(sampler2);
31+
this.description =
32+
"ConsistentComposedAndSampler{"
33+
+ "sampler1="
34+
+ sampler1.getDescription()
35+
+ ",sampler2="
36+
+ sampler2.getDescription()
37+
+ '}';
38+
}
39+
40+
@Override
41+
protected long getThreshold(long parentThreshold, boolean isRoot) {
42+
long threshold1 = sampler1.getThreshold(parentThreshold, isRoot);
43+
long threshold2 = sampler2.getThreshold(parentThreshold, isRoot);
44+
if (ConsistentSamplingUtil.isValidThreshold(threshold1)
45+
&& ConsistentSamplingUtil.isValidThreshold(threshold2)) {
46+
return Math.min(threshold1, threshold2);
47+
} else {
48+
return ConsistentSamplingUtil.getInvalidThreshold();
49+
}
50+
}
51+
52+
@Override
53+
public String getDescription() {
54+
return description;
55+
}
56+
}
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.contrib.sampler.consistent56;
7+
8+
import static java.util.Objects.requireNonNull;
9+
10+
import javax.annotation.concurrent.Immutable;
11+
12+
/**
13+
* A consistent sampler composed of two consistent samplers.
14+
*
15+
* <p>This sampler samples if any of the two samplers would sample.
16+
*/
17+
@Immutable
18+
final class ConsistentComposedOrSampler extends ConsistentSampler {
19+
20+
private final ConsistentSampler sampler1;
21+
private final ConsistentSampler sampler2;
22+
private final String description;
23+
24+
ConsistentComposedOrSampler(
25+
ConsistentSampler sampler1,
26+
ConsistentSampler sampler2,
27+
RandomValueGenerator randomValueGenerator) {
28+
super(randomValueGenerator);
29+
this.sampler1 = requireNonNull(sampler1);
30+
this.sampler2 = requireNonNull(sampler2);
31+
this.description =
32+
"ConsistentComposedOrSampler{"
33+
+ "sampler1="
34+
+ sampler1.getDescription()
35+
+ ",sampler2="
36+
+ sampler2.getDescription()
37+
+ '}';
38+
}
39+
40+
@Override
41+
protected long getThreshold(long parentThreshold, boolean isRoot) {
42+
long threshold1 = sampler1.getThreshold(parentThreshold, isRoot);
43+
long threshold2 = sampler2.getThreshold(parentThreshold, isRoot);
44+
if (ConsistentSamplingUtil.isValidThreshold(threshold1)) {
45+
if (ConsistentSamplingUtil.isValidThreshold(threshold2)) {
46+
return Math.max(threshold1, threshold2);
47+
}
48+
return threshold1;
49+
} else {
50+
if (ConsistentSamplingUtil.isValidThreshold(threshold2)) {
51+
return threshold2;
52+
}
53+
return ConsistentSamplingUtil.getInvalidThreshold();
54+
}
55+
}
56+
57+
@Override
58+
public String getDescription() {
59+
return description;
60+
}
61+
}
Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.contrib.sampler.consistent56;
7+
8+
import static io.opentelemetry.contrib.sampler.consistent56.ConsistentSamplingUtil.calculateSamplingProbability;
9+
import static io.opentelemetry.contrib.sampler.consistent56.ConsistentSamplingUtil.checkThreshold;
10+
11+
public class ConsistentFixedThresholdSampler extends ConsistentSampler {
12+
13+
private final long threshold;
14+
private final String description;
15+
16+
protected ConsistentFixedThresholdSampler(
17+
long threshold, RandomValueGenerator randomValueGenerator) {
18+
super(randomValueGenerator);
19+
checkThreshold(threshold);
20+
this.threshold = threshold;
21+
22+
String thresholdString;
23+
if (threshold == ConsistentSamplingUtil.getMaxThreshold()) {
24+
thresholdString = "max";
25+
} else {
26+
thresholdString =
27+
ConsistentSamplingUtil.appendLast56BitHexEncodedWithoutTrailingZeros(
28+
new StringBuilder(), threshold)
29+
.toString();
30+
}
31+
32+
this.description =
33+
"ConsistentFixedThresholdSampler{threshold="
34+
+ thresholdString
35+
+ ", sampling probability="
36+
+ calculateSamplingProbability(threshold)
37+
+ "}";
38+
}
39+
40+
@Override
41+
public String getDescription() {
42+
return description;
43+
}
44+
45+
@Override
46+
protected long getThreshold(long parentThreshold, boolean isRoot) {
47+
return threshold;
48+
}
49+
}
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.contrib.sampler.consistent56;
7+
8+
import static java.util.Objects.requireNonNull;
9+
10+
import javax.annotation.concurrent.Immutable;
11+
12+
/**
13+
* A consistent sampler that makes the same sampling decision as the parent. For root spans the
14+
* sampling decision is delegated to the root sampler.
15+
*/
16+
@Immutable
17+
final class ConsistentParentBasedSampler extends ConsistentSampler {
18+
19+
private final ConsistentSampler rootSampler;
20+
21+
private final String description;
22+
23+
/**
24+
* Constructs a new consistent parent based sampler using the given root sampler and the given
25+
* thread-safe random generator.
26+
*
27+
* @param rootSampler the root sampler
28+
* @param randomValueGenerator the function to use for generating the r-value
29+
*/
30+
ConsistentParentBasedSampler(
31+
ConsistentSampler rootSampler, RandomValueGenerator randomValueGenerator) {
32+
super(randomValueGenerator);
33+
this.rootSampler = requireNonNull(rootSampler);
34+
this.description =
35+
"ConsistentParentBasedSampler{rootSampler=" + rootSampler.getDescription() + '}';
36+
}
37+
38+
@Override
39+
protected long getThreshold(long parentThreshold, boolean isRoot) {
40+
if (isRoot) {
41+
return rootSampler.getThreshold(ConsistentSamplingUtil.getInvalidThreshold(), isRoot);
42+
} else {
43+
return parentThreshold;
44+
}
45+
}
46+
47+
@Override
48+
public String getDescription() {
49+
return description;
50+
}
51+
}

0 commit comments

Comments
 (0)