diff --git a/CHANGELOG.md b/CHANGELOG.md index ef77be1743a..7ee1734f3c5 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -11,6 +11,15 @@ - Enable the Logs feature in your `SentryOptions` or with the `io.sentry.logs.enabled` manifest option and the SDK will automatically send logcat logs to Sentry, if the Sentry Android Gradle plugin is applied. - To set the logcat level check the [Logcat integration documentation](https://docs.sentry.io/platforms/android/integrations/logcat/#configure). +### Dependencies + +- Bump OpenTelemetry ([#4532](https://github.com/getsentry/sentry-java/pull/4532)) + - `opentelemetry-sdk` to `1.51.0` + - `opentelemetry-instrumentation` to `2.17.0` + - `opentelemetry-javaagent` to `2.17.0` + - `opentelemetry-semconv` to `1.34.0` + - We are now configuring OpenTelemetry to still behave the same way it did before for span names it generates in GraphQL auto instrumentation ([#4537](https://github.com/getsentry/sentry-java/pull/4537)) + ## 8.16.1-alpha.2 ### Fixes diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 1e72c3db711..7ff788acf69 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -19,11 +19,12 @@ nopen = "1.0.1" # see https://www.jetbrains.com/help/kotlin-multiplatform-dev/compose-compatibility-and-versioning.html#kotlin-compatibility # see https://developer.android.com/jetpack/androidx/releases/compose-kotlin okhttp = "4.9.2" -otel = "1.44.1" -otelInstrumentation = "2.10.0" -otelInstrumentationAlpha = "2.10.0-alpha" +otel = "1.51.0" +otelInstrumentation = "2.17.0" +otelInstrumentationAlpha = "2.17.0-alpha" # check https://github.com/open-telemetry/opentelemetry-java-instrumentation/blob/main/dependencyManagement/build.gradle.kts#L49 for release version above to find a compatible version -otelSemanticConventions = "1.28.0-alpha" +otelSemanticConventions = "1.34.0" +otelSemanticConventionsAlpha = "1.34.0-alpha" retrofit = "2.9.0" slf4j = "1.7.30" springboot2 = "2.7.18" @@ -110,7 +111,7 @@ otel-javaagent = { module = "io.opentelemetry.javaagent:opentelemetry-javaagent" otel-javaagent-tooling = { module = "io.opentelemetry.javaagent:opentelemetry-javaagent-tooling", version.ref = "otelInstrumentationAlpha" } otel-javaagent-extension-api = { module = "io.opentelemetry.javaagent:opentelemetry-javaagent-extension-api", version.ref = "otelInstrumentationAlpha" } otel-semconv = { module = "io.opentelemetry.semconv:opentelemetry-semconv", version.ref = "otelSemanticConventions" } -otel-semconv-incubating = { module = "io.opentelemetry.semconv:opentelemetry-semconv-incubating", version.ref = "otelSemanticConventions" } +otel-semconv-incubating = { module = "io.opentelemetry.semconv:opentelemetry-semconv-incubating", version.ref = "otelSemanticConventionsAlpha" } p6spy = { module = "p6spy:p6spy", version = "3.9.1" } quartz = { module = "org.quartz-scheduler:quartz", version = "2.3.0" } reactor-core = { module = "io.projectreactor:reactor-core", version = "3.5.3" } diff --git a/sentry-opentelemetry/sentry-opentelemetry-agentcustomization/src/main/java/io/sentry/opentelemetry/SentryAutoConfigurationCustomizerProvider.java b/sentry-opentelemetry/sentry-opentelemetry-agentcustomization/src/main/java/io/sentry/opentelemetry/SentryAutoConfigurationCustomizerProvider.java index e1902f1bed7..59801643678 100644 --- a/sentry-opentelemetry/sentry-opentelemetry-agentcustomization/src/main/java/io/sentry/opentelemetry/SentryAutoConfigurationCustomizerProvider.java +++ b/sentry-opentelemetry/sentry-opentelemetry-agentcustomization/src/main/java/io/sentry/opentelemetry/SentryAutoConfigurationCustomizerProvider.java @@ -14,17 +14,23 @@ import io.sentry.protocol.SentryPackage; import java.util.HashMap; import java.util.Map; +import java.util.logging.Level; +import java.util.logging.Logger; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; public final class SentryAutoConfigurationCustomizerProvider implements AutoConfigurationCustomizerProvider { + private static final Logger logger = + Logger.getLogger(SentryAutoConfigurationCustomizerProvider.class.getName()); + public static volatile boolean skipInit = false; @Override public void customize(AutoConfigurationCustomizer autoConfiguration) { ensureSentryOtelStorageIsInitialized(); + customizeOpenTelemetryDefaults(); final @Nullable ManifestVersionReader.VersionInfoHolder versionInfoHolder = ManifestVersionReader.getInstance().readOpenTelemetryVersion(); @@ -63,6 +69,18 @@ private static void ensureSentryOtelStorageIsInitialized() { Sentry.getGlobalScope(); } + private void customizeOpenTelemetryDefaults() { + try { + if (System.getProperty("otel.instrumentation.graphql.add-operation-name-to-span-name.enabled") + == null) { + System.setProperty( + "otel.instrumentation.graphql.add-operation-name-to-span-name.enabled", "true"); + } + } catch (Exception e) { + logger.log(Level.WARNING, "Unable to change OpenTelemetry defaults for use with Sentry.", e); + } + } + private boolean isSentryAutoInitEnabled() { if (skipInit) { return false; diff --git a/sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/OpenTelemetryAttributesExtractor.java b/sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/OpenTelemetryAttributesExtractor.java index 7d4db373df8..87088ae2377 100644 --- a/sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/OpenTelemetryAttributesExtractor.java +++ b/sentry-opentelemetry/sentry-opentelemetry-core/src/main/java/io/sentry/opentelemetry/OpenTelemetryAttributesExtractor.java @@ -105,7 +105,6 @@ private static Map collectHeaders( return headers; } - @SuppressWarnings("deprecation") public @Nullable String extractUrl( final @NotNull Attributes attributes, final @NotNull SentryOptions options) { final @Nullable String urlFull = attributes.get(UrlAttributes.URL_FULL); @@ -113,12 +112,6 @@ private static Map collectHeaders( return urlFull; } - final @Nullable String deprecatedUrl = - attributes.get(io.opentelemetry.semconv.SemanticAttributes.HTTP_URL); - if (deprecatedUrl != null) { - return deprecatedUrl; - } - final String urlString = buildUrlString(attributes, options); if (!urlString.isEmpty()) { return urlString; diff --git a/sentry-opentelemetry/sentry-opentelemetry-core/src/test/kotlin/OpenTelemetryAttributesExtractorTest.kt b/sentry-opentelemetry/sentry-opentelemetry-core/src/test/kotlin/OpenTelemetryAttributesExtractorTest.kt index 42f6f515069..5cc37d80f9c 100644 --- a/sentry-opentelemetry/sentry-opentelemetry-core/src/test/kotlin/OpenTelemetryAttributesExtractorTest.kt +++ b/sentry-opentelemetry/sentry-opentelemetry-core/src/test/kotlin/OpenTelemetryAttributesExtractorTest.kt @@ -2,14 +2,15 @@ package io.sentry.opentelemetry import io.opentelemetry.api.common.AttributeKey import io.opentelemetry.sdk.internal.AttributesMap +import io.opentelemetry.sdk.trace.SpanLimits import io.opentelemetry.sdk.trace.data.SpanData import io.opentelemetry.semconv.HttpAttributes -import io.opentelemetry.semconv.SemanticAttributes import io.opentelemetry.semconv.ServerAttributes import io.opentelemetry.semconv.UrlAttributes import io.sentry.Scope import io.sentry.SentryOptions import io.sentry.protocol.Request +import java.util.UUID import kotlin.test.Test import kotlin.test.assertEquals import kotlin.test.assertFalse @@ -21,7 +22,7 @@ import org.mockito.kotlin.whenever class OpenTelemetryAttributesExtractorTest { private class Fixture { val spanData = mock() - val attributes = AttributesMap.create(100, 100) + val attributes = AttributesMap.create(100, SpanLimits.getDefault().maxAttributeValueLength) val options = SentryOptions.empty() val scope = Scope(options) @@ -195,15 +196,6 @@ class OpenTelemetryAttributesExtractorTest { assertEquals("https://sentry.io/some/path", url) } - @Test - fun `returns deprecated URL if present`() { - givenAttributes(mapOf(SemanticAttributes.HTTP_URL to "https://sentry.io/some/path")) - - val url = whenExtractingUrl() - - assertEquals("https://sentry.io/some/path", url) - } - @Test fun `returns reconstructed URL if attributes present`() { givenAttributes( @@ -293,19 +285,30 @@ class OpenTelemetryAttributesExtractorTest { @Test fun `sets server request headers based on OTel attributes and merges list of values`() { - givenAttributes( + val elements = + "sentry-environment=production,sentry-public_key=502f25099c204a2fbf4cb16edc5975d1,sentry-sample_rate=1,sentry-sampled=true,sentry-trace_id=df71f5972f754b4c85af13ff5c07017d" + val listOf = listOf(elements, "another-baggage=abc,more=def") + val pairs = AttributeKey.stringArrayKey("http.request.header.baggage") to listOf + val map = mapOf( HttpAttributes.HTTP_REQUEST_METHOD to "GET", - AttributeKey.stringArrayKey("http.request.header.baggage") to - listOf( - "sentry-environment=production,sentry-public_key=502f25099c204a2fbf4cb16edc5975d1,sentry-sample_rate=1,sentry-sampled=true,sentry-trace_id=df71f5972f754b4c85af13ff5c07017d", - "another-baggage=abc,more=def", - ), + pairs, AttributeKey.stringArrayKey("http.request.header.sentry-trace") to listOf("f9118105af4a2d42b4124532cd176588-4542d085bb0b4de5"), - AttributeKey.stringArrayKey("http.response.header.some-header") to listOf("some-value"), + AttributeKey.stringArrayKey("http.response.header.some-header") to + listOf( + "some-value" + + "__" + + UUID.randomUUID().toString() + + "__" + + UUID.randomUUID().toString() + + "__" + + UUID.randomUUID().toString() + + "__" + + UUID.randomUUID().toString() + ), ) - ) + givenAttributes(map) whenExtractingAttributes() diff --git a/sentry-opentelemetry/sentry-opentelemetry-core/src/test/kotlin/OtelInternalSpanDetectionUtilTest.kt b/sentry-opentelemetry/sentry-opentelemetry-core/src/test/kotlin/OtelInternalSpanDetectionUtilTest.kt index a67eeb33e81..bc453be6c1a 100644 --- a/sentry-opentelemetry/sentry-opentelemetry-core/src/test/kotlin/OtelInternalSpanDetectionUtilTest.kt +++ b/sentry-opentelemetry/sentry-opentelemetry-core/src/test/kotlin/OtelInternalSpanDetectionUtilTest.kt @@ -4,7 +4,6 @@ import io.opentelemetry.api.common.AttributeKey import io.opentelemetry.api.trace.SpanKind import io.opentelemetry.sdk.internal.AttributesMap import io.opentelemetry.semconv.HttpAttributes -import io.opentelemetry.semconv.SemanticAttributes import io.opentelemetry.semconv.ServerAttributes import io.opentelemetry.semconv.UrlAttributes import io.sentry.IScopes @@ -56,15 +55,6 @@ class OtelInternalSpanDetectionUtilTest { thenRequestIsConsideredInternal() } - @Test - fun `detects deprecated url as internal (span kind client)`() { - givenDsn("https://publicKey:secretKey@io.sentry:8081/path/id?sample.rate=0.1") - givenSpanKind(SpanKind.CLIENT) - givenAttributes(mapOf(SemanticAttributes.HTTP_URL to "https://io.sentry:8081")) - - thenRequestIsConsideredInternal() - } - @Test fun `detects split url as internal (span kind internal)`() { givenDsn("https://publicKey:secretKey@io.sentry:8081/path/id?sample.rate=0.1") @@ -92,15 +82,6 @@ class OtelInternalSpanDetectionUtilTest { thenRequestIsConsideredInternal() } - @Test - fun `detects deprecated url as internal (span kind internal)`() { - givenDsn("https://publicKey:secretKey@io.sentry:8081/path/id?sample.rate=0.1") - givenSpanKind(SpanKind.INTERNAL) - givenAttributes(mapOf(SemanticAttributes.HTTP_URL to "https://io.sentry:8081")) - - thenRequestIsConsideredInternal() - } - @Test fun `does not detect full url as internal (span kind server)`() { givenDsn("https://publicKey:secretKey@io.sentry:8081/path/id?sample.rate=0.1")