Skip to content

Commit 80eda8c

Browse files
Update sampleRate in DSC (#4158)
* wip * wip2 * wip3 * format + api * cleanup * revert change to demo * make baggage final again * remove ObjectToString suppressing * remove outdated comment * remove getPropagationContext from Scopes again * remove noop baggage and propagation context again * fix outbox sender; test; cleanup api file * Update sampleRate in DSC * wip * wip2 * wip3 * format + api * cleanup * revert change to demo * make baggage final again * remove ObjectToString suppressing * remove outdated comment * remove getPropagationContext from Scopes again * remove noop baggage and propagation context again * fix outbox sender; test; cleanup api file * review changes * Format code * changelog * fix build --------- Co-authored-by: Sentry Github Bot <bot+github-bot@sentry.io>
1 parent dc85168 commit 80eda8c

File tree

7 files changed

+115
-3
lines changed

7 files changed

+115
-3
lines changed

CHANGELOG.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
- (Internal) Add API to filter native debug images based on stacktrace addresses ([#4089](https://github.com/getsentry/sentry-java/pull/4089))
1616
- Propagate sampling random value ([#4153](https://github.com/getsentry/sentry-java/pull/4153))
1717
- The random value used for sampling traces is now sent to Sentry and attached to the `baggage` header on outgoing requests
18+
- Update `sampleRate` that is sent to Sentry and attached to the `baggage` header on outgoing requests ([#4158](https://github.com/getsentry/sentry-java/pull/4158))
19+
- If the SDK uses its `sampleRate` or `tracesSampler` callback, it now updates the `sampleRate` in Dynamic Sampling Context.
1820

1921
### Fixes
2022

sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/OtelSentrySpanProcessor.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -83,6 +83,7 @@ public void onStart(final @NotNull Context parentContext, final @NotNull ReadWri
8383
new SentryId(traceId), sentrySpanId, sentryParentSpanId, baggage, sampled);
8484

8585
baggage = propagationContext.getBaggage();
86+
baggage.setValuesFromSamplingDecision(samplingDecision);
8687

8788
updatePropagationContext(scopes, propagationContext);
8889
}

sentry/api/sentry.api

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,7 @@ public final class io/sentry/Baggage {
3333
public fun <init> (Lio/sentry/Baggage;)V
3434
public fun <init> (Lio/sentry/ILogger;)V
3535
public fun <init> (Ljava/util/Map;Ljava/lang/String;ZZLio/sentry/ILogger;)V
36+
public fun forceSetSampleRate (Ljava/lang/String;)V
3637
public fun freeze ()V
3738
public static fun fromEvent (Lio/sentry/SentryEvent;Lio/sentry/SentryOptions;)Lio/sentry/Baggage;
3839
public static fun fromHeader (Ljava/lang/String;)Lio/sentry/Baggage;
@@ -70,6 +71,7 @@ public final class io/sentry/Baggage {
7071
public fun setTraceId (Ljava/lang/String;)V
7172
public fun setTransaction (Ljava/lang/String;)V
7273
public fun setUserId (Ljava/lang/String;)V
74+
public fun setValuesFromSamplingDecision (Lio/sentry/TracesSamplingDecision;)V
7375
public fun setValuesFromScope (Lio/sentry/IScope;Lio/sentry/SentryOptions;)V
7476
public fun setValuesFromTransaction (Lio/sentry/protocol/SentryId;Lio/sentry/protocol/SentryId;Lio/sentry/SentryOptions;Lio/sentry/TracesSamplingDecision;Ljava/lang/String;Lio/sentry/protocol/TransactionNameSource;)V
7577
public fun toHeaderString (Ljava/lang/String;)Ljava/lang/String;

sentry/src/main/java/io/sentry/Baggage.java

Lines changed: 44 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -367,6 +367,11 @@ public void setSampleRate(final @Nullable String sampleRate) {
367367
set(DSCKeys.SAMPLE_RATE, sampleRate);
368368
}
369369

370+
@ApiStatus.Internal
371+
public void forceSetSampleRate(final @Nullable String sampleRate) {
372+
set(DSCKeys.SAMPLE_RATE, sampleRate, true);
373+
}
374+
370375
@ApiStatus.Internal
371376
public @Nullable String getSampleRand() {
372377
return get(DSCKeys.SAMPLE_RAND);
@@ -399,7 +404,18 @@ public void setReplayId(final @Nullable String replayId) {
399404

400405
@ApiStatus.Internal
401406
public void set(final @NotNull String key, final @Nullable String value) {
402-
if (mutable) {
407+
set(key, value, false);
408+
}
409+
410+
/**
411+
* Sets / updates a value
412+
*
413+
* @param key key
414+
* @param value value to set
415+
* @param force ignores mutability of this baggage and sets the value anyways
416+
*/
417+
private void set(final @NotNull String key, final @Nullable String value, final boolean force) {
418+
if (mutable || force) {
403419
this.keyValues.put(key, value);
404420
}
405421
}
@@ -439,6 +455,25 @@ public void setValuesFromTransaction(
439455
}
440456
setSampleRate(sampleRateToString(sampleRate(samplingDecision)));
441457
setSampled(StringUtils.toString(sampled(samplingDecision)));
458+
setSampleRand(sampleRateToString(sampleRand(samplingDecision))); // TODO check
459+
}
460+
461+
@ApiStatus.Internal
462+
public void setValuesFromSamplingDecision(
463+
final @Nullable TracesSamplingDecision samplingDecision) {
464+
if (samplingDecision == null) {
465+
return;
466+
}
467+
468+
setSampled(StringUtils.toString(sampled(samplingDecision)));
469+
470+
if (samplingDecision.getSampleRand() != null) {
471+
setSampleRand(sampleRateToString(sampleRand(samplingDecision)));
472+
}
473+
474+
if (samplingDecision.getSampleRate() != null) {
475+
forceSetSampleRate(sampleRateToString(sampleRate(samplingDecision)));
476+
}
442477
}
443478

444479
@ApiStatus.Internal
@@ -466,6 +501,14 @@ public void setValuesFromScope(
466501
return samplingDecision.getSampleRate();
467502
}
468503

504+
private static @Nullable Double sampleRand(@Nullable TracesSamplingDecision samplingDecision) {
505+
if (samplingDecision == null) {
506+
return null;
507+
}
508+
509+
return samplingDecision.getSampleRand();
510+
}
511+
469512
private static @Nullable String sampleRateToString(@Nullable Double sampleRateAsDouble) {
470513
if (!SampleRateUtils.isValidTracesSampleRate(sampleRateAsDouble, false)) {
471514
return null;

sentry/src/main/java/io/sentry/SpanContext.java

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -91,10 +91,10 @@ public SpanContext(
9191
this.spanId = Objects.requireNonNull(spanId, "spanId is required");
9292
this.op = Objects.requireNonNull(operation, "operation is required");
9393
this.parentSpanId = parentSpanId;
94-
this.samplingDecision = samplingDecision;
9594
this.description = description;
9695
this.status = status;
9796
this.origin = origin;
97+
setSamplingDecision(samplingDecision);
9898
}
9999

100100
/**
@@ -106,7 +106,7 @@ public SpanContext(final @NotNull SpanContext spanContext) {
106106
this.traceId = spanContext.traceId;
107107
this.spanId = spanContext.spanId;
108108
this.parentSpanId = spanContext.parentSpanId;
109-
this.samplingDecision = spanContext.samplingDecision;
109+
setSamplingDecision(spanContext.samplingDecision);
110110
this.op = spanContext.op;
111111
this.description = spanContext.description;
112112
this.status = spanContext.status;
@@ -209,6 +209,9 @@ public void setSampled(final @Nullable Boolean sampled, final @Nullable Boolean
209209
@ApiStatus.Internal
210210
public void setSamplingDecision(final @Nullable TracesSamplingDecision samplingDecision) {
211211
this.samplingDecision = samplingDecision;
212+
if (this.baggage != null) {
213+
this.baggage.setValuesFromSamplingDecision(this.samplingDecision);
214+
}
212215
}
213216

214217
public @Nullable String getOrigin() {

sentry/src/test/java/io/sentry/BaggageTest.kt

Lines changed: 50 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -355,6 +355,18 @@ class BaggageTest {
355355
assertEquals("sentry-trace_id=a,sentry-transaction=sentryTransaction", baggage.toHeaderString(null))
356356
}
357357

358+
@Test
359+
fun `if header contains sentry values baggage is marked as shouldFreeze`() {
360+
val baggage = Baggage.fromHeader("sentry-trace_id=a,sentry-transaction=sentryTransaction", logger)
361+
assertTrue(baggage.isShouldFreeze)
362+
}
363+
364+
@Test
365+
fun `if header does not contain sentry values baggage is not marked as shouldFreeze`() {
366+
val baggage = Baggage.fromHeader("a=b", logger)
367+
assertFalse(baggage.isShouldFreeze)
368+
}
369+
358370
@Test
359371
fun `value may contain = sign`() {
360372
val baggage = Baggage(logger)
@@ -560,6 +572,44 @@ class BaggageTest {
560572
}
561573

562574
@Test
575+
fun `sets values from traces sampling decision`() {
576+
val baggage = Baggage.fromHeader("a=b,c=d")
577+
baggage.setValuesFromSamplingDecision(TracesSamplingDecision(true, 0.021, 0.025))
578+
579+
assertEquals("true", baggage.sampled)
580+
assertEquals("0.021", baggage.sampleRate)
581+
assertEquals("0.025", baggage.sampleRand)
582+
}
583+
584+
@Test
585+
fun `handles null traces sampling decision`() {
586+
val baggage = Baggage.fromHeader("a=b,c=d")
587+
baggage.setValuesFromSamplingDecision(null)
588+
}
589+
590+
@Test
591+
fun `sets values from traces sampling decision only if non null`() {
592+
val baggage = Baggage.fromHeader("a=b,c=d")
593+
baggage.setValuesFromSamplingDecision(TracesSamplingDecision(true, 0.021, 0.025))
594+
baggage.setValuesFromSamplingDecision(TracesSamplingDecision(false, null, null))
595+
596+
assertEquals("false", baggage.sampled)
597+
assertEquals("0.021", baggage.sampleRate)
598+
assertEquals("0.025", baggage.sampleRand)
599+
}
600+
601+
@Test
602+
fun `replaces only sample rate if already frozen`() {
603+
val baggage = Baggage.fromHeader("a=b,c=d")
604+
baggage.setValuesFromSamplingDecision(TracesSamplingDecision(true, 0.021, 0.025))
605+
baggage.freeze()
606+
baggage.setValuesFromSamplingDecision(TracesSamplingDecision(false, 0.121, 0.125))
607+
608+
assertEquals("true", baggage.sampled)
609+
assertEquals("0.121", baggage.sampleRate)
610+
assertEquals("0.025", baggage.sampleRand)
611+
}
612+
563613
fun `sample rate can be retrieved as double`() {
564614
val baggage = Baggage.fromHeader("a=b,c=d")
565615
baggage.sampleRate = "0.1"

sentry/src/test/java/io/sentry/SpanContextTest.kt

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,4 +19,15 @@ class SpanContextTest {
1919
trace.setTag("tagName", "tagValue")
2020
assertEquals("tagValue", trace.tags["tagName"])
2121
}
22+
23+
@Test
24+
fun `updates sampling decision on baggage`() {
25+
val trace = SpanContext("op")
26+
trace.baggage = Baggage.fromHeader("a=b")
27+
trace.samplingDecision = TracesSamplingDecision(true, 0.1, 0.2)
28+
29+
assertEquals("true", trace.baggage?.sampled)
30+
assertEquals("0.1", trace.baggage?.sampleRate)
31+
assertEquals("0.2", trace.baggage?.sampleRand)
32+
}
2233
}

0 commit comments

Comments
 (0)