Skip to content

Commit d62849c

Browse files
Add adaptive sampling local config attribute to spans (#1299)
### Notes Adding a way for users to tell which of their services has appropriately ingested and set their local configuration YAML for adaptive sampling. ### Testing Unit tests + manual E2E test showing spans have the added attribute and all other adaptive sampling behaviour is unaffected By submitting this pull request, I confirm that my contribution is made under the terms of the Apache 2.0 license. Co-authored-by: Lei Wang <66336933+wangzlei@users.noreply.github.com>
1 parent 85792de commit d62849c

2 files changed

Lines changed: 221 additions & 8 deletions

File tree

.github/patches/opentelemetry-java-contrib.patch

Lines changed: 219 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -26,10 +26,29 @@ index bfb2eee6..d9adedfe 100644
2626
statistics.stream().map(SamplingStatisticsDocument::getRuleName).collect(toSet());
2727

2828
diff --git a/aws-xray/src/main/java/io/opentelemetry/contrib/awsxray/XrayRulesSampler.java b/aws-xray/src/main/java/io/opentelemetry/contrib/awsxray/XrayRulesSampler.java
29-
index f2ab7c2d..f0448176 100644
29+
index f2ab7c2d..42b7328c 100644
3030
--- a/aws-xray/src/main/java/io/opentelemetry/contrib/awsxray/XrayRulesSampler.java
3131
+++ b/aws-xray/src/main/java/io/opentelemetry/contrib/awsxray/XrayRulesSampler.java
32-
@@ -263,7 +263,7 @@ final class XrayRulesSampler implements Sampler {
32+
@@ -50,6 +50,8 @@ final class XrayRulesSampler implements Sampler {
33+
34+
public static final AttributeKey<String> AWS_XRAY_SAMPLING_RULE =
35+
AttributeKey.stringKey("aws.xray.sampling_rule");
36+
+ public static final AttributeKey<Boolean> AWS_XRAY_ADAPTIVE_SAMPLING_CONFIGURED =
37+
+ AttributeKey.booleanKey("aws.xray.adaptive_sampling_configured");
38+
39+
// Used for generating operation
40+
private static final String UNKNOWN_OPERATION = "UnknownOperation";
41+
@@ -183,6 +185,9 @@ final class XrayRulesSampler implements Sampler {
42+
.put(
43+
AWS_XRAY_SAMPLING_RULE.getKey(),
44+
ruleToPropagate != null ? ruleToPropagate : "UNKNOWN")
45+
+ .put(
46+
+ AWS_XRAY_ADAPTIVE_SAMPLING_CONFIGURED.getKey(),
47+
+ this.adaptiveSamplingConfig != null)
48+
.build(),
49+
hashedRule);
50+
}
51+
@@ -263,7 +268,7 @@ final class XrayRulesSampler implements Sampler {
3352
ruleToReportTo = applier;
3453
break;
3554
}
@@ -38,7 +57,7 @@ index f2ab7c2d..f0448176 100644
3857
matchedRule = applier;
3958
}
4059
}
41-
@@ -323,14 +323,8 @@ final class XrayRulesSampler implements Sampler {
60+
@@ -323,14 +328,8 @@ final class XrayRulesSampler implements Sampler {
4261
if (target != null) {
4362
return rule.withTarget(target, now, currentNanoTime);
4463
}
@@ -131,10 +150,202 @@ index 7a75f377..8ce009c0 100644
131150
void defaultInitialSampler() {
132151
try (AwsXrayRemoteSampler sampler = AwsXrayRemoteSampler.newBuilder(Resource.empty()).build()) {
133152
diff --git a/aws-xray/src/test/java/io/opentelemetry/contrib/awsxray/XrayRulesSamplerTest.java b/aws-xray/src/test/java/io/opentelemetry/contrib/awsxray/XrayRulesSamplerTest.java
134-
index c8a8dead..be314c1c 100644
153+
index c8a8dead..a27b3fe1 100644
135154
--- a/aws-xray/src/test/java/io/opentelemetry/contrib/awsxray/XrayRulesSamplerTest.java
136155
+++ b/aws-xray/src/test/java/io/opentelemetry/contrib/awsxray/XrayRulesSamplerTest.java
137-
@@ -571,11 +571,27 @@ class XrayRulesSamplerTest {
156+
@@ -134,6 +134,7 @@ class XrayRulesSamplerTest {
157+
SamplingDecision.RECORD_AND_SAMPLE,
158+
Attributes.builder()
159+
.put(XrayRulesSampler.AWS_XRAY_SAMPLING_RULE, "cat-rule")
160+
+ .put(XrayRulesSampler.AWS_XRAY_ADAPTIVE_SAMPLING_CONFIGURED, false)
161+
.build(),
162+
XrayRulesSampler.hashRuleName("cat-rule")));
163+
assertThat(doSample(sampler, "cat-service"))
164+
@@ -143,6 +144,7 @@ class XrayRulesSamplerTest {
165+
SamplingDecision.RECORD_AND_SAMPLE,
166+
Attributes.builder()
167+
.put(XrayRulesSampler.AWS_XRAY_SAMPLING_RULE, "cat-rule")
168+
+ .put(XrayRulesSampler.AWS_XRAY_ADAPTIVE_SAMPLING_CONFIGURED, false)
169+
.build(),
170+
XrayRulesSampler.hashRuleName("cat-rule")));
171+
assertThat(doSample(sampler, "dog-service"))
172+
@@ -152,6 +154,7 @@ class XrayRulesSamplerTest {
173+
SamplingDecision.RECORD_AND_SAMPLE,
174+
Attributes.builder()
175+
.put(XrayRulesSampler.AWS_XRAY_SAMPLING_RULE, "dog-rule")
176+
+ .put(XrayRulesSampler.AWS_XRAY_ADAPTIVE_SAMPLING_CONFIGURED, false)
177+
.build(),
178+
XrayRulesSampler.hashRuleName("dog-rule")));
179+
assertThat(doSample(sampler, "dog-service"))
180+
@@ -161,6 +164,7 @@ class XrayRulesSamplerTest {
181+
SamplingDecision.DROP,
182+
Attributes.builder()
183+
.put(XrayRulesSampler.AWS_XRAY_SAMPLING_RULE, "dog-rule")
184+
+ .put(XrayRulesSampler.AWS_XRAY_ADAPTIVE_SAMPLING_CONFIGURED, false)
185+
.build(),
186+
XrayRulesSampler.hashRuleName("dog-rule")));
187+
assertThat(doSample(sampler, "bat-service"))
188+
@@ -170,6 +174,7 @@ class XrayRulesSamplerTest {
189+
SamplingDecision.RECORD_AND_SAMPLE,
190+
Attributes.builder()
191+
.put(XrayRulesSampler.AWS_XRAY_SAMPLING_RULE, "bat-rule")
192+
+ .put(XrayRulesSampler.AWS_XRAY_ADAPTIVE_SAMPLING_CONFIGURED, false)
193+
.build(),
194+
XrayRulesSampler.hashRuleName("bat-rule")));
195+
assertThat(doSample(sampler, "bat-service"))
196+
@@ -179,6 +184,7 @@ class XrayRulesSamplerTest {
197+
SamplingDecision.RECORD_AND_SAMPLE,
198+
Attributes.builder()
199+
.put(XrayRulesSampler.AWS_XRAY_SAMPLING_RULE, "bat-rule")
200+
+ .put(XrayRulesSampler.AWS_XRAY_ADAPTIVE_SAMPLING_CONFIGURED, false)
201+
.build(),
202+
XrayRulesSampler.hashRuleName("bat-rule")));
203+
assertThat(doSample(sampler, "unknown"))
204+
@@ -188,6 +194,7 @@ class XrayRulesSamplerTest {
205+
SamplingDecision.DROP,
206+
Attributes.builder()
207+
.put(XrayRulesSampler.AWS_XRAY_SAMPLING_RULE, "default-rule")
208+
+ .put(XrayRulesSampler.AWS_XRAY_ADAPTIVE_SAMPLING_CONFIGURED, false)
209+
.build(),
210+
XrayRulesSampler.hashRuleName("default-rule")));
211+
212+
@@ -222,6 +229,7 @@ class XrayRulesSamplerTest {
213+
SamplingDecision.RECORD_AND_SAMPLE,
214+
Attributes.builder()
215+
.put(XrayRulesSampler.AWS_XRAY_SAMPLING_RULE, "dog-rule")
216+
+ .put(XrayRulesSampler.AWS_XRAY_ADAPTIVE_SAMPLING_CONFIGURED, false)
217+
.build(),
218+
XrayRulesSampler.hashRuleName("dog-rule")));
219+
assertThat(doSample(sampler, "dog-service"))
220+
@@ -231,6 +239,7 @@ class XrayRulesSamplerTest {
221+
SamplingDecision.DROP,
222+
Attributes.builder()
223+
.put(XrayRulesSampler.AWS_XRAY_SAMPLING_RULE, "dog-rule")
224+
+ .put(XrayRulesSampler.AWS_XRAY_ADAPTIVE_SAMPLING_CONFIGURED, false)
225+
.build(),
226+
XrayRulesSampler.hashRuleName("dog-rule")));
227+
assertThat(doSample(sampler, "unknown"))
228+
@@ -240,6 +249,7 @@ class XrayRulesSamplerTest {
229+
SamplingDecision.DROP,
230+
Attributes.builder()
231+
.put(XrayRulesSampler.AWS_XRAY_SAMPLING_RULE, "default-rule")
232+
+ .put(XrayRulesSampler.AWS_XRAY_ADAPTIVE_SAMPLING_CONFIGURED, false)
233+
.build(),
234+
XrayRulesSampler.hashRuleName("default-rule")));
235+
// Targets overridden to always drop.
236+
@@ -250,6 +260,7 @@ class XrayRulesSamplerTest {
237+
SamplingDecision.DROP,
238+
Attributes.builder()
239+
.put(XrayRulesSampler.AWS_XRAY_SAMPLING_RULE, "cat-rule")
240+
+ .put(XrayRulesSampler.AWS_XRAY_ADAPTIVE_SAMPLING_CONFIGURED, false)
241+
.build(),
242+
XrayRulesSampler.hashRuleName("cat-rule")));
243+
assertThat(doSample(sampler, "bat-service"))
244+
@@ -259,6 +270,7 @@ class XrayRulesSamplerTest {
245+
SamplingDecision.DROP,
246+
Attributes.builder()
247+
.put(XrayRulesSampler.AWS_XRAY_SAMPLING_RULE, "bat-rule")
248+
+ .put(XrayRulesSampler.AWS_XRAY_ADAPTIVE_SAMPLING_CONFIGURED, false)
249+
.build(),
250+
XrayRulesSampler.hashRuleName("bat-rule")));
251+
252+
@@ -367,6 +379,7 @@ class XrayRulesSamplerTest {
253+
SamplingDecision.RECORD_AND_SAMPLE,
254+
Attributes.builder()
255+
.put(XrayRulesSampler.AWS_XRAY_SAMPLING_RULE, "cat-rule")
256+
+ .put(XrayRulesSampler.AWS_XRAY_ADAPTIVE_SAMPLING_CONFIGURED, true)
257+
.build(),
258+
XrayRulesSampler.hashRuleName("cat-rule")));
259+
assertThat(doSample(sampler, "cat-service"))
260+
@@ -376,6 +389,7 @@ class XrayRulesSamplerTest {
261+
SamplingDecision.RECORD_AND_SAMPLE,
262+
Attributes.builder()
263+
.put(XrayRulesSampler.AWS_XRAY_SAMPLING_RULE, "cat-rule")
264+
+ .put(XrayRulesSampler.AWS_XRAY_ADAPTIVE_SAMPLING_CONFIGURED, true)
265+
.build(),
266+
XrayRulesSampler.hashRuleName("cat-rule")));
267+
assertThat(doSample(sampler, "dog-service"))
268+
@@ -385,6 +399,7 @@ class XrayRulesSamplerTest {
269+
SamplingDecision.RECORD_AND_SAMPLE,
270+
Attributes.builder()
271+
.put(XrayRulesSampler.AWS_XRAY_SAMPLING_RULE, "dog-rule")
272+
+ .put(XrayRulesSampler.AWS_XRAY_ADAPTIVE_SAMPLING_CONFIGURED, true)
273+
.build(),
274+
XrayRulesSampler.hashRuleName("dog-rule")));
275+
assertThat(doSample(sampler, "dog-service"))
276+
@@ -394,6 +409,7 @@ class XrayRulesSamplerTest {
277+
SamplingDecision.DROP,
278+
Attributes.builder()
279+
.put(XrayRulesSampler.AWS_XRAY_SAMPLING_RULE, "dog-rule")
280+
+ .put(XrayRulesSampler.AWS_XRAY_ADAPTIVE_SAMPLING_CONFIGURED, true)
281+
.build(),
282+
XrayRulesSampler.hashRuleName("dog-rule")));
283+
assertThat(doSample(sampler, "bat-service"))
284+
@@ -403,6 +419,7 @@ class XrayRulesSamplerTest {
285+
SamplingDecision.RECORD_AND_SAMPLE,
286+
Attributes.builder()
287+
.put(XrayRulesSampler.AWS_XRAY_SAMPLING_RULE, "bat-rule")
288+
+ .put(XrayRulesSampler.AWS_XRAY_ADAPTIVE_SAMPLING_CONFIGURED, true)
289+
.build(),
290+
XrayRulesSampler.hashRuleName("bat-rule")));
291+
assertThat(doSample(sampler, "bat-service"))
292+
@@ -412,6 +429,7 @@ class XrayRulesSamplerTest {
293+
SamplingDecision.RECORD_AND_SAMPLE,
294+
Attributes.builder()
295+
.put(XrayRulesSampler.AWS_XRAY_SAMPLING_RULE, "bat-rule")
296+
+ .put(XrayRulesSampler.AWS_XRAY_ADAPTIVE_SAMPLING_CONFIGURED, true)
297+
.build(),
298+
XrayRulesSampler.hashRuleName("bat-rule")));
299+
assertThat(doSample(sampler, "unknown"))
300+
@@ -421,6 +439,7 @@ class XrayRulesSamplerTest {
301+
SamplingDecision.DROP,
302+
Attributes.builder()
303+
.put(XrayRulesSampler.AWS_XRAY_SAMPLING_RULE, "default-rule")
304+
+ .put(XrayRulesSampler.AWS_XRAY_ADAPTIVE_SAMPLING_CONFIGURED, true)
305+
.build(),
306+
XrayRulesSampler.hashRuleName("default-rule")));
307+
308+
@@ -455,6 +474,7 @@ class XrayRulesSamplerTest {
309+
SamplingDecision.RECORD_AND_SAMPLE,
310+
Attributes.builder()
311+
.put(XrayRulesSampler.AWS_XRAY_SAMPLING_RULE, "dog-rule")
312+
+ .put(XrayRulesSampler.AWS_XRAY_ADAPTIVE_SAMPLING_CONFIGURED, true)
313+
.build(),
314+
XrayRulesSampler.hashRuleName("dog-rule")));
315+
assertThat(doSample(sampler, "dog-service"))
316+
@@ -464,6 +484,7 @@ class XrayRulesSamplerTest {
317+
SamplingDecision.DROP,
318+
Attributes.builder()
319+
.put(XrayRulesSampler.AWS_XRAY_SAMPLING_RULE, "dog-rule")
320+
+ .put(XrayRulesSampler.AWS_XRAY_ADAPTIVE_SAMPLING_CONFIGURED, true)
321+
.build(),
322+
XrayRulesSampler.hashRuleName("dog-rule")));
323+
assertThat(doSample(sampler, "unknown"))
324+
@@ -473,6 +494,7 @@ class XrayRulesSamplerTest {
325+
SamplingDecision.DROP,
326+
Attributes.builder()
327+
.put(XrayRulesSampler.AWS_XRAY_SAMPLING_RULE, "default-rule")
328+
+ .put(XrayRulesSampler.AWS_XRAY_ADAPTIVE_SAMPLING_CONFIGURED, true)
329+
.build(),
330+
XrayRulesSampler.hashRuleName("default-rule")));
331+
// Targets overridden to always drop.
332+
@@ -483,6 +505,7 @@ class XrayRulesSamplerTest {
333+
SamplingDecision.DROP,
334+
Attributes.builder()
335+
.put(XrayRulesSampler.AWS_XRAY_SAMPLING_RULE, "cat-rule")
336+
+ .put(XrayRulesSampler.AWS_XRAY_ADAPTIVE_SAMPLING_CONFIGURED, true)
337+
.build(),
338+
XrayRulesSampler.hashRuleName("cat-rule")));
339+
assertThat(doSample(sampler, "bat-service"))
340+
@@ -492,6 +515,7 @@ class XrayRulesSamplerTest {
341+
SamplingDecision.DROP,
342+
Attributes.builder()
343+
.put(XrayRulesSampler.AWS_XRAY_SAMPLING_RULE, "bat-rule")
344+
+ .put(XrayRulesSampler.AWS_XRAY_ADAPTIVE_SAMPLING_CONFIGURED, true)
345+
.build(),
346+
XrayRulesSampler.hashRuleName("bat-rule")));
347+
348+
@@ -571,11 +595,27 @@ class XrayRulesSamplerTest {
138349
0.0,
139350
"*",
140351
"*",
@@ -164,7 +375,7 @@ index c8a8dead..be314c1c 100644
164375
"*",
165376
"*",
166377
"*",
167-
@@ -603,7 +619,7 @@ class XrayRulesSamplerTest {
378+
@@ -603,7 +643,7 @@ class XrayRulesSamplerTest {
168379
Resource.getDefault(),
169380
clock,
170381
Sampler.alwaysOn(),
@@ -173,7 +384,7 @@ index c8a8dead..be314c1c 100644
173384
config);
174385

175386
Instant now = Instant.ofEpochSecond(0, clock.now());
176-
@@ -640,13 +656,16 @@ class XrayRulesSamplerTest {
387+
@@ -640,13 +680,16 @@ class XrayRulesSamplerTest {
177388
// Rules are ordered by priority, so cat-rule is first
178389
assertThat(snapshot.get(0).getBoostStatisticsDocument().getTotalCount()).isEqualTo(0);
179390
assertThat(snapshot.get(0).getBoostStatisticsDocument().getAnomalyCount()).isEqualTo(0);
@@ -192,7 +403,7 @@ index c8a8dead..be314c1c 100644
192403
// Mock trace coming from upstream service where it was sampled by cat-rule
193404
when(spanDataMock.getTraceId()).thenReturn("TRACE_ID4");
194405
when(readableSpanMock.getSpanContext())
195-
@@ -671,6 +690,9 @@ class XrayRulesSamplerTest {
406+
@@ -671,6 +714,9 @@ class XrayRulesSamplerTest {
196407
assertThat(snapshot.get(1).getBoostStatisticsDocument().getTotalCount()).isEqualTo(0);
197408
assertThat(snapshot.get(1).getBoostStatisticsDocument().getAnomalyCount()).isEqualTo(0);
198409
assertThat(snapshot.get(1).getBoostStatisticsDocument().getSampledAnomalyCount()).isEqualTo(0);

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@ If your change does not need a CHANGELOG entry, add the "skip changelog" label t
1313

1414
## Unreleased
1515

16+
- Add adaptive sampling local config attribute to spans
17+
([#1299](https://github.com/aws-observability/aws-otel-java-instrumentation/pull/1299))
1618
- Optimize GetSamplingTargets calls by removing empty statistics documents
1719
([#1298](https://github.com/aws-observability/aws-otel-java-instrumentation/pull/1298))
1820
- Ugrade to OTel v2.23.0 and Contrib v1.52.0

0 commit comments

Comments
 (0)