Skip to content

Commit 96b948d

Browse files
authored
Add SENTRY_AUTO_INIT environment variable to control OpenTelemetry Agent init (#2410)
1 parent 61132a2 commit 96b948d

File tree

13 files changed

+131
-31
lines changed

13 files changed

+131
-31
lines changed

CHANGELOG.md

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,15 @@
1010
- Fix `ClassNotFoundException` for `io.sentry.spring.SentrySpringServletContainerInitializer` in `sentry-spring-jakarta` ([#2411](https://github.com/getsentry/sentry-java/issues/2411))
1111
- Fix `sentry-samples-spring-jakarta` ([#2411](https://github.com/getsentry/sentry-java/issues/2411))
1212

13+
### Features
14+
15+
- Add SENTRY_AUTO_INIT environment variable to control OpenTelemetry Agent init ([#2410](https://github.com/getsentry/sentry-java/pull/2410))
16+
- Add OpenTelemetryLinkErrorEventProcessor for linking errors to traces created via OpenTelemetry ([#2418](https://github.com/getsentry/sentry-java/pull/2418))
17+
18+
### Dependencies
19+
20+
- Bump OpenTelemetry to 1.20.1 and OpenTelemetry Java Agent to 1.20.2 ([#2420](https://github.com/getsentry/sentry-java/pull/2420))
21+
1322
## 6.9.1
1423

1524
### Fixes

buildSrc/src/main/java/Config.kt

Lines changed: 13 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -135,10 +135,19 @@ object Config {
135135

136136
val apolloKotlin = "com.apollographql.apollo3:apollo-runtime:3.3.0"
137137

138-
val otelVersion = "1.19.0"
139-
val otelAlphaVersion = "1.19.0-alpha"
140-
val otelJavaagentVersion = "1.19.2"
141-
val otelJavaagentAlphaVersion = "1.19.2-alpha"
138+
object OpenTelemetry {
139+
val otelVersion = "1.20.1"
140+
val otelAlphaVersion = "1.20.1-alpha"
141+
val otelJavaagentVersion = "1.20.2"
142+
val otelJavaagentAlphaVersion = "1.20.2-alpha"
143+
144+
val otelSdk = "io.opentelemetry:opentelemetry-sdk:$otelVersion"
145+
val otelSemconv = "io.opentelemetry:opentelemetry-semconv:$otelAlphaVersion"
146+
val otelJavaAgent = "io.opentelemetry.javaagent:opentelemetry-javaagent:$otelJavaagentVersion"
147+
val otelJavaAgentExtensionApi = "io.opentelemetry.javaagent:opentelemetry-javaagent-extension-api:$otelJavaagentAlphaVersion"
148+
val otelJavaAgentTooling = "io.opentelemetry.javaagent:opentelemetry-javaagent-tooling:$otelJavaagentAlphaVersion"
149+
val otelExtensionAutoconfigureSpi = "io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi:$otelVersion"
150+
}
142151
}
143152

144153
object AnnotationProcessors {

sentry-opentelemetry/sentry-opentelemetry-agent/README.md

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -38,6 +38,13 @@ Sentry.init(
3838
Using the `otel` instrumenter will ensure `Sentry` instrumentation will be done via OpenTelemetry
3939
and integrations as well as direct interactions with transactions and spans have no effect.
4040

41+
## Controlling auto initialization of Sentry
42+
43+
By default if you pass either `SENTRY_DSN` or `SENTRY_PROPERTIES_FILE` as environment variable,
44+
Sentry will automatically be initialized by this agent. To disable this behaviour, you can set
45+
`SENTRY_AUTO_INIT=false` as environment variable. You will then have to initialize Sentry inside
46+
the target application.
47+
4148
## Debugging
4249

4350
To enable debug logging for Sentry, please provide `SENTRY_DEBUG=true` as environment variable or

sentry-opentelemetry/sentry-opentelemetry-agent/build.gradle.kts

Lines changed: 10 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -14,8 +14,12 @@ fun relocatePackages(shadowJar: ShadowJar) {
1414
// rewrite dependencies calling Logger.getLogger
1515
shadowJar.relocate("java.util.logging.Logger", "io.opentelemetry.javaagent.bootstrap.PatchLogger")
1616

17-
// rewrite library instrumentation dependencies
18-
shadowJar.relocate("io.opentelemetry.instrumentation", "io.opentelemetry.javaagent.shaded.instrumentation")
17+
// prevents conflict with library instrumentation, since these classes live in the bootstrap class loader
18+
shadowJar.relocate("io.opentelemetry.instrumentation", "io.opentelemetry.javaagent.shaded.instrumentation") {
19+
// Exclude resource providers since they live in the agent class loader
20+
exclude("io.opentelemetry.instrumentation.resources.*")
21+
exclude("io.opentelemetry.instrumentation.spring.resources.*")
22+
}
1923

2024
// relocate OpenTelemetry API usage
2125
shadowJar.relocate("io.opentelemetry.api", "io.opentelemetry.javaagent.shaded.io.opentelemetry.api")
@@ -50,7 +54,7 @@ val upstreamAgent = configurations.create("upstreamAgent") {
5054
dependencies {
5155
bootstrapLibs(projects.sentry)
5256
javaagentLibs(projects.sentryOpentelemetry.sentryOpentelemetryAgentcustomization)
53-
upstreamAgent("io.opentelemetry.javaagent:opentelemetry-javaagent:${Config.Libs.otelJavaagentVersion}")
57+
upstreamAgent(Config.Libs.OpenTelemetry.otelJavaAgent)
5458
}
5559

5660
fun isolateClasses(jars: Iterable<File>): CopySpec {
@@ -146,11 +150,11 @@ tasks {
146150
attributes.put("Can-Redefine-Classes", "true")
147151
attributes.put("Can-Retransform-Classes", "true")
148152
attributes.put("Implementation-Vendor", "Sentry")
149-
attributes.put("Implementation-Version", "sentry-${project.version}-otel-${Config.Libs.otelJavaagentVersion}")
153+
attributes.put("Implementation-Version", "sentry-${project.version}-otel-${Config.Libs.OpenTelemetry.otelJavaagentVersion}")
150154
attributes.put("Sentry-Version-Name", project.version)
151155
attributes.put("Sentry-Opentelemetry-SDK-Name", Config.Sentry.SENTRY_OPENTELEMETRY_AGENT_SDK_NAME)
152-
attributes.put("Sentry-Opentelemetry-Version-Name", Config.Libs.otelVersion)
153-
attributes.put("Sentry-Opentelemetry-Javaagent-Version-Name", Config.Libs.otelJavaagentVersion)
156+
attributes.put("Sentry-Opentelemetry-Version-Name", Config.Libs.OpenTelemetry.otelVersion)
157+
attributes.put("Sentry-Opentelemetry-Javaagent-Version-Name", Config.Libs.OpenTelemetry.otelJavaagentVersion)
154158
}
155159
}
156160

sentry-opentelemetry/sentry-opentelemetry-agentcustomization/build.gradle.kts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -22,10 +22,10 @@ dependencies {
2222
compileOnly(projects.sentry)
2323
implementation(projects.sentryOpentelemetry.sentryOpentelemetryCore)
2424

25-
compileOnly("io.opentelemetry:opentelemetry-sdk:${Config.Libs.otelVersion}")
26-
compileOnly("io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi:${Config.Libs.otelVersion}")
27-
compileOnly("io.opentelemetry.javaagent:opentelemetry-javaagent-extension-api:${Config.Libs.otelJavaagentAlphaVersion}")
28-
compileOnly("io.opentelemetry.javaagent:opentelemetry-javaagent-tooling:${Config.Libs.otelJavaagentAlphaVersion}")
25+
compileOnly(Config.Libs.OpenTelemetry.otelSdk)
26+
compileOnly(Config.Libs.OpenTelemetry.otelExtensionAutoconfigureSpi)
27+
compileOnly(Config.Libs.OpenTelemetry.otelJavaAgentExtensionApi)
28+
compileOnly(Config.Libs.OpenTelemetry.otelJavaAgentTooling)
2929

3030
compileOnly(Config.CompileOnly.nopen)
3131
errorprone(Config.CompileOnly.nopenChecker)

sentry-opentelemetry/sentry-opentelemetry-agentcustomization/src/main/java/io/sentry/opentelemetry/SentryAutoConfigurationCustomizerProvider.java

Lines changed: 15 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -23,14 +23,12 @@ public final class SentryAutoConfigurationCustomizerProvider
2323

2424
@Override
2525
public void customize(AutoConfigurationCustomizer autoConfiguration) {
26-
final @Nullable String sentryPropertiesFile = System.getenv("SENTRY_PROPERTIES_FILE");
27-
final @Nullable String sentryDsn = System.getenv("SENTRY_DSN");
28-
29-
if (sentryPropertiesFile != null || sentryDsn != null) {
26+
if (isSentryAutoInitEnabled()) {
3027
Sentry.init(
3128
options -> {
3229
options.setEnableExternalConfiguration(true);
3330
options.setInstrumenter(Instrumenter.OTEL);
31+
options.addEventProcessor(new OpenTelemetryLinkErrorEventProcessor());
3432
final @Nullable SdkVersion sdkVersion = createSdkVersion(options);
3533
if (sdkVersion != null) {
3634
options.setSdkVersion(sdkVersion);
@@ -43,6 +41,19 @@ public void customize(AutoConfigurationCustomizer autoConfiguration) {
4341
.addPropertiesSupplier(this::getDefaultProperties);
4442
}
4543

44+
private boolean isSentryAutoInitEnabled() {
45+
final @Nullable String sentryAutoInit = System.getenv("SENTRY_AUTO_INIT");
46+
47+
if (sentryAutoInit != null) {
48+
return "true".equalsIgnoreCase(sentryAutoInit);
49+
} else {
50+
final @Nullable String sentryPropertiesFile = System.getenv("SENTRY_PROPERTIES_FILE");
51+
final @Nullable String sentryDsn = System.getenv("SENTRY_DSN");
52+
53+
return sentryPropertiesFile != null || sentryDsn != null;
54+
}
55+
}
56+
4657
private @Nullable SdkVersion createSdkVersion(final @NotNull SentryOptions sentryOptions) {
4758
SdkVersion sdkVersion = sentryOptions.getSdkVersion();
4859

sentry-opentelemetry/sentry-opentelemetry-core/api/sentry-opentelemetry-core.api

Lines changed: 5 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,8 @@
1+
public final class io/sentry/opentelemetry/OpenTelemetryLinkErrorEventProcessor : io/sentry/EventProcessor {
2+
public fun <init> ()V
3+
public fun process (Lio/sentry/SentryEvent;Lio/sentry/Hint;)Lio/sentry/SentryEvent;
4+
}
5+
16
public final class io/sentry/opentelemetry/OtelSpanInfo {
27
public fun <init> (Ljava/lang/String;Ljava/lang/String;Lio/sentry/protocol/TransactionNameSource;)V
38
public fun getDescription ()Ljava/lang/String;
@@ -26,13 +31,6 @@ public final class io/sentry/opentelemetry/SentrySpanProcessor : io/opentelemetr
2631
public fun onStart (Lio/opentelemetry/context/Context;Lio/opentelemetry/sdk/trace/ReadWriteSpan;)V
2732
}
2833

29-
public final class io/sentry/opentelemetry/SentrySpanStorage {
30-
public fun get (Ljava/lang/String;)Lio/sentry/ISpan;
31-
public static fun getInstance ()Lio/sentry/opentelemetry/SentrySpanStorage;
32-
public fun removeAndGet (Ljava/lang/String;)Lio/sentry/ISpan;
33-
public fun store (Ljava/lang/String;Lio/sentry/ISpan;)V
34-
}
35-
3634
public final class io/sentry/opentelemetry/SpanDescriptionExtractor {
3735
public fun <init> ()V
3836
public fun extractSpanDescription (Lio/opentelemetry/sdk/trace/ReadableSpan;)Lio/sentry/opentelemetry/OtelSpanInfo;

sentry-opentelemetry/sentry-opentelemetry-core/build.gradle.kts

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -21,8 +21,8 @@ tasks.withType<KotlinCompile>().configureEach {
2121
dependencies {
2222
compileOnly(projects.sentry)
2323

24-
compileOnly("io.opentelemetry:opentelemetry-sdk:${Config.Libs.otelVersion}")
25-
compileOnly("io.opentelemetry:opentelemetry-semconv:${Config.Libs.otelAlphaVersion}")
24+
compileOnly(Config.Libs.OpenTelemetry.otelSdk)
25+
compileOnly(Config.Libs.OpenTelemetry.otelSemconv)
2626

2727
compileOnly(Config.CompileOnly.nopen)
2828
errorprone(Config.CompileOnly.nopenChecker)
@@ -37,8 +37,8 @@ dependencies {
3737
testImplementation(Config.TestLibs.mockitoKotlin)
3838
testImplementation(Config.TestLibs.awaitility)
3939

40-
testImplementation("io.opentelemetry:opentelemetry-sdk:${Config.Libs.otelVersion}")
41-
testImplementation("io.opentelemetry:opentelemetry-semconv:${Config.Libs.otelAlphaVersion}")
40+
testImplementation(Config.Libs.OpenTelemetry.otelSdk)
41+
testImplementation(Config.Libs.OpenTelemetry.otelSemconv)
4242
}
4343

4444
configure<SourceSetContainer> {
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,50 @@
1+
package io.sentry.opentelemetry;
2+
3+
import io.opentelemetry.api.trace.Span;
4+
import io.opentelemetry.api.trace.SpanId;
5+
import io.opentelemetry.api.trace.TraceId;
6+
import io.sentry.EventProcessor;
7+
import io.sentry.Hint;
8+
import io.sentry.HubAdapter;
9+
import io.sentry.ISpan;
10+
import io.sentry.Instrumenter;
11+
import io.sentry.SentryEvent;
12+
import io.sentry.SentrySpanStorage;
13+
import io.sentry.SpanContext;
14+
import io.sentry.protocol.SentryId;
15+
import org.jetbrains.annotations.NotNull;
16+
import org.jetbrains.annotations.Nullable;
17+
18+
public final class OpenTelemetryLinkErrorEventProcessor implements EventProcessor {
19+
20+
private final @NotNull SentrySpanStorage spanStorage = SentrySpanStorage.getInstance();
21+
22+
@Override
23+
public @Nullable SentryEvent process(final @NotNull SentryEvent event, final @NotNull Hint hint) {
24+
if (Instrumenter.OTEL.equals(HubAdapter.getInstance().getOptions().getInstrumenter())) {
25+
@NotNull final Span otelSpan = Span.current();
26+
@NotNull final String traceId = otelSpan.getSpanContext().getTraceId();
27+
@NotNull final String spanId = otelSpan.getSpanContext().getSpanId();
28+
29+
if (TraceId.isValid(traceId) && SpanId.isValid(spanId)) {
30+
final @Nullable ISpan sentrySpan = spanStorage.get(spanId);
31+
if (sentrySpan != null) {
32+
final @NotNull SpanContext sentrySpanSpanContext = sentrySpan.getSpanContext();
33+
final @NotNull String operation = sentrySpanSpanContext.getOperation();
34+
final @Nullable io.sentry.SpanId parentSpanId = sentrySpanSpanContext.getParentSpanId();
35+
final @NotNull SpanContext spanContext =
36+
new SpanContext(
37+
new SentryId(traceId),
38+
new io.sentry.SpanId(spanId),
39+
operation,
40+
parentSpanId,
41+
null);
42+
43+
event.getContexts().setTrace(spanContext);
44+
}
45+
}
46+
}
47+
48+
return event;
49+
}
50+
}

sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/SentryPropagator.java

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@
1111
import io.sentry.Baggage;
1212
import io.sentry.BaggageHeader;
1313
import io.sentry.ISpan;
14+
import io.sentry.SentrySpanStorage;
1415
import io.sentry.SentryTraceHeader;
1516
import io.sentry.exception.InvalidSentryTraceHeaderException;
1617
import java.util.Arrays;

0 commit comments

Comments
 (0)