diff --git a/sentry-opentelemetry/sentry-opentelemetry-bootstrap/api/sentry-opentelemetry-bootstrap.api b/sentry-opentelemetry/sentry-opentelemetry-bootstrap/api/sentry-opentelemetry-bootstrap.api index b5135d9d320..110faac5648 100644 --- a/sentry-opentelemetry/sentry-opentelemetry-bootstrap/api/sentry-opentelemetry-bootstrap.api +++ b/sentry-opentelemetry/sentry-opentelemetry-bootstrap/api/sentry-opentelemetry-bootstrap.api @@ -1,4 +1,6 @@ public final class io/sentry/opentelemetry/InternalSemanticAttributes { + public static final field BAGGAGE Lio/opentelemetry/api/common/AttributeKey; + public static final field BAGGAGE_MUTABLE Lio/opentelemetry/api/common/AttributeKey; public static final field IS_REMOTE_PARENT Lio/opentelemetry/api/common/AttributeKey; public static final field PARENT_SAMPLED Lio/opentelemetry/api/common/AttributeKey; public static final field PROFILE_SAMPLED Lio/opentelemetry/api/common/AttributeKey; @@ -16,7 +18,7 @@ public final class io/sentry/opentelemetry/OtelContextScopesStorage : io/sentry/ } public final class io/sentry/opentelemetry/OtelSpanContext : io/sentry/SpanContext { - public fun (Lio/opentelemetry/sdk/trace/ReadWriteSpan;Lio/sentry/TracesSamplingDecision;Lio/sentry/opentelemetry/OtelSpanWrapper;)V + public fun (Lio/opentelemetry/sdk/trace/ReadWriteSpan;Lio/sentry/TracesSamplingDecision;Lio/sentry/opentelemetry/OtelSpanWrapper;Lio/sentry/Baggage;)V public fun getStatus ()Lio/sentry/SpanStatus; public fun setStatus (Lio/sentry/SpanStatus;)V } @@ -30,7 +32,7 @@ public final class io/sentry/opentelemetry/OtelSpanFactory : io/sentry/ISpanFact } public final class io/sentry/opentelemetry/OtelSpanWrapper : io/sentry/ISpan { - public fun (Lio/opentelemetry/sdk/trace/ReadWriteSpan;Lio/sentry/IScopes;Lio/sentry/SentryDate;Lio/sentry/TracesSamplingDecision;Lio/sentry/opentelemetry/OtelSpanWrapper;)V + public fun (Lio/opentelemetry/sdk/trace/ReadWriteSpan;Lio/sentry/IScopes;Lio/sentry/SentryDate;Lio/sentry/TracesSamplingDecision;Lio/sentry/opentelemetry/OtelSpanWrapper;Lio/sentry/Baggage;)V public fun finish ()V public fun finish (Lio/sentry/SpanStatus;)V public fun finish (Lio/sentry/SpanStatus;Lio/sentry/SentryDate;)V diff --git a/sentry-opentelemetry/sentry-opentelemetry-bootstrap/src/main/java/io/sentry/opentelemetry/InternalSemanticAttributes.java b/sentry-opentelemetry/sentry-opentelemetry-bootstrap/src/main/java/io/sentry/opentelemetry/InternalSemanticAttributes.java index e21db174f1b..f9d04c37241 100644 --- a/sentry-opentelemetry/sentry-opentelemetry-bootstrap/src/main/java/io/sentry/opentelemetry/InternalSemanticAttributes.java +++ b/sentry-opentelemetry/sentry-opentelemetry-bootstrap/src/main/java/io/sentry/opentelemetry/InternalSemanticAttributes.java @@ -18,6 +18,9 @@ public final class InternalSemanticAttributes { AttributeKey.doubleKey("sentry.profile_sample_rate"); public static final AttributeKey IS_REMOTE_PARENT = AttributeKey.booleanKey("sentry.is_remote_parent"); + public static final AttributeKey BAGGAGE = AttributeKey.stringKey("sentry.baggage"); + public static final AttributeKey BAGGAGE_MUTABLE = + AttributeKey.booleanKey("sentry.baggage_mutable"); // public static final AttributeKey BREADCRUMB_TYPE = // AttributeKey.stringKey("sentry.breadcrumb.type"); // public static final AttributeKey BREADCRUMB_TYPE = diff --git a/sentry-opentelemetry/sentry-opentelemetry-bootstrap/src/main/java/io/sentry/opentelemetry/OtelSpanContext.java b/sentry-opentelemetry/sentry-opentelemetry-bootstrap/src/main/java/io/sentry/opentelemetry/OtelSpanContext.java index 2d1bd78b957..127dbfd57e3 100644 --- a/sentry-opentelemetry/sentry-opentelemetry-bootstrap/src/main/java/io/sentry/opentelemetry/OtelSpanContext.java +++ b/sentry-opentelemetry/sentry-opentelemetry-bootstrap/src/main/java/io/sentry/opentelemetry/OtelSpanContext.java @@ -4,6 +4,7 @@ import io.opentelemetry.api.trace.StatusCode; import io.opentelemetry.sdk.trace.ReadWriteSpan; import io.opentelemetry.sdk.trace.data.StatusData; +import io.sentry.Baggage; import io.sentry.SpanContext; import io.sentry.SpanId; import io.sentry.SpanStatus; @@ -26,7 +27,8 @@ public final class OtelSpanContext extends SpanContext { public OtelSpanContext( final @NotNull ReadWriteSpan span, final @Nullable TracesSamplingDecision samplingDecision, - final @Nullable OtelSpanWrapper parentSpan) { + final @Nullable OtelSpanWrapper parentSpan, + final @Nullable Baggage baggage) { super( new SentryId(span.getSpanContext().getTraceId()), new SpanId(span.getSpanContext().getSpanId()), @@ -39,6 +41,7 @@ public OtelSpanContext( null, null); this.span = new WeakReference<>(span); + this.baggage = baggage; } @Override diff --git a/sentry-opentelemetry/sentry-opentelemetry-bootstrap/src/main/java/io/sentry/opentelemetry/OtelSpanFactory.java b/sentry-opentelemetry/sentry-opentelemetry-bootstrap/src/main/java/io/sentry/opentelemetry/OtelSpanFactory.java index 3467789c633..8c8fca4ba41 100644 --- a/sentry-opentelemetry/sentry-opentelemetry-bootstrap/src/main/java/io/sentry/opentelemetry/OtelSpanFactory.java +++ b/sentry-opentelemetry/sentry-opentelemetry-bootstrap/src/main/java/io/sentry/opentelemetry/OtelSpanFactory.java @@ -7,6 +7,7 @@ import io.opentelemetry.api.trace.TraceState; import io.opentelemetry.api.trace.Tracer; import io.opentelemetry.context.Context; +import io.sentry.Baggage; import io.sentry.IScope; import io.sentry.IScopes; import io.sentry.ISpan; @@ -104,7 +105,12 @@ public final class OtelSpanFactory implements ISpanFactory { } } - // TODO [POTEL] send baggage in (note: won't go through propagators) + // note: won't go through propagators + final @Nullable Baggage baggage = spanContext.getBaggage(); + if (baggage != null) { + spanBuilder.setAttribute(InternalSemanticAttributes.BAGGAGE_MUTABLE, baggage.isMutable()); + spanBuilder.setAttribute(InternalSemanticAttributes.BAGGAGE, baggage.toHeaderString(null)); + } final @Nullable SentryDate startTimestampFromOptions = spanOptions.getStartTimestamp(); final @NotNull SentryDate startTimestamp = diff --git a/sentry-opentelemetry/sentry-opentelemetry-bootstrap/src/main/java/io/sentry/opentelemetry/OtelSpanWrapper.java b/sentry-opentelemetry/sentry-opentelemetry-bootstrap/src/main/java/io/sentry/opentelemetry/OtelSpanWrapper.java index 8ec6c6bb0b8..a0d6c0a9d43 100644 --- a/sentry-opentelemetry/sentry-opentelemetry-bootstrap/src/main/java/io/sentry/opentelemetry/OtelSpanWrapper.java +++ b/sentry-opentelemetry/sentry-opentelemetry-bootstrap/src/main/java/io/sentry/opentelemetry/OtelSpanWrapper.java @@ -3,6 +3,7 @@ import io.opentelemetry.api.trace.Span; import io.opentelemetry.context.Scope; import io.opentelemetry.sdk.trace.ReadWriteSpan; +import io.sentry.Baggage; import io.sentry.BaggageHeader; import io.sentry.IScopes; import io.sentry.ISentryLifecycleToken; @@ -25,6 +26,7 @@ import io.sentry.protocol.MeasurementValue; import io.sentry.protocol.SentryId; import io.sentry.protocol.TransactionNameSource; +import io.sentry.protocol.User; import io.sentry.util.LazyEvaluator; import io.sentry.util.Objects; import java.lang.ref.WeakReference; @@ -34,6 +36,7 @@ import java.util.Map; import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.TimeUnit; +import java.util.concurrent.atomic.AtomicReference; import org.jetbrains.annotations.ApiStatus; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; @@ -62,6 +65,7 @@ public final class OtelSpanWrapper implements ISpan { private final @NotNull Contexts contexts = new Contexts(); private @Nullable String transactionName; private @Nullable TransactionNameSource transactionNameSource; + private final @Nullable Baggage baggage; // TODO [POTEL] // private @Nullable SpanFinishedCallback spanFinishedCallback; @@ -78,16 +82,28 @@ public final class OtelSpanWrapper implements ISpan { private @NotNull Deque tokensToCleanup = new ArrayDeque<>(1); + // TODO [POTEL] reference root span? for getting root baggage public OtelSpanWrapper( final @NotNull ReadWriteSpan span, final @NotNull IScopes scopes, final @NotNull SentryDate startTimestamp, final @Nullable TracesSamplingDecision samplingDecision, - final @Nullable OtelSpanWrapper parentSpan) { + final @Nullable OtelSpanWrapper parentSpan, + final @Nullable Baggage baggage) { this.scopes = Objects.requireNonNull(scopes, "scopes are required"); this.span = new WeakReference<>(span); this.startTimestamp = startTimestamp; - this.context = new OtelSpanContext(span, samplingDecision, parentSpan); + + if (parentSpan != null) { + this.baggage = parentSpan.getSpanContext().getBaggage(); + } else if (baggage != null) { + this.baggage = baggage; + } else { + this.baggage = null; + // this.baggage = new Baggage(scopes.getOptions().getLogger()); + } + + this.context = new OtelSpanContext(span, samplingDecision, parentSpan, this.baggage); } @Override @@ -178,15 +194,43 @@ public OtelSpanWrapper( @Override public @Nullable TraceContext traceContext() { - // return transaction.traceContext(); - // TODO [POTEL] + if (scopes.getOptions().isTraceSampling()) { + if (baggage != null) { + updateBaggageValues(); + return baggage.toTraceContext(); + } + } return null; } + private void updateBaggageValues() { + synchronized (this) { + if (baggage != null && baggage.isMutable()) { + final AtomicReference userAtomicReference = new AtomicReference<>(); + scopes.configureScope( + scope -> { + userAtomicReference.set(scope.getUser()); + }); + baggage.setValuesFromTransaction( + getSpanContext().getTraceId(), + userAtomicReference.get(), + scopes.getOptions(), + this.getSamplingDecision(), + getTransactionName(), + getTransactionNameSource()); + baggage.freeze(); + } + } + } + @Override public @Nullable BaggageHeader toBaggageHeader(@Nullable List thirdPartyBaggageHeaders) { - // return transaction.toBaggageHeader(thirdPartyBaggageHeaders); - // TODO [POTEL] + if (scopes.getOptions().isTraceSampling()) { + if (baggage != null) { + updateBaggageValues(); + return BaggageHeader.fromBaggageAndOutgoingHeader(baggage, thirdPartyBaggageHeaders); + } + } return null; } diff --git a/sentry-opentelemetry/sentry-opentelemetry-bootstrap/src/main/java/io/sentry/opentelemetry/OtelTransactionSpanForwarder.java b/sentry-opentelemetry/sentry-opentelemetry-bootstrap/src/main/java/io/sentry/opentelemetry/OtelTransactionSpanForwarder.java index fd7110d8ec2..beba25374a3 100644 --- a/sentry-opentelemetry/sentry-opentelemetry-bootstrap/src/main/java/io/sentry/opentelemetry/OtelTransactionSpanForwarder.java +++ b/sentry-opentelemetry/sentry-opentelemetry-bootstrap/src/main/java/io/sentry/opentelemetry/OtelTransactionSpanForwarder.java @@ -77,19 +77,16 @@ public OtelTransactionSpanForwarder(final @NotNull OtelSpanWrapper rootSpan) { @Override public @NotNull SentryTraceHeader toSentryTrace() { - // TODO [POTEL] root span? return rootSpan.toSentryTrace(); } @Override public @Nullable TraceContext traceContext() { - // TODO [POTEL] root span? return rootSpan.traceContext(); } @Override public @Nullable BaggageHeader toBaggageHeader(@Nullable List thirdPartyBaggageHeaders) { - // TODO [POTEL] root span? return rootSpan.toBaggageHeader(thirdPartyBaggageHeaders); } diff --git a/sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/PotelSentryPropagator.java b/sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/PotelSentryPropagator.java index 1cc4b1c4119..3a9d0718f4b 100644 --- a/sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/PotelSentryPropagator.java +++ b/sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/PotelSentryPropagator.java @@ -10,6 +10,7 @@ import io.opentelemetry.context.propagation.TextMapGetter; import io.opentelemetry.context.propagation.TextMapPropagator; import io.opentelemetry.context.propagation.TextMapSetter; +import io.sentry.Baggage; import io.sentry.BaggageHeader; import io.sentry.IScopes; import io.sentry.PropagationContext; @@ -100,6 +101,7 @@ public Context extract( SentryTraceHeader sentryTraceHeader = new SentryTraceHeader(sentryTraceString); final @Nullable String baggageString = getter.get(carrier, BaggageHeader.BAGGAGE_HEADER); + final Baggage baggage = Baggage.fromHeader(baggageString); final @NotNull TraceState traceState = TraceState.getDefault(); SpanContext otelSpanContext = @@ -112,7 +114,11 @@ public Context extract( Span wrappedSpan = Span.wrap(otelSpanContext); final @NotNull Context modifiedContext = - context.with(wrappedSpan).with(SENTRY_SCOPES_KEY, scopesToUse); + context + .with(wrappedSpan) + .with(SENTRY_SCOPES_KEY, scopesToUse) + .with(SentryOtelKeys.SENTRY_TRACE_KEY, sentryTraceHeader) + .with(SentryOtelKeys.SENTRY_BAGGAGE_KEY, baggage); scopes .getOptions() diff --git a/sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/PotelSentrySpanProcessor.java b/sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/PotelSentrySpanProcessor.java index 9105467cefc..2ce773fc380 100644 --- a/sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/PotelSentrySpanProcessor.java +++ b/sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/PotelSentrySpanProcessor.java @@ -8,6 +8,7 @@ import io.opentelemetry.sdk.trace.ReadWriteSpan; import io.opentelemetry.sdk.trace.ReadableSpan; import io.opentelemetry.sdk.trace.SpanProcessor; +import io.sentry.Baggage; import io.sentry.IScopes; import io.sentry.PropagationContext; import io.sentry.SamplingContext; @@ -16,6 +17,7 @@ import io.sentry.SentryDate; import io.sentry.SentryLevel; import io.sentry.SentryLongDate; +import io.sentry.SentryTraceHeader; import io.sentry.SpanId; import io.sentry.TracesSampler; import io.sentry.TracesSamplingDecision; @@ -54,8 +56,20 @@ public void onStart(final @NotNull Context parentContext, final @NotNull ReadWri final @Nullable OtelSpanWrapper sentryParentSpan = spanStorage.getSentrySpan(otelSpan.getParentSpanContext()); @Nullable TracesSamplingDecision samplingDecision = null; + // TODO [POTEL] baggage from propagator should be honored + @Nullable Baggage baggage = null; otelSpan.setAttribute(IS_REMOTE_PARENT, otelSpan.getParentSpanContext().isRemote()); if (sentryParentSpan == null) { + final @Nullable Boolean baggageMutable = + otelSpan.getAttribute(InternalSemanticAttributes.BAGGAGE_MUTABLE); + final @Nullable String baggageString = + otelSpan.getAttribute(InternalSemanticAttributes.BAGGAGE); + if (baggageString != null) { + baggage = Baggage.fromHeader(baggageString); + if (baggageMutable == true) { + baggage.freeze(); + } + } final @Nullable Boolean sampled = otelSpan.getAttribute(InternalSemanticAttributes.SAMPLED); final @Nullable Double sampleRate = otelSpan.getAttribute(InternalSemanticAttributes.SAMPLE_RATE); @@ -73,7 +87,11 @@ public void onStart(final @NotNull Context parentContext, final @NotNull ReadWri final @NotNull PropagationContext propagationContext = new PropagationContext( - new SentryId(traceId), new SpanId(spanId), new SpanId(parentSpanId), null, sampled); + new SentryId(traceId), + new SpanId(spanId), + new SpanId(parentSpanId), + baggage, + sampled); scopes.configureScope( scope -> { @@ -96,9 +114,19 @@ public void onStart(final @NotNull Context parentContext, final @NotNull ReadWri final @NotNull String traceId = otelSpan.getSpanContext().getTraceId(); final @NotNull String spanId = otelSpan.getSpanContext().getSpanId(); + final @NotNull SpanId sentrySpanId = new SpanId(spanId); + + @Nullable + SentryTraceHeader sentryTraceHeader = parentContext.get(SentryOtelKeys.SENTRY_TRACE_KEY); + @Nullable Baggage baggageFromContext = parentContext.get(SentryOtelKeys.SENTRY_BAGGAGE_KEY); + if (sentryTraceHeader != null) { + baggage = baggageFromContext; + } final @NotNull PropagationContext propagationContext = - new PropagationContext(new SentryId(traceId), new SpanId(spanId), null, null, null); + sentryTraceHeader == null + ? new PropagationContext(new SentryId(traceId), sentrySpanId, null, baggage, null) + : PropagationContext.fromHeaders(sentryTraceHeader, baggage, sentrySpanId); scopes.configureScope( scope -> { @@ -118,7 +146,8 @@ public void onStart(final @NotNull Context parentContext, final @NotNull ReadWri new SentryLongDate(otelSpan.toSpanData().getStartEpochNanos()); spanStorage.storeSentrySpan( spanContext, - new OtelSpanWrapper(otelSpan, scopes, startTimestamp, samplingDecision, sentryParentSpan)); + new OtelSpanWrapper( + otelSpan, scopes, startTimestamp, samplingDecision, sentryParentSpan, baggage)); } @Override diff --git a/sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/SentrySpanExporter.java b/sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/SentrySpanExporter.java index 2c62ab45e63..9b96010c75e 100644 --- a/sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/SentrySpanExporter.java +++ b/sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/SentrySpanExporter.java @@ -10,6 +10,7 @@ import io.opentelemetry.sdk.trace.data.StatusData; import io.opentelemetry.sdk.trace.export.SpanExporter; import io.opentelemetry.semconv.SemanticAttributes; +import io.sentry.Baggage; import io.sentry.DateUtils; import io.sentry.DefaultSpanFactory; import io.sentry.DsnUtil; @@ -22,6 +23,7 @@ import io.sentry.SentryInstantDate; import io.sentry.SentryLevel; import io.sentry.SentryLongDate; +import io.sentry.SpanContext; import io.sentry.SpanId; import io.sentry.SpanOptions; import io.sentry.SpanStatus; @@ -197,8 +199,6 @@ private List maybeSend(final @NotNull List spans) { createAndFinishSpanForOtelSpan(childNode, transaction, remaining); } - // spanStorage.getScope() - // transaction.finishWithScope transaction.finish( mapOtelStatus(span, transaction), new SentryLongDate(span.getEndEpochNanos())); } @@ -312,7 +312,6 @@ private void transferSpanDetails( private @Nullable ITransaction createTransactionForOtelSpan(final @NotNull SpanData span) { final @NotNull String spanId = span.getSpanId(); final @NotNull String traceId = span.getTraceId(); - // final @Nullable IScope scope = spanStorage.getScope(spanId); final @Nullable OtelSpanWrapper sentrySpanMaybe = spanStorage.getSentrySpan(span.getSpanContext()); @@ -322,15 +321,6 @@ private void transferSpanDetails( scopesMaybe == null ? ScopesAdapter.getInstance() : scopesMaybe; final @NotNull OtelSpanInfo spanInfo = spanDescriptionExtractor.extractSpanInfo(span); - // final @Nullable Boolean parentSampled = - // span.getAttributes().get(InternalSemanticAttributes.PARENT_SAMPLED); - // TODO DSC - // TODO op, desc, tags, data, origin, source - // TODO metadata - - // TODO we'll have to copy some of otel span attributes over to our transaction/span, e.g. - // thread info is wrong because it's created here in the exporter - scopesToUse .getOptions() .getLogger() @@ -341,10 +331,10 @@ private void transferSpanDetails( traceId); final SpanId sentrySpanId = new SpanId(spanId); - // TODO parentSpanId, parentSamplingDecision, baggage - @NotNull String transactionName = spanInfo.getDescription(); @NotNull TransactionNameSource transactionNameSource = spanInfo.getTransactionNameSource(); + @Nullable SpanId parentSpanId = null; + @Nullable Baggage baggage = null; if (sentrySpanMaybe != null) { final @NotNull OtelSpanWrapper sentrySpan = sentrySpanMaybe; @@ -357,16 +347,14 @@ private void transferSpanDetails( if (transactionNameSourceMaybe != null) { transactionNameSource = transactionNameSourceMaybe; } + final @NotNull SpanContext spanContext = sentrySpan.getSpanContext(); + parentSpanId = spanContext.getParentSpanId(); + baggage = spanContext.getBaggage(); } + // TODO [POTEL] parentSamplingDecision? final @NotNull TransactionContext transactionContext = - new TransactionContext(new SentryId(traceId), sentrySpanId, null, null, null); - // traceData.getSentryTraceHeader() == null - // ? new TransactionContext( - // new SentryId(traceData.getTraceId()), spanId, null, null, null) - // : TransactionContext.fromPropagationContext( - // PropagationContext.fromHeaders( - // traceData.getSentryTraceHeader(), traceData.getBaggage(), spanId)); + new TransactionContext(new SentryId(traceId), sentrySpanId, parentSpanId, null, baggage); transactionContext.setName(transactionName); transactionContext.setTransactionNameSource(transactionNameSource); @@ -380,7 +368,6 @@ private void transferSpanDetails( transactionOptions.setStartTimestamp(new SentryLongDate(span.getStartEpochNanos())); transactionOptions.setSpanFactory(new DefaultSpanFactory()); - // TODO [POTEL] do not sample again ITransaction sentryTransaction = scopesToUse.startTransaction(transactionContext, transactionOptions); sentryTransaction.getSpanContext().setOrigin(TRACE_ORIGN); diff --git a/sentry/api/sentry.api b/sentry/api/sentry.api index 44117d931ab..5602ecd0975 100644 --- a/sentry/api/sentry.api +++ b/sentry/api/sentry.api @@ -66,7 +66,7 @@ public final class io/sentry/Baggage { public fun setUserId (Ljava/lang/String;)V public fun setUserSegment (Ljava/lang/String;)V public fun setValuesFromScope (Lio/sentry/IScope;Lio/sentry/SentryOptions;)V - public fun setValuesFromTransaction (Lio/sentry/ITransaction;Lio/sentry/protocol/User;Lio/sentry/SentryOptions;Lio/sentry/TracesSamplingDecision;)V + public fun setValuesFromTransaction (Lio/sentry/protocol/SentryId;Lio/sentry/protocol/User;Lio/sentry/SentryOptions;Lio/sentry/TracesSamplingDecision;Ljava/lang/String;Lio/sentry/protocol/TransactionNameSource;)V public fun toHeaderString (Ljava/lang/String;)Ljava/lang/String; public fun toTraceContext ()Lio/sentry/TraceContext; } @@ -3155,6 +3155,7 @@ public final class io/sentry/Span : io/sentry/ISpan { public class io/sentry/SpanContext : io/sentry/JsonSerializable, io/sentry/JsonUnknown { public static final field DEFAULT_ORIGIN Ljava/lang/String; public static final field TYPE Ljava/lang/String; + protected field baggage Lio/sentry/Baggage; protected field description Ljava/lang/String; protected field op Ljava/lang/String; protected field origin Ljava/lang/String; @@ -3167,6 +3168,7 @@ public class io/sentry/SpanContext : io/sentry/JsonSerializable, io/sentry/JsonU public fun (Ljava/lang/String;Lio/sentry/TracesSamplingDecision;)V public fun copyForChild (Ljava/lang/String;Lio/sentry/SpanId;Lio/sentry/SpanId;)Lio/sentry/SpanContext; public fun equals (Ljava/lang/Object;)Z + public fun getBaggage ()Lio/sentry/Baggage; public fun getDescription ()Ljava/lang/String; public fun getInstrumenter ()Lio/sentry/Instrumenter; public fun getOperation ()Ljava/lang/String; @@ -3372,7 +3374,6 @@ public final class io/sentry/TransactionContext : io/sentry/SpanContext { public fun (Ljava/lang/String;Ljava/lang/String;Lio/sentry/TracesSamplingDecision;)V public static fun fromPropagationContext (Lio/sentry/PropagationContext;)Lio/sentry/TransactionContext; public static fun fromSentryTrace (Ljava/lang/String;Ljava/lang/String;Lio/sentry/SentryTraceHeader;)Lio/sentry/TransactionContext; - public fun getBaggage ()Lio/sentry/Baggage; public fun getName ()Ljava/lang/String; public fun getParentSampled ()Ljava/lang/Boolean; public fun getParentSamplingDecision ()Lio/sentry/TracesSamplingDecision; diff --git a/sentry/src/main/java/io/sentry/Baggage.java b/sentry/src/main/java/io/sentry/Baggage.java index 4a637bacdf7..34ab1f03175 100644 --- a/sentry/src/main/java/io/sentry/Baggage.java +++ b/sentry/src/main/java/io/sentry/Baggage.java @@ -371,19 +371,18 @@ public void set(final @NotNull String key, final @Nullable String value) { @ApiStatus.Internal public void setValuesFromTransaction( - final @NotNull ITransaction transaction, + final @NotNull SentryId traceId, final @Nullable User user, final @NotNull SentryOptions sentryOptions, - final @Nullable TracesSamplingDecision samplingDecision) { - setTraceId(transaction.getSpanContext().getTraceId().toString()); + final @Nullable TracesSamplingDecision samplingDecision, + final @Nullable String transactionName, + final @Nullable TransactionNameSource transactionNameSource) { + setTraceId(traceId.toString()); setPublicKey(new Dsn(sentryOptions.getDsn()).getPublicKey()); setRelease(sentryOptions.getRelease()); setEnvironment(sentryOptions.getEnvironment()); setUserSegment(user != null ? getSegment(user) : null); - setTransaction( - isHighQualityTransactionName(transaction.getTransactionNameSource()) - ? transaction.getName() - : null); + setTransaction(isHighQualityTransactionName(transactionNameSource) ? transactionName : null); setSampleRate(sampleRateToString(sampleRate(samplingDecision))); setSampled(StringUtils.toString(sampled(samplingDecision))); } diff --git a/sentry/src/main/java/io/sentry/SentryTracer.java b/sentry/src/main/java/io/sentry/SentryTracer.java index c39036e6db5..43cd3cf188c 100644 --- a/sentry/src/main/java/io/sentry/SentryTracer.java +++ b/sentry/src/main/java/io/sentry/SentryTracer.java @@ -638,7 +638,12 @@ private void updateBaggageValues() { userAtomicReference.set(scope.getUser()); }); baggage.setValuesFromTransaction( - this, userAtomicReference.get(), scopes.getOptions(), this.getSamplingDecision()); + getSpanContext().getTraceId(), + userAtomicReference.get(), + scopes.getOptions(), + this.getSamplingDecision(), + getName(), + getTransactionNameSource()); baggage.freeze(); } } diff --git a/sentry/src/main/java/io/sentry/SpanContext.java b/sentry/src/main/java/io/sentry/SpanContext.java index 1b11d10e5ce..2d1b8c5fe7c 100644 --- a/sentry/src/main/java/io/sentry/SpanContext.java +++ b/sentry/src/main/java/io/sentry/SpanContext.java @@ -51,6 +51,8 @@ public class SpanContext implements JsonUnknown, JsonSerializable { private @NotNull Instrumenter instrumenter = Instrumenter.SENTRY; + protected @Nullable Baggage baggage; + public SpanContext( final @NotNull String operation, final @Nullable TracesSamplingDecision samplingDecision) { this(new SentryId(), new SpanId(), operation, null, samplingDecision); @@ -225,6 +227,10 @@ public void setInstrumenter(final @NotNull Instrumenter instrumenter) { this.instrumenter = instrumenter; } + public @Nullable Baggage getBaggage() { + return baggage; + } + @ApiStatus.Internal public SpanContext copyForChild( final @NotNull String operation, diff --git a/sentry/src/main/java/io/sentry/TransactionContext.java b/sentry/src/main/java/io/sentry/TransactionContext.java index 6d63942baf5..8fd4779c264 100644 --- a/sentry/src/main/java/io/sentry/TransactionContext.java +++ b/sentry/src/main/java/io/sentry/TransactionContext.java @@ -16,7 +16,6 @@ public final class TransactionContext extends SpanContext { private @NotNull String name; private @NotNull TransactionNameSource transactionNameSource; private @Nullable TracesSamplingDecision parentSamplingDecision; - private @Nullable Baggage baggage; private boolean isForNextAppStart = false; /** @@ -157,10 +156,6 @@ public TransactionContext( return parentSamplingDecision; } - public @Nullable Baggage getBaggage() { - return baggage; - } - public void setParentSampled(final @Nullable Boolean parentSampled) { if (parentSampled == null) { this.parentSamplingDecision = null; diff --git a/sentry/src/test/java/io/sentry/TraceContextSerializationTest.kt b/sentry/src/test/java/io/sentry/TraceContextSerializationTest.kt index 0847c9448f0..66f34f41c45 100644 --- a/sentry/src/test/java/io/sentry/TraceContextSerializationTest.kt +++ b/sentry/src/test/java/io/sentry/TraceContextSerializationTest.kt @@ -1,6 +1,7 @@ package io.sentry import io.sentry.protocol.SentryId +import io.sentry.protocol.TransactionNameSource import io.sentry.protocol.User import org.junit.Test import org.mockito.kotlin.mock @@ -57,7 +58,7 @@ class TraceContextSerializationTest { val scopes: IScopes = mock() whenever(scopes.options).thenReturn(SentryOptions()) baggage.setValuesFromTransaction( - SentryTracer(TransactionContext("name", "op"), scopes), + SentryId(), User().apply { id = "user-id" others = mapOf("segment" to "pro") @@ -68,7 +69,9 @@ class TraceContextSerializationTest { release = "1.0.17" tracesSampleRate = sRate }, - TracesSamplingDecision(sRate > 0.5, sRate) + TracesSamplingDecision(sRate > 0.5, sRate), + "name", + TransactionNameSource.ROUTE ) return baggage.toTraceContext()!! }