Skip to content

Commit 408f2d8

Browse files
authored
Add incubator ComposableAnnotatingSampler (#7804)
1 parent 578f82b commit 408f2d8

File tree

3 files changed

+141
-0
lines changed

3 files changed

+141
-0
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,48 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.sdk.extension.incubator.trace.samplers;
7+
8+
import io.opentelemetry.api.common.Attributes;
9+
import io.opentelemetry.api.trace.SpanKind;
10+
import io.opentelemetry.context.Context;
11+
import io.opentelemetry.sdk.trace.data.LinkData;
12+
import java.util.List;
13+
14+
final class ComposableAnnotatingSampler implements ComposableSampler {
15+
private final ComposableSampler delegate;
16+
private final Attributes attributes;
17+
private final String description;
18+
19+
ComposableAnnotatingSampler(ComposableSampler delegate, Attributes attributes) {
20+
this.delegate = delegate;
21+
this.attributes = attributes;
22+
23+
this.description =
24+
"ComposableAnnotatingSampler{" + delegate.getDescription() + "," + attributes + "}";
25+
}
26+
27+
@Override
28+
public SamplingIntent getSamplingIntent(
29+
Context parentContext,
30+
String traceId,
31+
String name,
32+
SpanKind spanKind,
33+
Attributes attributes,
34+
List<LinkData> parentLinks) {
35+
SamplingIntent intent =
36+
delegate.getSamplingIntent(parentContext, traceId, name, spanKind, attributes, parentLinks);
37+
return SamplingIntent.create(
38+
intent.getThreshold(),
39+
intent.isThresholdReliable(),
40+
intent.getAttributes().toBuilder().putAll(this.attributes).build(),
41+
intent.getTraceStateUpdater());
42+
}
43+
44+
@Override
45+
public String getDescription() {
46+
return description;
47+
}
48+
}

sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/trace/samplers/ComposableSampler.java

Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -45,6 +45,14 @@ static ComposableRuleBasedSamplerBuilder ruleBasedBuilder() {
4545
return new ComposableRuleBasedSamplerBuilder();
4646
}
4747

48+
/**
49+
* Returns a {@link ComposableSampler} that adds the given {@link Attributes} to all sampled
50+
* spans.
51+
*/
52+
static ComposableSampler annotating(ComposableSampler sampler, Attributes attributes) {
53+
return new ComposableAnnotatingSampler(sampler, attributes);
54+
}
55+
4856
/** Returns the {@link SamplingIntent} to use to make a sampling decision. */
4957
SamplingIntent getSamplingIntent(
5058
Context parentContext,
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
/*
2+
* Copyright The OpenTelemetry Authors
3+
* SPDX-License-Identifier: Apache-2.0
4+
*/
5+
6+
package io.opentelemetry.sdk.extension.incubator.trace.samplers;
7+
8+
import static org.assertj.core.api.Assertions.assertThat;
9+
10+
import io.opentelemetry.api.common.AttributeKey;
11+
import io.opentelemetry.api.common.Attributes;
12+
import io.opentelemetry.api.trace.SpanKind;
13+
import io.opentelemetry.api.trace.TraceId;
14+
import io.opentelemetry.context.Context;
15+
import java.util.Collections;
16+
import org.junit.jupiter.api.Test;
17+
18+
class ComposableAnnotatingSamplerTest {
19+
20+
private static final Attributes ATTRIBUTES =
21+
Attributes.of(
22+
AttributeKey.stringKey("http.route"), "/bear", AttributeKey.longKey("size"), 100L);
23+
24+
@Test
25+
void testDescription() {
26+
assertThat(
27+
ComposableSampler.annotating(ComposableSampler.alwaysOn(), Attributes.empty())
28+
.getDescription())
29+
.isEqualTo("ComposableAnnotatingSampler{ComposableAlwaysOnSampler,{}}");
30+
assertThat(
31+
ComposableSampler.annotating(ComposableSampler.alwaysOn(), ATTRIBUTES).getDescription())
32+
.isEqualTo(
33+
"ComposableAnnotatingSampler{ComposableAlwaysOnSampler,{http.route=\"/bear\", size=100}}");
34+
}
35+
36+
@Test
37+
void setsAttributes() {
38+
SamplingIntent intent =
39+
ComposableSampler.annotating(ComposableSampler.alwaysOn(), ATTRIBUTES)
40+
.getSamplingIntent(
41+
Context.root(),
42+
TraceId.getInvalid(),
43+
"span",
44+
SpanKind.SERVER,
45+
Attributes.empty(),
46+
Collections.emptyList());
47+
assertThat(intent.getThreshold()).isEqualTo(0);
48+
assertThat(intent.getAttributes()).isEqualTo(ATTRIBUTES);
49+
}
50+
51+
@Test
52+
void mergesAttributes() {
53+
// Easiest way to have a SamplingIntent with attributes is to use annotating sampler itself.
54+
// This effectively creates a "test coverage dependency" where we know it's ok since we verify
55+
// the base case in setsAttributes().
56+
ComposableSampler baseSampler =
57+
ComposableSampler.annotating(
58+
ComposableSampler.alwaysOn(),
59+
Attributes.of(
60+
AttributeKey.stringKey("http.route"),
61+
"/cat",
62+
AttributeKey.stringKey("type"),
63+
"mammal"));
64+
65+
SamplingIntent intent =
66+
ComposableSampler.annotating(baseSampler, ATTRIBUTES)
67+
.getSamplingIntent(
68+
Context.root(),
69+
TraceId.getInvalid(),
70+
"span",
71+
SpanKind.SERVER,
72+
Attributes.empty(),
73+
Collections.emptyList());
74+
assertThat(intent.getThreshold()).isEqualTo(0);
75+
assertThat(intent.getAttributes())
76+
.isEqualTo(
77+
Attributes.of(
78+
AttributeKey.stringKey("http.route"),
79+
"/bear",
80+
AttributeKey.longKey("size"),
81+
100L,
82+
AttributeKey.stringKey("type"),
83+
"mammal"));
84+
}
85+
}

0 commit comments

Comments
 (0)