-
Notifications
You must be signed in to change notification settings - Fork 124
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
sampler and span processor prototype implementations for consistent s…
…ampling (#226) * sampler and exporter implementations for consistent sampling * improved dependencies (in particular, removed dependency on guava) * Update consistent-sampling/src/main/java/io/opentelemetry/contrib/samplers/ConsistentParentBasedSampler.java Co-authored-by: Anuraag Agrawal <[email protected]> * reverted some changes * removed wrong immutable annotation * added javadoc * avoid else statements when returning * factory methods for consistent samplers, avoid exposure of implementations * added javadoc for AND and OR sampler composition * replaced use of synchronized by atomic reference * simplified thread local initialization * removed consistent reservoir sampling * improved comment * removed unnecessary clipping of sampling probability * added javadoc explaining maths of implementation * Update consistent-sampling/src/main/java/io/opentelemetry/contrib/state/OtelTraceState.java Co-authored-by: Joshua MacDonald <[email protected]> * Update consistent-sampling/src/main/java/io/opentelemetry/contrib/state/OtelTraceState.java Co-authored-by: Joshua MacDonald <[email protected]> * Update consistent-sampling/src/main/java/io/opentelemetry/contrib/state/OtelTraceState.java Co-authored-by: Joshua MacDonald <[email protected]> * Update consistent-sampling/src/main/java/io/opentelemetry/contrib/state/OtelTraceState.java Co-authored-by: Joshua MacDonald <[email protected]> * Update consistent-sampling/src/main/java/io/opentelemetry/contrib/samplers/ConsistentComposedAndSampler.java Co-authored-by: Trask Stalnaker <[email protected]> * Update consistent-sampling/src/main/java/io/opentelemetry/contrib/samplers/ConsistentComposedOrSampler.java Co-authored-by: Trask Stalnaker <[email protected]> * Update consistent-sampling/src/main/java/io/opentelemetry/contrib/samplers/ConsistentRateLimitingSampler.java Co-authored-by: Trask Stalnaker <[email protected]> * Update consistent-sampling/src/main/java/io/opentelemetry/contrib/samplers/ConsistentParentBasedSampler.java Co-authored-by: Trask Stalnaker <[email protected]> * Update consistent-sampling/src/main/java/io/opentelemetry/contrib/samplers/ConsistentSampler.java Co-authored-by: Trask Stalnaker <[email protected]> * added component owner for consistent sampling * Update consistent-sampling/src/main/java/io/opentelemetry/contrib/state/OtelTraceState.java Co-authored-by: Trask Stalnaker <[email protected]> * removed nonnull annotation * renamed variable s -> pair * renamed char parameter r -> c * renamed method isLowerCaseNum -> isDigit * use empty list instead of null for otherKeyValuePairs * simplified isValueByte method * Update consistent-sampling/src/main/java/io/opentelemetry/contrib/state/OtelTraceState.java Co-authored-by: Trask Stalnaker <[email protected]> * renamed variable sepPos -> separatorPos * replaced 0. and 1. by 0.0 and 1.0 * improved readability as suggested by @trask * removed unused methods from RandomUtil * added javadoc * renamed targetSpansPerNanosLimit -> targetSpansPerNanosecondLimit * throw IllegalArgumentException instead of returning NaN + added comments * renamed tsStartPos -> startPos and eqPos -> colonPos * improved readability of invariant check * added some more test cases * fixed typo * removed unused method * refactored random generator * made OtelTraceState and RandomGenerator package private and moved them to samplers package Co-authored-by: Anuraag Agrawal <[email protected]> Co-authored-by: Joshua MacDonald <[email protected]> Co-authored-by: Trask Stalnaker <[email protected]>
- Loading branch information
1 parent
7ca173b
commit 0b9ab8a
Showing
17 changed files
with
1,782 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,12 @@ | ||
plugins { | ||
id("otel.java-conventions") | ||
id("otel.publish-conventions") | ||
} | ||
|
||
description = "Sampler and exporter implementations for consistent sampling" | ||
|
||
dependencies { | ||
api("io.opentelemetry:opentelemetry-sdk-trace") | ||
testImplementation("org.hipparchus:hipparchus-core:2.0") | ||
testImplementation("org.hipparchus:hipparchus-stat:2.0") | ||
} |
30 changes: 30 additions & 0 deletions
30
...-sampling/src/main/java/io/opentelemetry/contrib/samplers/ConsistentAlwaysOffSampler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
/* | ||
* Copyright The OpenTelemetry Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package io.opentelemetry.contrib.samplers; | ||
|
||
import javax.annotation.concurrent.Immutable; | ||
|
||
@Immutable | ||
final class ConsistentAlwaysOffSampler extends ConsistentSampler { | ||
|
||
private ConsistentAlwaysOffSampler() {} | ||
|
||
private static final ConsistentSampler INSTANCE = new ConsistentAlwaysOffSampler(); | ||
|
||
static ConsistentSampler getInstance() { | ||
return INSTANCE; | ||
} | ||
|
||
@Override | ||
protected int getP(int parentP, boolean isRoot) { | ||
return OtelTraceState.getMaxP(); | ||
} | ||
|
||
@Override | ||
public String getDescription() { | ||
return "ConsistentAlwaysOffSampler"; | ||
} | ||
} |
30 changes: 30 additions & 0 deletions
30
...t-sampling/src/main/java/io/opentelemetry/contrib/samplers/ConsistentAlwaysOnSampler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,30 @@ | ||
/* | ||
* Copyright The OpenTelemetry Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package io.opentelemetry.contrib.samplers; | ||
|
||
import javax.annotation.concurrent.Immutable; | ||
|
||
@Immutable | ||
final class ConsistentAlwaysOnSampler extends ConsistentSampler { | ||
|
||
private ConsistentAlwaysOnSampler() {} | ||
|
||
private static final ConsistentSampler INSTANCE = new ConsistentAlwaysOnSampler(); | ||
|
||
static ConsistentSampler getInstance() { | ||
return INSTANCE; | ||
} | ||
|
||
@Override | ||
protected int getP(int parentP, boolean isRoot) { | ||
return 0; | ||
} | ||
|
||
@Override | ||
public String getDescription() { | ||
return "ConsistentAlwaysOnSampler"; | ||
} | ||
} |
51 changes: 51 additions & 0 deletions
51
...ampling/src/main/java/io/opentelemetry/contrib/samplers/ConsistentComposedAndSampler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,51 @@ | ||
/* | ||
* Copyright The OpenTelemetry Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package io.opentelemetry.contrib.samplers; | ||
|
||
import static java.util.Objects.requireNonNull; | ||
|
||
import javax.annotation.concurrent.Immutable; | ||
|
||
/** | ||
* A consistent sampler composed of two consistent samplers. | ||
* | ||
* <p>This sampler samples if both samplers would sample. | ||
*/ | ||
@Immutable | ||
final class ConsistentComposedAndSampler extends ConsistentSampler { | ||
|
||
private final ConsistentSampler sampler1; | ||
private final ConsistentSampler sampler2; | ||
private final String description; | ||
|
||
ConsistentComposedAndSampler(ConsistentSampler sampler1, ConsistentSampler sampler2) { | ||
this.sampler1 = requireNonNull(sampler1); | ||
this.sampler2 = requireNonNull(sampler2); | ||
this.description = | ||
"ConsistentComposedAndSampler{" | ||
+ "sampler1=" | ||
+ sampler1.getDescription() | ||
+ ",sampler2=" | ||
+ sampler2.getDescription() | ||
+ '}'; | ||
} | ||
|
||
@Override | ||
protected int getP(int parentP, boolean isRoot) { | ||
int p1 = sampler1.getP(parentP, isRoot); | ||
int p2 = sampler2.getP(parentP, isRoot); | ||
if (OtelTraceState.isValidP(p1) && OtelTraceState.isValidP(p2)) { | ||
return Math.max(p1, p2); | ||
} else { | ||
return OtelTraceState.getInvalidP(); | ||
} | ||
} | ||
|
||
@Override | ||
public String getDescription() { | ||
return description; | ||
} | ||
} |
57 changes: 57 additions & 0 deletions
57
...sampling/src/main/java/io/opentelemetry/contrib/samplers/ConsistentComposedOrSampler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
/* | ||
* Copyright The OpenTelemetry Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package io.opentelemetry.contrib.samplers; | ||
|
||
import static java.util.Objects.requireNonNull; | ||
|
||
import javax.annotation.concurrent.Immutable; | ||
|
||
/** | ||
* A consistent sampler composed of two consistent samplers. | ||
* | ||
* <p>This sampler samples if any of the two samplers would sample. | ||
*/ | ||
@Immutable | ||
final class ConsistentComposedOrSampler extends ConsistentSampler { | ||
|
||
private final ConsistentSampler sampler1; | ||
private final ConsistentSampler sampler2; | ||
private final String description; | ||
|
||
ConsistentComposedOrSampler(ConsistentSampler sampler1, ConsistentSampler sampler2) { | ||
this.sampler1 = requireNonNull(sampler1); | ||
this.sampler2 = requireNonNull(sampler2); | ||
this.description = | ||
"ConsistentComposedOrSampler{" | ||
+ "sampler1=" | ||
+ sampler1.getDescription() | ||
+ ",sampler2=" | ||
+ sampler2.getDescription() | ||
+ '}'; | ||
} | ||
|
||
@Override | ||
protected int getP(int parentP, boolean isRoot) { | ||
int p1 = sampler1.getP(parentP, isRoot); | ||
int p2 = sampler2.getP(parentP, isRoot); | ||
if (OtelTraceState.isValidP(p1)) { | ||
if (OtelTraceState.isValidP(p2)) { | ||
return Math.min(p1, p2); | ||
} | ||
return p1; | ||
} else { | ||
if (OtelTraceState.isValidP(p2)) { | ||
return p2; | ||
} | ||
return OtelTraceState.getInvalidP(); | ||
} | ||
} | ||
|
||
@Override | ||
public String getDescription() { | ||
return description; | ||
} | ||
} |
61 changes: 61 additions & 0 deletions
61
...ampling/src/main/java/io/opentelemetry/contrib/samplers/ConsistentParentBasedSampler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,61 @@ | ||
/* | ||
* Copyright The OpenTelemetry Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package io.opentelemetry.contrib.samplers; | ||
|
||
import static java.util.Objects.requireNonNull; | ||
|
||
import javax.annotation.concurrent.Immutable; | ||
|
||
/** | ||
* A consistent sampler that makes the same sampling decision as the parent and optionally falls | ||
* back to an alternative consistent sampler, if the parent p-value is invalid (like for root | ||
* spans). | ||
*/ | ||
@Immutable | ||
final class ConsistentParentBasedSampler extends ConsistentSampler { | ||
|
||
private final ConsistentSampler rootSampler; | ||
|
||
private final String description; | ||
|
||
/** | ||
* Constructs a new consistent parent based sampler using the given root sampler. | ||
* | ||
* @param rootSampler the root sampler | ||
*/ | ||
ConsistentParentBasedSampler(ConsistentSampler rootSampler) { | ||
this(rootSampler, RandomGenerator.getDefault()); | ||
} | ||
|
||
/** | ||
* Constructs a new consistent parent based sampler using the given root sampler and the given | ||
* thread-safe random generator. | ||
* | ||
* @param rootSampler the root sampler | ||
* @param threadSafeRandomGenerator a thread-safe random generator | ||
*/ | ||
ConsistentParentBasedSampler( | ||
ConsistentSampler rootSampler, RandomGenerator threadSafeRandomGenerator) { | ||
super(threadSafeRandomGenerator); | ||
this.rootSampler = requireNonNull(rootSampler); | ||
this.description = | ||
"ConsistentParentBasedSampler{rootSampler=" + rootSampler.getDescription() + '}'; | ||
} | ||
|
||
@Override | ||
protected int getP(int parentP, boolean isRoot) { | ||
if (isRoot) { | ||
return rootSampler.getP(parentP, isRoot); | ||
} else { | ||
return parentP; | ||
} | ||
} | ||
|
||
@Override | ||
public String getDescription() { | ||
return description; | ||
} | ||
} |
69 changes: 69 additions & 0 deletions
69
...ng/src/main/java/io/opentelemetry/contrib/samplers/ConsistentProbabilityBasedSampler.java
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,69 @@ | ||
/* | ||
* Copyright The OpenTelemetry Authors | ||
* SPDX-License-Identifier: Apache-2.0 | ||
*/ | ||
|
||
package io.opentelemetry.contrib.samplers; | ||
|
||
import javax.annotation.concurrent.Immutable; | ||
|
||
/** A consistent sampler that samples with a fixed probability. */ | ||
@Immutable | ||
final class ConsistentProbabilityBasedSampler extends ConsistentSampler { | ||
|
||
private final int lowerPValue; | ||
private final int upperPValue; | ||
private final double probabilityToUseLowerPValue; | ||
private final String description; | ||
|
||
/** | ||
* Constructor. | ||
* | ||
* @param samplingProbability the sampling probability | ||
*/ | ||
ConsistentProbabilityBasedSampler(double samplingProbability) { | ||
this(samplingProbability, RandomGenerator.getDefault()); | ||
} | ||
|
||
/** | ||
* Constructor. | ||
* | ||
* @param samplingProbability the sampling probability | ||
* @param randomGenerator a random generator | ||
*/ | ||
ConsistentProbabilityBasedSampler(double samplingProbability, RandomGenerator randomGenerator) { | ||
super(randomGenerator); | ||
if (samplingProbability < 0.0 || samplingProbability > 1.0) { | ||
throw new IllegalArgumentException("Sampling probability must be in range [0.0, 1.0]!"); | ||
} | ||
this.description = | ||
String.format("ConsistentProbabilityBasedSampler{%.6f}", samplingProbability); | ||
|
||
lowerPValue = getLowerBoundP(samplingProbability); | ||
upperPValue = getUpperBoundP(samplingProbability); | ||
|
||
if (lowerPValue == upperPValue) { | ||
probabilityToUseLowerPValue = 1; | ||
} else { | ||
double upperSamplingProbability = getSamplingProbability(lowerPValue); | ||
double lowerSamplingProbability = getSamplingProbability(upperPValue); | ||
probabilityToUseLowerPValue = | ||
(samplingProbability - lowerSamplingProbability) | ||
/ (upperSamplingProbability - lowerSamplingProbability); | ||
} | ||
} | ||
|
||
@Override | ||
protected int getP(int parentP, boolean isRoot) { | ||
if (randomGenerator.nextBoolean(probabilityToUseLowerPValue)) { | ||
return lowerPValue; | ||
} else { | ||
return upperPValue; | ||
} | ||
} | ||
|
||
@Override | ||
public String getDescription() { | ||
return description; | ||
} | ||
} |
Oops, something went wrong.