Skip to content
Merged
Show file tree
Hide file tree
Changes from all 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
8 changes: 5 additions & 3 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,11 @@
- To enable the auto configuration of it, please set `-Dotel.java.global-autoconfigure.enabled=true` on the `java` command, when starting your application.
- You may also want to set `OTEL_LOGS_EXPORTER=none;OTEL_METRICS_EXPORTER=none;OTEL_TRACES_EXPORTER=none` env vars to not have the log flooded with error messages regarding OpenTelemetry features we don't use.
- `OpenTelemetryUtil.applyOpenTelemetryOptions` now takes an enum instead of a boolean for its mode
- Use `AGENT` when using `sentry-opentelemetry-agent`
- Use `AGENTLESS` when using `sentry-opentelemetry-agentless`
- Use `AGENTLESS_SPRING` when using `sentry-opentelemetry-agentless-spring`
- Add `openTelemetryMode` option ([#3994](https://github.com/getsentry/sentry-java/pull/3994))
- It defaults to `AUTO` meaning the SDK will figure out how to best configure itself for use with OpenTelemetry
- Use `AGENT` when using `sentry-opentelemetry-agent`
- Use `AGENTLESS` when using `sentry-opentelemetry-agentless`
- Use `AGENTLESS_SPRING` when using `sentry-opentelemetry-agentless-spring`

### Fixes

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
import io.sentry.InitPriority;
import io.sentry.Sentry;
import io.sentry.SentryIntegrationPackageStorage;
import io.sentry.SentryOpenTelemetryMode;
import io.sentry.SentryOptions;
import io.sentry.protocol.SdkVersion;
import io.sentry.protocol.SentryPackage;
Expand Down Expand Up @@ -39,7 +38,6 @@ public void customize(AutoConfigurationCustomizer autoConfiguration) {
options -> {
options.setEnableExternalConfiguration(true);
options.setInitPriority(InitPriority.HIGH);
OpenTelemetryUtil.applyOpenTelemetryOptions(options, SentryOpenTelemetryMode.AGENT);
final @Nullable SdkVersion sdkVersion = createSdkVersion(options, versionInfoHolder);
if (sdkVersion != null) {
options.setSdkVersion(sdkVersion);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,9 +13,7 @@
import io.sentry.Sentry;
import io.sentry.SentryEvent;
import io.sentry.SentryLevel;
import io.sentry.SentryOpenTelemetryMode;
import io.sentry.SpanStatus;
import io.sentry.opentelemetry.OpenTelemetryUtil;
import io.sentry.protocol.Message;
import io.sentry.protocol.User;
import java.util.Collections;
Expand All @@ -30,8 +28,6 @@ public static void main(String[] args) throws InterruptedException {
options.setDsn(
"https://[email protected]/5428563");

OpenTelemetryUtil.applyOpenTelemetryOptions(options, SentryOpenTelemetryMode.AGENTLESS);

// All events get assigned to the release. See more at
// https://docs.sentry.io/workflow/releases/
options.setRelease("[email protected]+1");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import io.sentry.DefaultSpanFactory
import io.sentry.IScopes
import io.sentry.ITransportFactory
import io.sentry.Sentry
import io.sentry.SentryOpenTelemetryMode
import io.sentry.SentryOptions
import io.sentry.checkEvent
import io.sentry.checkTransaction
Expand Down Expand Up @@ -249,6 +250,7 @@ open class App {
open fun optionsCallback() = Sentry.OptionsConfiguration<SentryOptions> { options ->
// due to OTel being on the classpath we need to set the default again
options.spanFactory = DefaultSpanFactory()
options.openTelemetryMode = SentryOpenTelemetryMode.ALL_ORIGINS
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ import io.sentry.DefaultSpanFactory
import io.sentry.IScopes
import io.sentry.ITransportFactory
import io.sentry.Sentry
import io.sentry.SentryOpenTelemetryMode
import io.sentry.SentryOptions
import io.sentry.checkEvent
import io.sentry.checkTransaction
Expand Down Expand Up @@ -249,6 +250,8 @@ open class App {
open fun optionsCallback() = Sentry.OptionsConfiguration<SentryOptions> { options ->
// due to OTel being on the classpath we need to set the default again
options.spanFactory = DefaultSpanFactory()
// to test the actual spring implementation
options.openTelemetryMode = SentryOpenTelemetryMode.ALL_ORIGINS
}
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import io.sentry.SentryIntegrationPackageStorage;
import io.sentry.SentryOpenTelemetryMode;
import io.sentry.SentryOptions;
import io.sentry.opentelemetry.OpenTelemetryUtil;
import org.jetbrains.annotations.NotNull;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
Expand All @@ -22,7 +21,7 @@ public class SentryOpenTelemetryAgentWithoutAutoInitConfiguration {
return options -> {
SentryIntegrationPackageStorage.getInstance()
.addIntegration("SpringBoot3OpenTelemetryAgentWithoutAutoInit");
OpenTelemetryUtil.applyOpenTelemetryOptions(options, SentryOpenTelemetryMode.AGENT);
options.setOpenTelemetryMode(SentryOpenTelemetryMode.AGENT);
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import io.sentry.SentryIntegrationPackageStorage;
import io.sentry.SentryOpenTelemetryMode;
import io.sentry.SentryOptions;
import io.sentry.opentelemetry.OpenTelemetryUtil;
import io.sentry.opentelemetry.OtelSpanFactory;
import io.sentry.opentelemetry.SentryAutoConfigurationCustomizerProvider;
import org.jetbrains.annotations.NotNull;
Expand All @@ -33,8 +32,7 @@ public static ISpanFactory openTelemetrySpanFactory(OpenTelemetry openTelemetry)
SentryIntegrationPackageStorage.getInstance()
.addIntegration("SpringBoot3OpenTelemetryNoAgent");
SentryAutoConfigurationCustomizerProvider.skipInit = true;
OpenTelemetryUtil.applyOpenTelemetryOptions(
options, SentryOpenTelemetryMode.AGENTLESS_SPRING);
options.setOpenTelemetryMode(SentryOpenTelemetryMode.AGENTLESS_SPRING);
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@
import io.sentry.SentryIntegrationPackageStorage;
import io.sentry.SentryOpenTelemetryMode;
import io.sentry.SentryOptions;
import io.sentry.opentelemetry.OpenTelemetryUtil;
import org.jetbrains.annotations.NotNull;
import org.springframework.boot.autoconfigure.condition.ConditionalOnMissingBean;
import org.springframework.context.annotation.Bean;
Expand All @@ -22,7 +21,7 @@ public class SentryOpenTelemetryAgentWithoutAutoInitConfiguration {
return options -> {
SentryIntegrationPackageStorage.getInstance()
.addIntegration("SpringBootOpenTelemetryAgentWithoutAutoInit");
OpenTelemetryUtil.applyOpenTelemetryOptions(options, SentryOpenTelemetryMode.AGENT);
options.setOpenTelemetryMode(SentryOpenTelemetryMode.AGENT);
};
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
import io.sentry.SentryIntegrationPackageStorage;
import io.sentry.SentryOpenTelemetryMode;
import io.sentry.SentryOptions;
import io.sentry.opentelemetry.OpenTelemetryUtil;
import io.sentry.opentelemetry.OtelSpanFactory;
import io.sentry.opentelemetry.SentryAutoConfigurationCustomizerProvider;
import org.jetbrains.annotations.NotNull;
Expand All @@ -33,8 +32,7 @@ public static ISpanFactory openTelemetrySpanFactory(OpenTelemetry openTelemetry)
SentryIntegrationPackageStorage.getInstance()
.addIntegration("SpringBootOpenTelemetryNoAgent");
SentryAutoConfigurationCustomizerProvider.skipInit = true;
OpenTelemetryUtil.applyOpenTelemetryOptions(
options, SentryOpenTelemetryMode.AGENTLESS_SPRING);
options.setOpenTelemetryMode(SentryOpenTelemetryMode.AGENTLESS_SPRING);
};
}
}
7 changes: 6 additions & 1 deletion sentry/api/sentry.api
Original file line number Diff line number Diff line change
Expand Up @@ -2785,6 +2785,8 @@ public final class io/sentry/SentryOpenTelemetryMode : java/lang/Enum {
public static final field AGENT Lio/sentry/SentryOpenTelemetryMode;
public static final field AGENTLESS Lio/sentry/SentryOpenTelemetryMode;
public static final field AGENTLESS_SPRING Lio/sentry/SentryOpenTelemetryMode;
public static final field ALL_ORIGINS Lio/sentry/SentryOpenTelemetryMode;
public static final field AUTO Lio/sentry/SentryOpenTelemetryMode;
public static fun valueOf (Ljava/lang/String;)Lio/sentry/SentryOpenTelemetryMode;
public static fun values ()[Lio/sentry/SentryOpenTelemetryMode;
}
Expand All @@ -2797,6 +2799,7 @@ public class io/sentry/SentryOptions {
public fun addContextTag (Ljava/lang/String;)V
public fun addEventProcessor (Lio/sentry/EventProcessor;)V
public fun addIgnoredExceptionForType (Ljava/lang/Class;)V
public fun addIgnoredSpanOrigin (Ljava/lang/String;)V
public fun addInAppExclude (Ljava/lang/String;)V
public fun addInAppInclude (Ljava/lang/String;)V
public fun addIntegration (Lio/sentry/Integration;)V
Expand Down Expand Up @@ -2854,6 +2857,7 @@ public class io/sentry/SentryOptions {
public fun getMaxSpans ()I
public fun getMaxTraceFileSize ()J
public fun getModulesLoader ()Lio/sentry/internal/modules/IModulesLoader;
public fun getOpenTelemetryMode ()Lio/sentry/SentryOpenTelemetryMode;
public fun getOptionsObservers ()Ljava/util/List;
public fun getOutboxPath ()Ljava/lang/String;
public fun getPerformanceCollectors ()Ljava/util/List;
Expand Down Expand Up @@ -2979,6 +2983,7 @@ public class io/sentry/SentryOptions {
public fun setMaxSpans (I)V
public fun setMaxTraceFileSize (J)V
public fun setModulesLoader (Lio/sentry/internal/modules/IModulesLoader;)V
public fun setOpenTelemetryMode (Lio/sentry/SentryOpenTelemetryMode;)V
public fun setPrintUncaughtStackTrace (Z)V
public fun setProfilesSampleRate (Ljava/lang/Double;)V
public fun setProfilesSampler (Lio/sentry/SentryOptions$ProfilesSamplerCallback;)V
Expand Down Expand Up @@ -4213,7 +4218,7 @@ public abstract interface class io/sentry/internal/viewhierarchy/ViewHierarchyEx

public final class io/sentry/opentelemetry/OpenTelemetryUtil {
public fun <init> ()V
public static fun applyOpenTelemetryOptions (Lio/sentry/SentryOptions;Lio/sentry/SentryOpenTelemetryMode;)V
public static fun applyIgnoredSpanOrigins (Lio/sentry/SentryOptions;Lio/sentry/util/LoadClass;)V
}

public final class io/sentry/profilemeasurements/ProfileMeasurement : io/sentry/JsonSerializable, io/sentry/JsonUnknown {
Expand Down
3 changes: 3 additions & 0 deletions sentry/src/main/java/io/sentry/Sentry.java
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
import io.sentry.internal.modules.ManifestModulesLoader;
import io.sentry.internal.modules.NoOpModulesLoader;
import io.sentry.internal.modules.ResourcesModulesLoader;
import io.sentry.opentelemetry.OpenTelemetryUtil;
import io.sentry.protocol.SentryId;
import io.sentry.protocol.User;
import io.sentry.transport.NoOpEnvelopeCache;
Expand Down Expand Up @@ -490,6 +491,8 @@ private static void initConfigurations(final @NotNull SentryOptions options) {
}
logger.log(SentryLevel.INFO, "Initializing SDK with DSN: '%s'", options.getDsn());

OpenTelemetryUtil.applyIgnoredSpanOrigins(options, new LoadClass());

// TODO: read values from conf file, Build conf or system envs
// eg release, distinctId, sentryClientName

Expand Down
23 changes: 23 additions & 0 deletions sentry/src/main/java/io/sentry/SentryOpenTelemetryMode.java
Original file line number Diff line number Diff line change
@@ -1,7 +1,30 @@
package io.sentry;

/**
* Configures the SDK to either automatically determine if OpenTelemetry is available, whether to
* use it and what way to use it in.
*/
public enum SentryOpenTelemetryMode {
/** Let the SDK figure out what mode OpenTelemetry is in and whether to even use OpenTelemetry */
AUTO,
/**
* For now this only means no span origins will be ignored. This does however not mean, the SDK
* won't try tro use OpenTelemetry if available.
*
* <p>Due to some parts of the SDK being initialized before any config mechanism is available, we
* cannot completely disable the OpenTelemetry parts with this setting.
*/
ALL_ORIGINS,
/** The `sentry-opentelemetry-agent` is used */
AGENT,
/**
* `sentry-opentelemetry-agentless` is used, meaning OpenTelemetry will be used but there is no
* auto instrumentation available.
*/
AGENTLESS,
/**
* `sentry-opentelemetry-agentless-spring-boot` is used, meaning
* `opentelemetry-spring-boot-starter` and its auto instrumentation is used.
*/
AGENTLESS_SPRING
}
28 changes: 28 additions & 0 deletions sentry/src/main/java/io/sentry/SentryOptions.java
Original file line number Diff line number Diff line change
Expand Up @@ -513,6 +513,8 @@ public class SentryOptions {

protected final @NotNull AutoClosableReentrantLock lock = new AutoClosableReentrantLock();

private @NotNull SentryOpenTelemetryMode openTelemetryMode = SentryOpenTelemetryMode.AUTO;

/**
* Adds an event processor
*
Expand Down Expand Up @@ -2193,6 +2195,13 @@ public void setIgnoredCheckIns(final @Nullable List<String> ignoredCheckIns) {
return ignoredSpanOrigins;
}

public void addIgnoredSpanOrigin(final @NotNull String origin) {
if (this.ignoredSpanOrigins == null) {
this.ignoredSpanOrigins = new ArrayList<>();
}
this.ignoredSpanOrigins.add(origin);
}

@ApiStatus.Experimental
public void setIgnoredSpanOrigins(final @Nullable List<String> ignoredSpanOrigins) {
if (ignoredSpanOrigins == null) {
Expand Down Expand Up @@ -2458,6 +2467,25 @@ public void setGlobalHubMode(final @Nullable Boolean globalHubMode) {
return globalHubMode;
}

/**
* Configures the SDK to either automatically determine if OpenTelemetry is available, whether to
* use it and what way to use it in.
*
* <p>See {@link SentryOpenTelemetryMode}
*
* <p>By default the SDK will use OpenTelemetry if available, preferring the agent. On Android
* OpenTelemetry is not used.
*
* @param openTelemetryMode the mode
*/
public void setOpenTelemetryMode(final @NotNull SentryOpenTelemetryMode openTelemetryMode) {
this.openTelemetryMode = openTelemetryMode;
}

public @NotNull SentryOpenTelemetryMode getOpenTelemetryMode() {
return openTelemetryMode;
}

/**
* Load the lazy fields. Useful to load in the background, so that results are already cached. DO
* NOT CALL THIS METHOD ON THE MAIN THREAD.
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,18 +2,49 @@

import io.sentry.SentryOpenTelemetryMode;
import io.sentry.SentryOptions;
import io.sentry.util.LoadClass;
import io.sentry.util.Platform;
import io.sentry.util.SpanUtils;
import java.util.Collections;
import java.util.List;
import org.jetbrains.annotations.ApiStatus;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

@ApiStatus.Experimental
@ApiStatus.Internal
public final class OpenTelemetryUtil {

public static void applyOpenTelemetryOptions(
final @Nullable SentryOptions options, final @NotNull SentryOpenTelemetryMode mode) {
if (options != null) {
options.setIgnoredSpanOrigins(SpanUtils.ignoredSpanOriginsForOpenTelemetry(mode));
@ApiStatus.Internal
public static void applyIgnoredSpanOrigins(
final @NotNull SentryOptions options, final @NotNull LoadClass loadClass) {
if (Platform.isJvm()) {
final @NotNull List<String> ignored = ignoredSpanOrigins(options, loadClass);
for (String origin : ignored) {
options.addIgnoredSpanOrigin(origin);
}
}
}

private static @NotNull List<String> ignoredSpanOrigins(
final @NotNull SentryOptions options, final @NotNull LoadClass loadClass) {
final @NotNull SentryOpenTelemetryMode openTelemetryMode = options.getOpenTelemetryMode();
if (SentryOpenTelemetryMode.AUTO.equals(openTelemetryMode)) {
if (loadClass.isClassAvailable(
"io.sentry.opentelemetry.agent.AgentMarker", options.getLogger())) {
return SpanUtils.ignoredSpanOriginsForOpenTelemetry(SentryOpenTelemetryMode.AGENT);
}
if (loadClass.isClassAvailable(
"io.sentry.opentelemetry.agent.AgentlessMarker", options.getLogger())) {
return SpanUtils.ignoredSpanOriginsForOpenTelemetry(SentryOpenTelemetryMode.AGENTLESS);
}
if (loadClass.isClassAvailable(
"io.sentry.opentelemetry.agent.AgentlessSpringMarker", options.getLogger())) {
return SpanUtils.ignoredSpanOriginsForOpenTelemetry(
SentryOpenTelemetryMode.AGENTLESS_SPRING);
}
} else {
return SpanUtils.ignoredSpanOriginsForOpenTelemetry(openTelemetryMode);
}

return Collections.emptyList();
}
}
Loading