Skip to content

Commit 8d5794a

Browse files
author
Anuraag Agrawal
authored
First try rate limited sampler for initialSampler of XRay remote sampler. (#68)
1 parent 9b9514e commit 8d5794a

File tree

4 files changed

+114
-3
lines changed

4 files changed

+114
-3
lines changed

aws-xray/src/main/java/io/opentelemetry/contrib/awsxray/AwsXrayRemoteSamplerBuilder.java

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import io.opentelemetry.sdk.trace.samplers.Sampler;
1212
import java.time.Duration;
1313
import java.util.concurrent.TimeUnit;
14+
import org.checkerframework.checker.nullness.qual.Nullable;
1415

1516
/** A builder for {@link AwsXrayRemoteSampler}. */
1617
public final class AwsXrayRemoteSamplerBuilder {
@@ -22,7 +23,7 @@ public final class AwsXrayRemoteSamplerBuilder {
2223

2324
private Clock clock = Clock.getDefault();
2425
private String endpoint = DEFAULT_ENDPOINT;
25-
private Sampler initialSampler = Sampler.parentBased(Sampler.traceIdRatioBased(0.05));
26+
@Nullable private Sampler initialSampler;
2627
private long pollingIntervalNanos = TimeUnit.SECONDS.toNanos(DEFAULT_POLLING_INTERVAL_SECS);
2728

2829
AwsXrayRemoteSamplerBuilder(Resource resource) {
@@ -84,6 +85,13 @@ public AwsXrayRemoteSamplerBuilder setClock(Clock clock) {
8485

8586
/** Returns a {@link AwsXrayRemoteSampler} with the configuration of this builder. */
8687
public AwsXrayRemoteSampler build() {
88+
Sampler initialSampler = this.initialSampler;
89+
if (initialSampler == null) {
90+
initialSampler =
91+
Sampler.parentBased(
92+
new OrElseSampler(
93+
new RateLimitingSampler(1, clock), Sampler.traceIdRatioBased(0.05)));
94+
}
8795
return new AwsXrayRemoteSampler(
8896
resource, clock, endpoint, initialSampler, pollingIntervalNanos);
8997
}
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+
package io.opentelemetry.contrib.awsxray;
6+
7+
import io.opentelemetry.api.common.Attributes;
8+
import io.opentelemetry.api.trace.SpanKind;
9+
import io.opentelemetry.context.Context;
10+
import io.opentelemetry.sdk.trace.data.LinkData;
11+
import io.opentelemetry.sdk.trace.samplers.Sampler;
12+
import io.opentelemetry.sdk.trace.samplers.SamplingDecision;
13+
import io.opentelemetry.sdk.trace.samplers.SamplingResult;
14+
import java.util.List;
15+
16+
class OrElseSampler implements Sampler {
17+
18+
private final Sampler first;
19+
private final Sampler second;
20+
21+
OrElseSampler(Sampler first, Sampler second) {
22+
this.first = first;
23+
this.second = second;
24+
}
25+
26+
@Override
27+
public SamplingResult shouldSample(
28+
Context parentContext,
29+
String traceId,
30+
String name,
31+
SpanKind spanKind,
32+
Attributes attributes,
33+
List<LinkData> parentLinks) {
34+
SamplingResult result =
35+
first.shouldSample(parentContext, traceId, name, spanKind, attributes, parentLinks);
36+
if (result.getDecision() != SamplingDecision.DROP) {
37+
return result;
38+
}
39+
return second.shouldSample(parentContext, traceId, name, spanKind, attributes, parentLinks);
40+
}
41+
42+
@Override
43+
public String getDescription() {
44+
return "OrElse{"
45+
+ "first:"
46+
+ first.getDescription()
47+
+ ", second:"
48+
+ second.getDescription()
49+
+ "}";
50+
}
51+
}

aws-xray/src/test/java/io/opentelemetry/contrib/awsxray/AwsXrayRemoteSamplerTest.java

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -236,7 +236,12 @@ void getAndUpdate() throws Exception {
236236

237237
@Test
238238
void defaultInitialSampler() {
239-
assertThat(AwsXrayRemoteSampler.newBuilder(Resource.empty()).build().getDescription())
240-
.startsWith("AwsXrayRemoteSampler{ParentBased{root:TraceIdRatioBased{0.050000}");
239+
try (AwsXrayRemoteSampler sampler = AwsXrayRemoteSampler.newBuilder(Resource.empty()).build()) {
240+
assertThat(sampler.getDescription())
241+
.startsWith(
242+
"AwsXrayRemoteSampler{"
243+
+ "ParentBased{root:OrElse{"
244+
+ "first:RateLimitingSampler{1}, second:TraceIdRatioBased{0.050000}");
245+
}
241246
}
242247
}
Lines changed: 47 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,47 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
package io.opentelemetry.contrib.awsxray;
6+
7+
import static org.assertj.core.api.Assertions.assertThat;
8+
9+
import io.opentelemetry.api.common.Attributes;
10+
import io.opentelemetry.api.trace.SpanKind;
11+
import io.opentelemetry.api.trace.TraceId;
12+
import io.opentelemetry.context.Context;
13+
import io.opentelemetry.sdk.trace.samplers.Sampler;
14+
import io.opentelemetry.sdk.trace.samplers.SamplingDecision;
15+
import io.opentelemetry.sdk.trace.samplers.SamplingResult;
16+
import java.util.Collections;
17+
import org.junit.jupiter.api.Test;
18+
import org.junit.jupiter.api.extension.ExtendWith;
19+
import org.mockito.junit.jupiter.MockitoExtension;
20+
21+
@ExtendWith(MockitoExtension.class)
22+
class OrElseSamplerTest {
23+
24+
@Test
25+
void firstWins() {
26+
Sampler sampler = new OrElseSampler(Sampler.alwaysOn(), Sampler.alwaysOff());
27+
assertThat(doSample(sampler).getDecision()).isEqualTo(SamplingDecision.RECORD_AND_SAMPLE);
28+
}
29+
30+
@Test
31+
void fallsBackToSecond() {
32+
Sampler sampler = new OrElseSampler(Sampler.alwaysOff(), Sampler.alwaysOn());
33+
assertThat(doSample(sampler).getDecision()).isEqualTo(SamplingDecision.RECORD_AND_SAMPLE);
34+
sampler = new OrElseSampler(Sampler.alwaysOff(), Sampler.alwaysOff());
35+
assertThat(doSample(sampler).getDecision()).isEqualTo(SamplingDecision.DROP);
36+
}
37+
38+
private SamplingResult doSample(Sampler sampler) {
39+
return sampler.shouldSample(
40+
Context.current(),
41+
TraceId.fromLongs(1, 2),
42+
"span",
43+
SpanKind.CLIENT,
44+
Attributes.empty(),
45+
Collections.emptyList());
46+
}
47+
}

0 commit comments

Comments
 (0)