Skip to content
Merged
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
7 changes: 7 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,13 @@
- `SentryAttribute.stringAttribute()` takes a `String` value
- We opted for handling parameters via `SentryLogParameters` to avoid creating tons of overloads that are ambiguous.

### Fixes

- Isolation scope is now forked in `OtelSentrySpanProcessor` instead of `OtelSentryPropagator` ([#4434](https://github.com/getsentry/sentry-java/pull/4434))
- Since propagator may never be invoked we moved the location where isolation scope is forked.
- Not invoking `OtelSentryPropagator.extract` or having a `sentry-trace` header that failed to parse would cause isolation scope not to be forked.
- This in turn caused data to bleed between scopes, e.g. from one request into another

## 8.12.0

### Features
Expand Down
Original file line number Diff line number Diff line change
@@ -1,7 +1,5 @@
package io.sentry.opentelemetry;

import static io.sentry.opentelemetry.SentryOtelKeys.SENTRY_SCOPES_KEY;

import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.SpanContext;
Expand All @@ -15,7 +13,6 @@
import io.sentry.BaggageHeader;
import io.sentry.IScopes;
import io.sentry.ScopesAdapter;
import io.sentry.Sentry;
import io.sentry.SentryLevel;
import io.sentry.SentryOptions;
import io.sentry.SentryTraceHeader;
Expand Down Expand Up @@ -105,16 +102,10 @@ public <C> void inject(final Context context, final C carrier, final TextMapSett
@Override
public <C> Context extract(
final Context context, final C carrier, final TextMapGetter<C> getter) {
final @Nullable IScopes scopesFromParentContext = context.get(SENTRY_SCOPES_KEY);
final @NotNull IScopes scopesToUse =
scopesFromParentContext != null
? scopesFromParentContext.forkedScopes("propagator")
: Sentry.forkedRootScopes("propagator");

final @Nullable String sentryTraceString =
getter.get(carrier, SentryTraceHeader.SENTRY_TRACE_HEADER);
if (sentryTraceString == null) {
return context.with(SENTRY_SCOPES_KEY, scopesToUse);
return context;
}

try {
Expand All @@ -136,7 +127,6 @@ public <C> Context extract(
final @NotNull Context modifiedContext =
context
.with(wrappedSpan)
.with(SENTRY_SCOPES_KEY, scopesToUse)
.with(SentryOtelKeys.SENTRY_TRACE_KEY, sentryTraceHeader)
.with(SentryOtelKeys.SENTRY_BAGGAGE_KEY, baggage);

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import io.opentelemetry.sdk.trace.SpanProcessor;
import io.opentelemetry.sdk.trace.data.EventData;
import io.opentelemetry.sdk.trace.data.ExceptionEventData;
import io.opentelemetry.sdk.trace.data.SpanData;
import io.sentry.Baggage;
import io.sentry.DateUtils;
import io.sentry.IScopes;
Expand Down Expand Up @@ -48,11 +49,7 @@ public void onStart(final @NotNull Context parentContext, final @NotNull ReadWri
return;
}

final @Nullable IScopes scopesFromContext = parentContext.get(SENTRY_SCOPES_KEY);
final @NotNull IScopes scopes =
scopesFromContext != null
? scopesFromContext.forkedCurrentScope("spanprocessor")
: Sentry.forkedRootScopes("spanprocessor");
final @NotNull IScopes scopes = forkScopes(parentContext, otelSpan.toSpanData());

final @Nullable IOtelSpanWrapper sentryParentSpan =
spanStorage.getSentrySpan(otelSpan.getParentSpanContext());
Expand Down Expand Up @@ -111,6 +108,22 @@ public void onStart(final @NotNull Context parentContext, final @NotNull ReadWri
spanStorage.storeSentrySpan(spanContext, sentrySpan);
}

private IScopes forkScopes(final @NotNull Context context, final @NotNull SpanData span) {
final @Nullable IScopes scopesFromContext = context.get(SENTRY_SCOPES_KEY);
if (scopesFromContext == null) {
return Sentry.forkedRootScopes("spanprocessor.new");
}
if (isRootSpan(span)) {
return scopesFromContext.forkedScopes("spanprocessor.rootspan");
}

return scopesFromContext.forkedCurrentScope("spanprocessor.nonrootspan");
}

private boolean isRootSpan(SpanData otelSpan) {
return !otelSpan.getParentSpanContext().isValid() || otelSpan.getParentSpanContext().isRemote();
}

private @Nullable Boolean isSampled(
final @NotNull ReadWriteSpan otelSpan,
final @Nullable TracesSamplingDecision samplingDecision) {
Expand Down
Loading