diff --git a/CHANGELOG.md b/CHANGELOG.md index d902e9a99f..0e9db2e82d 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ - A `sentry-trace` header that only contains trace ID and span ID but no sampled flag (`-1`, `-0` suffix) means the receiving system can make its own sampling decision - When generating `sentry-trace` header from `PropagationContext` we now copy the `sampled` flag. - In `TransactionContext.fromPropagationContext` when there is no parent sampling decision, keep the decision `null` so a new sampling decision is made instead of defaulting to `false` +- Defer sampling decision by setting `sampled` to `null` in `PropagationContext` when using OpenTelemetry in case of an incoming defer sampling `sentry-trace` header. ([#3945](https://github.com/getsentry/sentry-java/pull/3945)) ## 8.0.0-rc.1 diff --git a/sentry-opentelemetry/sentry-opentelemetry-core/api/sentry-opentelemetry-core.api b/sentry-opentelemetry/sentry-opentelemetry-core/api/sentry-opentelemetry-core.api index 60e2010e6c..fd2099a730 100644 --- a/sentry-opentelemetry/sentry-opentelemetry-core/api/sentry-opentelemetry-core.api +++ b/sentry-opentelemetry/sentry-opentelemetry-core/api/sentry-opentelemetry-core.api @@ -12,7 +12,6 @@ public final class io/sentry/opentelemetry/OtelInternalSpanDetectionUtil { public final class io/sentry/opentelemetry/OtelSamplingUtil { public fun ()V public static fun extractSamplingDecision (Lio/opentelemetry/api/common/Attributes;)Lio/sentry/TracesSamplingDecision; - public static fun extractSamplingDecisionOrDefault (Lio/opentelemetry/api/common/Attributes;)Lio/sentry/TracesSamplingDecision; } public final class io/sentry/opentelemetry/OtelSentryPropagator : io/opentelemetry/context/propagation/TextMapPropagator { diff --git a/sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/OtelSamplingUtil.java b/sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/OtelSamplingUtil.java index 45a8922741..01f414f902 100644 --- a/sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/OtelSamplingUtil.java +++ b/sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/OtelSamplingUtil.java @@ -9,16 +9,6 @@ @ApiStatus.Internal public final class OtelSamplingUtil { - public static @NotNull TracesSamplingDecision extractSamplingDecisionOrDefault( - final @NotNull Attributes attributes) { - final @Nullable TracesSamplingDecision decision = extractSamplingDecision(attributes); - if (decision != null) { - return decision; - } else { - return new TracesSamplingDecision(false); - } - } - public static @Nullable TracesSamplingDecision extractSamplingDecision( final @NotNull Attributes attributes) { final @Nullable Boolean sampled = attributes.get(InternalSemanticAttributes.SAMPLED); diff --git a/sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/OtelSentrySpanProcessor.java b/sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/OtelSentrySpanProcessor.java index 569067a856..27149d821f 100644 --- a/sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/OtelSentrySpanProcessor.java +++ b/sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/OtelSentrySpanProcessor.java @@ -49,9 +49,9 @@ public void onStart(final @NotNull Context parentContext, final @NotNull ReadWri final @Nullable IOtelSpanWrapper sentryParentSpan = spanStorage.getSentrySpan(otelSpan.getParentSpanContext()); - @NotNull + @Nullable TracesSamplingDecision samplingDecision = - OtelSamplingUtil.extractSamplingDecisionOrDefault(otelSpan.toSpanData().getAttributes()); + OtelSamplingUtil.extractSamplingDecision(otelSpan.toSpanData().getAttributes()); @Nullable Baggage baggage = null; @Nullable SpanId sentryParentSpanId = null; otelSpan.setAttribute(IS_REMOTE_PARENT, otelSpan.getParentSpanContext().isRemote()); @@ -81,10 +81,7 @@ public void onStart(final @NotNull Context parentContext, final @NotNull ReadWri } } - final boolean sampled = - samplingDecision != null - ? samplingDecision.getSampled() - : otelSpan.getSpanContext().isSampled(); + final @Nullable Boolean sampled = isSampled(otelSpan, samplingDecision); final @NotNull PropagationContext propagationContext = sentryTraceHeader == null @@ -111,6 +108,21 @@ public void onStart(final @NotNull Context parentContext, final @NotNull ReadWri spanStorage.storeSentrySpan(spanContext, sentrySpan); } + private @Nullable Boolean isSampled( + final @NotNull ReadWriteSpan otelSpan, + final @Nullable TracesSamplingDecision samplingDecision) { + if (samplingDecision != null) { + return samplingDecision.getSampled(); + } + + if (otelSpan.getSpanContext().isSampled()) { + return true; + } + + // tracing without performance + return null; + } + private static void updatePropagationContext( IScopes scopes, PropagationContext propagationContext) { scopes.configureScope(