Skip to content

Commit

Permalink
Add OpenTelemetryLinkErrorEventProcessor for linking errors to traces…
Browse files Browse the repository at this point in the history
… created via OpenTelemetry (#2418)
  • Loading branch information
adinauer committed Dec 6, 2022
1 parent 2d1a223 commit 3814df6
Show file tree
Hide file tree
Showing 8 changed files with 71 additions and 9 deletions.
1 change: 1 addition & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
### Features

- Add SENTRY_AUTO_INIT environment variable to control OpenTelemetry Agent init ([#2410](https://github.com/getsentry/sentry-java/pull/2410))
- Add OpenTelemetryLinkErrorEventProcessor for linking errors to traces created via OpenTelemetry ([#2418](https://github.com/getsentry/sentry-java/pull/2418))

## 6.9.1

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -28,6 +28,7 @@ public void customize(AutoConfigurationCustomizer autoConfiguration) {
options -> {
options.setEnableExternalConfiguration(true);
options.setInstrumenter(Instrumenter.OTEL);
options.addEventProcessor(new OpenTelemetryLinkErrorEventProcessor());
final @Nullable SdkVersion sdkVersion = createSdkVersion(options);
if (sdkVersion != null) {
options.setSdkVersion(sdkVersion);
Expand Down
Original file line number Diff line number Diff line change
@@ -1,3 +1,8 @@
public final class io/sentry/opentelemetry/OpenTelemetryLinkErrorEventProcessor : io/sentry/EventProcessor {
public fun <init> ()V
public fun process (Lio/sentry/SentryEvent;Lio/sentry/Hint;)Lio/sentry/SentryEvent;
}

public final class io/sentry/opentelemetry/OtelSpanInfo {
public fun <init> (Ljava/lang/String;Ljava/lang/String;Lio/sentry/protocol/TransactionNameSource;)V
public fun getDescription ()Ljava/lang/String;
Expand Down Expand Up @@ -26,13 +31,6 @@ public final class io/sentry/opentelemetry/SentrySpanProcessor : io/opentelemetr
public fun onStart (Lio/opentelemetry/context/Context;Lio/opentelemetry/sdk/trace/ReadWriteSpan;)V
}

public final class io/sentry/opentelemetry/SentrySpanStorage {
public fun get (Ljava/lang/String;)Lio/sentry/ISpan;
public static fun getInstance ()Lio/sentry/opentelemetry/SentrySpanStorage;
public fun removeAndGet (Ljava/lang/String;)Lio/sentry/ISpan;
public fun store (Ljava/lang/String;Lio/sentry/ISpan;)V
}

public final class io/sentry/opentelemetry/SpanDescriptionExtractor {
public fun <init> ()V
public fun extractSpanDescription (Lio/opentelemetry/sdk/trace/ReadableSpan;)Lio/sentry/opentelemetry/OtelSpanInfo;
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,50 @@
package io.sentry.opentelemetry;

import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.SpanId;
import io.opentelemetry.api.trace.TraceId;
import io.sentry.EventProcessor;
import io.sentry.Hint;
import io.sentry.HubAdapter;
import io.sentry.ISpan;
import io.sentry.Instrumenter;
import io.sentry.SentryEvent;
import io.sentry.SentrySpanStorage;
import io.sentry.SpanContext;
import io.sentry.protocol.SentryId;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

public final class OpenTelemetryLinkErrorEventProcessor implements EventProcessor {

private final @NotNull SentrySpanStorage spanStorage = SentrySpanStorage.getInstance();

@Override
public @Nullable SentryEvent process(final @NotNull SentryEvent event, final @NotNull Hint hint) {
if (Instrumenter.OTEL.equals(HubAdapter.getInstance().getOptions().getInstrumenter())) {
@NotNull final Span otelSpan = Span.current();
@NotNull final String traceId = otelSpan.getSpanContext().getTraceId();
@NotNull final String spanId = otelSpan.getSpanContext().getSpanId();

if (TraceId.isValid(traceId) && SpanId.isValid(spanId)) {
final @Nullable ISpan sentrySpan = spanStorage.get(spanId);
if (sentrySpan != null) {
final @NotNull SpanContext sentrySpanSpanContext = sentrySpan.getSpanContext();
final @NotNull String operation = sentrySpanSpanContext.getOperation();
final @Nullable io.sentry.SpanId parentSpanId = sentrySpanSpanContext.getParentSpanId();
final @NotNull SpanContext spanContext =
new SpanContext(
new SentryId(traceId),
new io.sentry.SpanId(spanId),
operation,
parentSpanId,
null);

event.getContexts().setTrace(spanContext);
}
}
}

return event;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import io.sentry.Baggage;
import io.sentry.BaggageHeader;
import io.sentry.ISpan;
import io.sentry.SentrySpanStorage;
import io.sentry.SentryTraceHeader;
import io.sentry.exception.InvalidSentryTraceHeaderException;
import java.util.Arrays;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -19,6 +19,7 @@
import io.sentry.ISpan;
import io.sentry.ITransaction;
import io.sentry.Instrumenter;
import io.sentry.SentrySpanStorage;
import io.sentry.SentryTraceHeader;
import io.sentry.SpanId;
import io.sentry.SpanStatus;
Expand Down
7 changes: 7 additions & 0 deletions sentry/api/sentry.api
Original file line number Diff line number Diff line change
Expand Up @@ -1562,6 +1562,13 @@ public abstract interface class io/sentry/SentryOptions$TracesSamplerCallback {
public abstract fun sample (Lio/sentry/SamplingContext;)Ljava/lang/Double;
}

public final class io/sentry/SentrySpanStorage {
public fun get (Ljava/lang/String;)Lio/sentry/ISpan;
public static fun getInstance ()Lio/sentry/SentrySpanStorage;
public fun removeAndGet (Ljava/lang/String;)Lio/sentry/ISpan;
public fun store (Ljava/lang/String;Lio/sentry/ISpan;)V
}

public final class io/sentry/SentryTraceHeader {
public static final field SENTRY_TRACE_HEADER Ljava/lang/String;
public fun <init> (Lio/sentry/protocol/SentryId;Lio/sentry/SpanId;Ljava/lang/Boolean;)V
Expand Down
Original file line number Diff line number Diff line change
@@ -1,12 +1,15 @@
package io.sentry.opentelemetry;
package io.sentry;

import io.sentry.ISpan;
import java.util.Map;
import java.util.concurrent.ConcurrentHashMap;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

/**
* Has been moved to `sentry` gradle module to include it in the bootstrap classloader without
* having to introduce yet another module for OpenTelemetry support.
*/
@ApiStatus.Internal
public final class SentrySpanStorage {
private static volatile @Nullable SentrySpanStorage INSTANCE;
Expand Down

0 comments on commit 3814df6

Please sign in to comment.