Skip to content

Commit

Permalink
consistent sampler prototypes using 56 bits of randomness (#1063)
Browse files Browse the repository at this point in the history
  • Loading branch information
oertl committed Oct 18, 2023
1 parent 27e17fd commit e466431
Show file tree
Hide file tree
Showing 21 changed files with 2,086 additions and 1 deletion.
2 changes: 1 addition & 1 deletion consistent-sampling/build.gradle.kts
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@ plugins {
}

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

dependencies {
api("io.opentelemetry:opentelemetry-sdk-trace")
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,26 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.contrib.sampler.consistent56;

import javax.annotation.concurrent.Immutable;

@Immutable
final class ConsistentAlwaysOffSampler extends ConsistentSampler {

ConsistentAlwaysOffSampler(RandomValueGenerator randomValueGenerator) {
super(randomValueGenerator);
}

@Override
protected long getThreshold(long parentThreshold, boolean isRoot) {
return 0;
}

@Override
public String getDescription() {
return "ConsistentAlwaysOffSampler";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,28 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.contrib.sampler.consistent56;

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

import javax.annotation.concurrent.Immutable;

@Immutable
final class ConsistentAlwaysOnSampler extends ConsistentSampler {

ConsistentAlwaysOnSampler(RandomValueGenerator randomValueGenerator) {
super(randomValueGenerator);
}

@Override
protected long getThreshold(long parentThreshold, boolean isRoot) {
return getMaxThreshold();
}

@Override
public String getDescription() {
return "ConsistentAlwaysOnSampler";
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,56 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.contrib.sampler.consistent56;

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,
RandomValueGenerator randomValueGenerator) {
super(randomValueGenerator);
this.sampler1 = requireNonNull(sampler1);
this.sampler2 = requireNonNull(sampler2);
this.description =
"ConsistentComposedAndSampler{"
+ "sampler1="
+ sampler1.getDescription()
+ ",sampler2="
+ sampler2.getDescription()
+ '}';
}

@Override
protected long getThreshold(long parentThreshold, boolean isRoot) {
long threshold1 = sampler1.getThreshold(parentThreshold, isRoot);
long threshold2 = sampler2.getThreshold(parentThreshold, isRoot);
if (ConsistentSamplingUtil.isValidThreshold(threshold1)
&& ConsistentSamplingUtil.isValidThreshold(threshold2)) {
return Math.min(threshold1, threshold2);
} else {
return ConsistentSamplingUtil.getInvalidThreshold();
}
}

@Override
public String getDescription() {
return description;
}
}
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.sampler.consistent56;

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,
RandomValueGenerator randomValueGenerator) {
super(randomValueGenerator);
this.sampler1 = requireNonNull(sampler1);
this.sampler2 = requireNonNull(sampler2);
this.description =
"ConsistentComposedOrSampler{"
+ "sampler1="
+ sampler1.getDescription()
+ ",sampler2="
+ sampler2.getDescription()
+ '}';
}

@Override
protected long getThreshold(long parentThreshold, boolean isRoot) {
long threshold1 = sampler1.getThreshold(parentThreshold, isRoot);
long threshold2 = sampler2.getThreshold(parentThreshold, isRoot);
if (ConsistentSamplingUtil.isValidThreshold(threshold1)) {
if (ConsistentSamplingUtil.isValidThreshold(threshold2)) {
return Math.max(threshold1, threshold2);
}
return threshold1;
} else {
if (ConsistentSamplingUtil.isValidThreshold(threshold2)) {
return threshold2;
}
return ConsistentSamplingUtil.getInvalidThreshold();
}
}

@Override
public String getDescription() {
return description;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.contrib.sampler.consistent56;

import static io.opentelemetry.contrib.sampler.consistent56.ConsistentSamplingUtil.calculateSamplingProbability;
import static io.opentelemetry.contrib.sampler.consistent56.ConsistentSamplingUtil.checkThreshold;

public class ConsistentFixedThresholdSampler extends ConsistentSampler {

private final long threshold;
private final String description;

protected ConsistentFixedThresholdSampler(
long threshold, RandomValueGenerator randomValueGenerator) {
super(randomValueGenerator);
checkThreshold(threshold);
this.threshold = threshold;

String thresholdString;
if (threshold == ConsistentSamplingUtil.getMaxThreshold()) {
thresholdString = "max";
} else {
thresholdString =
ConsistentSamplingUtil.appendLast56BitHexEncodedWithoutTrailingZeros(
new StringBuilder(), threshold)
.toString();
}

this.description =
"ConsistentFixedThresholdSampler{threshold="
+ thresholdString
+ ", sampling probability="
+ calculateSamplingProbability(threshold)
+ "}";
}

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

@Override
protected long getThreshold(long parentThreshold, boolean isRoot) {
return threshold;
}
}
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.sampler.consistent56;

import static java.util.Objects.requireNonNull;

import javax.annotation.concurrent.Immutable;

/**
* A consistent sampler that makes the same sampling decision as the parent. For root spans the
* sampling decision is delegated to the root sampler.
*/
@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 and the given
* thread-safe random generator.
*
* @param rootSampler the root sampler
* @param randomValueGenerator the function to use for generating the r-value
*/
ConsistentParentBasedSampler(
ConsistentSampler rootSampler, RandomValueGenerator randomValueGenerator) {
super(randomValueGenerator);
this.rootSampler = requireNonNull(rootSampler);
this.description =
"ConsistentParentBasedSampler{rootSampler=" + rootSampler.getDescription() + '}';
}

@Override
protected long getThreshold(long parentThreshold, boolean isRoot) {
if (isRoot) {
return rootSampler.getThreshold(ConsistentSamplingUtil.getInvalidThreshold(), isRoot);
} else {
return parentThreshold;
}
}

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

0 comments on commit e466431

Please sign in to comment.