diff --git a/sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/OpenTelemetryLinkErrorEventProcessor.java b/sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/OpenTelemetryLinkErrorEventProcessor.java index e528afe2e4..bec48e0fc7 100644 --- a/sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/OpenTelemetryLinkErrorEventProcessor.java +++ b/sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/OpenTelemetryLinkErrorEventProcessor.java @@ -10,6 +10,7 @@ import io.sentry.ISpan; import io.sentry.Instrumenter; import io.sentry.SentryEvent; +import io.sentry.SentryLevel; import io.sentry.SentrySpanStorage; import io.sentry.SpanContext; import io.sentry.protocol.SentryId; @@ -33,7 +34,8 @@ public OpenTelemetryLinkErrorEventProcessor() { @Override public @Nullable SentryEvent process(final @NotNull SentryEvent event, final @NotNull Hint hint) { - if (Instrumenter.OTEL.equals(hub.getOptions().getInstrumenter())) { + final @NotNull Instrumenter instrumenter = hub.getOptions().getInstrumenter(); + if (Instrumenter.OTEL.equals(instrumenter)) { @NotNull final Span otelSpan = Span.current(); @NotNull final String traceId = otelSpan.getSpanContext().getTraceId(); @NotNull final String spanId = otelSpan.getSpanContext().getSpanId(); @@ -53,8 +55,33 @@ public OpenTelemetryLinkErrorEventProcessor() { null); event.getContexts().setTrace(spanContext); + hub.getOptions() + .getLogger() + .log( + SentryLevel.DEBUG, + "Linking Sentry event to span %s created via OpenTelemetry.", + spanId); + } else { + hub.getOptions() + .getLogger() + .log( + SentryLevel.DEBUG, + "Not linking Sentry event to any transaction created via OpenTelemetry as none has been found."); } + } else { + hub.getOptions() + .getLogger() + .log( + SentryLevel.DEBUG, + "Not linking Sentry event to any transaction created via OpenTelemetry as traceId or spanId are invalid."); } + } else { + hub.getOptions() + .getLogger() + .log( + SentryLevel.DEBUG, + "Not linking Sentry event to any transaction created via OpenTelemetry as instrumenter is set to %s.", + instrumenter); } return event; diff --git a/sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/SentryPropagator.java b/sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/SentryPropagator.java index f82f747c85..4ca85dd572 100644 --- a/sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/SentryPropagator.java +++ b/sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/SentryPropagator.java @@ -10,7 +10,10 @@ import io.opentelemetry.context.propagation.TextMapSetter; import io.sentry.Baggage; import io.sentry.BaggageHeader; +import io.sentry.HubAdapter; +import io.sentry.IHub; import io.sentry.ISpan; +import io.sentry.SentryLevel; import io.sentry.SentrySpanStorage; import io.sentry.SentryTraceHeader; import io.sentry.exception.InvalidSentryTraceHeaderException; @@ -26,6 +29,15 @@ public final class SentryPropagator implements TextMapPropagator { private static final @NotNull List FIELDS = Arrays.asList(SentryTraceHeader.SENTRY_TRACE_HEADER, BaggageHeader.BAGGAGE_HEADER); private final @NotNull SentrySpanStorage spanStorage = SentrySpanStorage.getInstance(); + private final @NotNull IHub hub; + + public SentryPropagator() { + this(HubAdapter.getInstance()); + } + + SentryPropagator(final @NotNull IHub hub) { + this.hub = hub; + } @Override public Collection fields() { @@ -37,10 +49,20 @@ public void inject(final Context context, final C carrier, final TextMapSett final @NotNull Span otelSpan = Span.fromContext(context); final @NotNull SpanContext otelSpanContext = otelSpan.getSpanContext(); if (!otelSpanContext.isValid()) { + hub.getOptions() + .getLogger() + .log( + SentryLevel.DEBUG, + "Not injecting Sentry tracing information for invalid OpenTelemetry span."); return; } final @Nullable ISpan sentrySpan = spanStorage.get(otelSpanContext.getSpanId()); if (sentrySpan == null || sentrySpan.isNoOp()) { + hub.getOptions() + .getLogger() + .log( + SentryLevel.DEBUG, + "Not injecting Sentry tracing information as no Sentry span has been found or it is a NoOp."); return; } @@ -82,8 +104,18 @@ public Context extract( Span wrappedSpan = Span.wrap(otelSpanContext); modifiedContext = modifiedContext.with(wrappedSpan); + hub.getOptions() + .getLogger() + .log(SentryLevel.DEBUG, "Continuing Sentry trace %s", sentryTraceHeader.getTraceId()); + return modifiedContext; } catch (InvalidSentryTraceHeaderException e) { + hub.getOptions() + .getLogger() + .log( + SentryLevel.ERROR, + "Unable to extract Sentry tracing information from invalid header.", + e); return context; } } diff --git a/sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/SentrySpanProcessor.java b/sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/SentrySpanProcessor.java index fba597a48c..c02a073f17 100644 --- a/sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/SentrySpanProcessor.java +++ b/sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/SentrySpanProcessor.java @@ -19,6 +19,7 @@ import io.sentry.ISpan; import io.sentry.ITransaction; import io.sentry.Instrumenter; +import io.sentry.SentryLevel; import io.sentry.SentrySpanStorage; import io.sentry.SentryTraceHeader; import io.sentry.SpanId; @@ -48,7 +49,7 @@ public SentrySpanProcessor() { this(HubAdapter.getInstance()); } - SentrySpanProcessor(@NotNull IHub hub) { + SentrySpanProcessor(final @NotNull IHub hub) { this.hub = hub; } @@ -59,6 +60,11 @@ public void onStart(final @NotNull Context parentContext, final @NotNull ReadWri } if (isSentryRequest(otelSpan)) { + hub.getOptions() + .getLogger() + .log( + SentryLevel.DEBUG, + "Not forwarding OpenTelemetry Span to Sentry as this looks like a span for a request to Sentry."); return; } @@ -67,6 +73,13 @@ public void onStart(final @NotNull Context parentContext, final @NotNull ReadWri traceData.getParentSpanId() == null ? null : spanStorage.get(traceData.getParentSpanId()); if (sentryParentSpan != null) { + hub.getOptions() + .getLogger() + .log( + SentryLevel.DEBUG, + "Creating Sentry child span %s for OpenTelemetry span. Parent span is %s.", + traceData.getSpanId(), + traceData.getParentSpanId()); final @NotNull Date startDate = DateUtils.nanosToDate(otelSpan.toSpanData().getStartEpochNanos()); final @NotNull ISpan sentryChildSpan = @@ -74,6 +87,12 @@ public void onStart(final @NotNull Context parentContext, final @NotNull ReadWri otelSpan.getName(), otelSpan.getName(), startDate, Instrumenter.OTEL); spanStorage.store(traceData.getSpanId(), sentryChildSpan); } else { + hub.getOptions() + .getLogger() + .log( + SentryLevel.DEBUG, + "Creating Sentry transaction %s for OpenTelemetry span.", + traceData.getSpanId()); final @NotNull String transactionName = otelSpan.getName(); final @NotNull TransactionNameSource transactionNameSource = TransactionNameSource.CUSTOM; final @Nullable String op = otelSpan.getName(); @@ -124,18 +143,41 @@ public void onEnd(final @NotNull ReadableSpan otelSpan) { final @Nullable ISpan sentrySpan = spanStorage.removeAndGet(traceData.getSpanId()); if (sentrySpan == null) { + hub.getOptions() + .getLogger() + .log( + SentryLevel.DEBUG, + "Unable to find Sentry span for OpenTelemetry span %s.", + traceData.getSpanId()); return; } if (isSentryRequest(otelSpan)) { + hub.getOptions() + .getLogger() + .log( + SentryLevel.DEBUG, + "Not forwarding OpenTelemetry Span to Sentry as this looks like a span for a request to Sentry."); return; } if (sentrySpan instanceof ITransaction) { ITransaction sentryTransaction = (ITransaction) sentrySpan; updateTransactionWithOtelData(sentryTransaction, otelSpan); + hub.getOptions() + .getLogger() + .log( + SentryLevel.DEBUG, + "Finishing Sentry transaction for OpenTelemetry span %s.", + traceData.getSpanId()); } else { updateSpanWithOtelData(sentrySpan, otelSpan); + hub.getOptions() + .getLogger() + .log( + SentryLevel.DEBUG, + "Finishing Sentry span for OpenTelemetry span %s.", + traceData.getSpanId()); } final @NotNull SpanStatus sentryStatus = mapOtelStatus(otelSpan); @@ -151,15 +193,32 @@ public boolean isEndRequired() { private boolean ensurePrerequisites(final @NotNull ReadableSpan otelSpan) { if (!hasSentryBeenInitialized()) { + hub.getOptions() + .getLogger() + .log( + SentryLevel.DEBUG, + "Not forwarding OpenTelemetry Span to Sentry as Sentry has not yet been initialized."); return false; } - if (!Instrumenter.OTEL.equals(hub.getOptions().getInstrumenter())) { + final @NotNull Instrumenter instrumenter = hub.getOptions().getInstrumenter(); + if (!Instrumenter.OTEL.equals(instrumenter)) { + hub.getOptions() + .getLogger() + .log( + SentryLevel.DEBUG, + "Not forwarding OpenTelemetry Span to Sentry as instrumenter has been set to %s.", + instrumenter); return false; } final @NotNull SpanContext otelSpanContext = otelSpan.getSpanContext(); if (!otelSpanContext.isValid()) { + hub.getOptions() + .getLogger() + .log( + SentryLevel.DEBUG, + "Not forwarding OpenTelemetry Span to Sentry as the span is invalid."); return false; } diff --git a/sentry-opentelemetry/sentry-opentelemetry-core/src/test/kotlin/SentrySpanProcessorTest.kt b/sentry-opentelemetry/sentry-opentelemetry-core/src/test/kotlin/SentrySpanProcessorTest.kt index 0c6fe77f26..472cf17f2a 100644 --- a/sentry-opentelemetry/sentry-opentelemetry-core/src/test/kotlin/SentrySpanProcessorTest.kt +++ b/sentry-opentelemetry/sentry-opentelemetry-core/src/test/kotlin/SentrySpanProcessorTest.kt @@ -142,30 +142,32 @@ class SentrySpanProcessorTest { @Test fun `does nothing on start if Sentry has not been initialized`() { - val hub = mock() + fixture.setup() val context = mock() val span = mock() - whenever(hub.isEnabled).thenReturn(false) + whenever(fixture.hub.isEnabled).thenReturn(false) - SentrySpanProcessor(hub).onStart(context, span) + SentrySpanProcessor(fixture.hub).onStart(context, span) - verify(hub).isEnabled - verifyNoMoreInteractions(hub) + verify(fixture.hub).isEnabled + verify(fixture.hub).options + verifyNoMoreInteractions(fixture.hub) verifyNoInteractions(context, span) } @Test fun `does nothing on end if Sentry has not been initialized`() { - val hub = mock() + fixture.setup() val span = mock() - whenever(hub.isEnabled).thenReturn(false) + whenever(fixture.hub.isEnabled).thenReturn(false) - SentrySpanProcessor(hub).onEnd(span) + SentrySpanProcessor(fixture.hub).onEnd(span) - verify(hub).isEnabled - verifyNoMoreInteractions(hub) + verify(fixture.hub).isEnabled + verify(fixture.hub).options + verifyNoMoreInteractions(fixture.hub) verifyNoInteractions(span) }