From 35c344580200206dad39c6f2cd8720c46436c4fd Mon Sep 17 00:00:00 2001 From: Alexander Dinauer Date: Mon, 23 Mar 2026 12:03:38 +0100 Subject: [PATCH 1/5] build(opentelemetry): Bump OpenTelemetry dependencies Update OpenTelemetry core, instrumentation, and semantic conventions\nversions in the shared version catalog.\n\nThis keeps sentry-java aligned with newer OTel releases used by the\nopentelemetry modules and samples.\n\nCo-Authored-By: Claude --- gradle/libs.versions.toml | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index 7b53258a5a..60be4fd2c0 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -22,12 +22,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.57.0" -otelInstrumentation = "2.23.0" -otelInstrumentationAlpha = "2.23.0-alpha" +otel = "1.60.1" +otelInstrumentation = "2.26.0" +otelInstrumentationAlpha = "2.26.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.37.0" -otelSemanticConventionsAlpha = "1.37.0-alpha" +otelSemanticConventions = "1.40.0" +otelSemanticConventionsAlpha = "1.40.0-alpha" retrofit = "2.9.0" slf4j = "1.7.30" springboot2 = "2.7.18" From 2905b10f39e5d383393f536a782d0aee6819bba2 Mon Sep 17 00:00:00 2001 From: Alexander Dinauer Date: Mon, 23 Mar 2026 12:30:27 +0100 Subject: [PATCH 2/5] changelog --- CHANGELOG.md | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index 57d640f385..389848665e 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -19,6 +19,10 @@ } ``` +### Dependencies + +- Bump OpenTelemetry dependencies to 1.60.1 / 2.26.0 / 1.40.0 ([#5225](https://github.com/getsentry/sentry-java/pull/5225)) + ## 8.36.0 ### Features From ca25f9bf527f5be7738dd4fe0fa37bf1083785b0 Mon Sep 17 00:00:00 2001 From: Alexander Dinauer Date: Mon, 23 Mar 2026 12:33:25 +0100 Subject: [PATCH 3/5] docs(changelog): Clarify OpenTelemetry bump versions Align the OpenTelemetry changelog entry with prior dependency bump style\nby listing each artifact and including previous versions for context.\n\nThis makes the upgrade scope easier to review and mirrors the detail\nlevel used in earlier OpenTelemetry changelog entries.\n\nCo-Authored-By: Claude --- CHANGELOG.md | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index 389848665e..58d20127fb 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -21,7 +21,12 @@ ### Dependencies -- Bump OpenTelemetry dependencies to 1.60.1 / 2.26.0 / 1.40.0 ([#5225](https://github.com/getsentry/sentry-java/pull/5225)) +- Bump OpenTelemetry ([#5225](https://github.com/getsentry/sentry-java/pull/5225)) + - `opentelemetry` to `1.60.1` (was `1.57.0`) + - `opentelemetry-instrumentation` to `2.26.0` (was `2.23.0`) + - `opentelemetry-instrumentation-alpha` to `2.26.0-alpha` (was `2.23.0-alpha`) + - `opentelemetry-semconv` to `1.40.0` (was `1.37.0`) + - `opentelemetry-semconv-alpha` to `1.40.0-alpha` (was `1.37.0-alpha`) ## 8.36.0 From 0702e7891d6187377823b2b1e5467fa07529b272 Mon Sep 17 00:00:00 2001 From: Alexander Dinauer Date: Mon, 23 Mar 2026 12:35:39 +0100 Subject: [PATCH 4/5] ci(e2e): Enable Spring Boot 4 no-agent system tests Enable the spring-boot-4 opentelemetry-noagent sample in backend system-test matrix and spring-boot-4 workflow. This turns the previously commented-out no-agent scenario into an active CI check so regressions are caught automatically. Co-Authored-By: Claude --- .github/workflows/spring-boot-4-matrix.yml | 15 +++++++-------- .github/workflows/system-tests-backend.yml | 6 +++--- 2 files changed, 10 insertions(+), 11 deletions(-) diff --git a/.github/workflows/spring-boot-4-matrix.yml b/.github/workflows/spring-boot-4-matrix.yml index c82113828c..b436a7f31e 100644 --- a/.github/workflows/spring-boot-4-matrix.yml +++ b/.github/workflows/spring-boot-4-matrix.yml @@ -132,14 +132,13 @@ jobs: --auto-init "false" \ --build "true" -# needs a fix in opentelemetry-spring-boot-starter -# - name: Run sentry-samples-spring-boot-4-opentelemetry-noagent -# run: | -# python3 test/system-test-runner.py test \ -# --module "sentry-samples-spring-boot-4-opentelemetry-noagent" \ -# --agent false \ -# --auto-init "true" \ -# --build "true" + - name: Run sentry-samples-spring-boot-4-opentelemetry-noagent + run: | + python3 test/system-test-runner.py test \ + --module "sentry-samples-spring-boot-4-opentelemetry-noagent" \ + --agent false \ + --auto-init "true" \ + --build "true" - name: Run sentry-samples-spring-7 run: | diff --git a/.github/workflows/system-tests-backend.yml b/.github/workflows/system-tests-backend.yml index 4f7929343c..f57f81aaf8 100644 --- a/.github/workflows/system-tests-backend.yml +++ b/.github/workflows/system-tests-backend.yml @@ -72,9 +72,9 @@ jobs: - sample: "sentry-samples-spring-boot-4-webflux" agent: "false" agent-auto-init: "true" -# - sample: "sentry-samples-spring-boot-4-opentelemetry-noagent" -# agent: "false" -# agent-auto-init: "true" + - sample: "sentry-samples-spring-boot-4-opentelemetry-noagent" + agent: "false" + agent-auto-init: "true" - sample: "sentry-samples-spring-boot-4-opentelemetry" agent: "true" agent-auto-init: "true" From 3c3f390a5f820a0609ef5cc9b3e9354274841062 Mon Sep 17 00:00:00 2001 From: Alexander Dinauer Date: Mon, 23 Mar 2026 13:19:39 +0100 Subject: [PATCH 5/5] fix(opentelemetry): Use stable Attributes API in core tests Replace test usage of sdk.internal.AttributesMap with public Attributes builders.\n\nThe OTel dependency bump removed the internal class, which broke\n:sentry-opentelemetry:sentry-opentelemetry-core:compileTestKotlin and\ntherefore the full build. Co-Authored-By: Claude --- .../OpenTelemetryAttributesExtractorTest.kt | 24 +++++++++++++++---- .../OtelInternalSpanDetectionUtilTest.kt | 21 +++++++++++++--- .../kotlin/SpanDescriptionExtractorTest.kt | 23 ++++++++++++++---- 3 files changed, 56 insertions(+), 12 deletions(-) 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 5cc37d80f9..6d37240f0b 100644 --- a/sentry-opentelemetry/sentry-opentelemetry-core/src/test/kotlin/OpenTelemetryAttributesExtractorTest.kt +++ b/sentry-opentelemetry/sentry-opentelemetry-core/src/test/kotlin/OpenTelemetryAttributesExtractorTest.kt @@ -1,8 +1,7 @@ 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.api.common.Attributes import io.opentelemetry.sdk.trace.data.SpanData import io.opentelemetry.semconv.HttpAttributes import io.opentelemetry.semconv.ServerAttributes @@ -22,12 +21,12 @@ import org.mockito.kotlin.whenever class OpenTelemetryAttributesExtractorTest { private class Fixture { val spanData = mock() - val attributes = AttributesMap.create(100, SpanLimits.getDefault().maxAttributeValueLength) + var attributes: Attributes = Attributes.empty() val options = SentryOptions.empty() val scope = Scope(options) init { - whenever(spanData.attributes).thenReturn(attributes) + whenever(spanData.attributes).thenAnswer { attributes } } } @@ -346,7 +345,22 @@ class OpenTelemetryAttributesExtractorTest { } private fun givenAttributes(map: Map, Any>) { - map.forEach { k, v -> fixture.attributes.put(k, v) } + fixture.attributes = buildAttributes(map) + } + + private fun buildAttributes(map: Map, Any>): Attributes { + val builder = Attributes.builder() + map.forEach { (key, value) -> putAttribute(builder, key, value) } + return builder.build() + } + + @Suppress("UNCHECKED_CAST") + private fun putAttribute( + builder: io.opentelemetry.api.common.AttributesBuilder, + key: AttributeKey, + value: Any, + ) { + builder.put(key as AttributeKey, value) } private fun 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 bc453be6c1..63a6c77c52 100644 --- a/sentry-opentelemetry/sentry-opentelemetry-core/src/test/kotlin/OtelInternalSpanDetectionUtilTest.kt +++ b/sentry-opentelemetry/sentry-opentelemetry-core/src/test/kotlin/OtelInternalSpanDetectionUtilTest.kt @@ -1,8 +1,8 @@ package io.sentry.opentelemetry import io.opentelemetry.api.common.AttributeKey +import io.opentelemetry.api.common.Attributes import io.opentelemetry.api.trace.SpanKind -import io.opentelemetry.sdk.internal.AttributesMap import io.opentelemetry.semconv.HttpAttributes import io.opentelemetry.semconv.ServerAttributes import io.opentelemetry.semconv.UrlAttributes @@ -17,7 +17,7 @@ import org.mockito.kotlin.whenever class OtelInternalSpanDetectionUtilTest { private class Fixture { val scopes = mock() - val attributes = AttributesMap.create(100, 100) + var attributes: Attributes = Attributes.empty() val options = SentryOptions.empty() var spanKind: SpanKind = SpanKind.INTERNAL @@ -152,7 +152,22 @@ class OtelInternalSpanDetectionUtilTest { } private fun givenAttributes(map: Map, Any>) { - map.forEach { k, v -> fixture.attributes.put(k, v) } + fixture.attributes = buildAttributes(map) + } + + private fun buildAttributes(map: Map, Any>): Attributes { + val builder = Attributes.builder() + map.forEach { (key, value) -> putAttribute(builder, key, value) } + return builder.build() + } + + @Suppress("UNCHECKED_CAST") + private fun putAttribute( + builder: io.opentelemetry.api.common.AttributesBuilder, + key: AttributeKey, + value: Any, + ) { + builder.put(key as AttributeKey, value) } private fun givenDsn(dsn: String) { diff --git a/sentry-opentelemetry/sentry-opentelemetry-core/src/test/kotlin/SpanDescriptionExtractorTest.kt b/sentry-opentelemetry/sentry-opentelemetry-core/src/test/kotlin/SpanDescriptionExtractorTest.kt index af04914e27..9c5a1a352d 100644 --- a/sentry-opentelemetry/sentry-opentelemetry-core/src/test/kotlin/SpanDescriptionExtractorTest.kt +++ b/sentry-opentelemetry/sentry-opentelemetry-core/src/test/kotlin/SpanDescriptionExtractorTest.kt @@ -1,11 +1,11 @@ package io.sentry.opentelemetry import io.opentelemetry.api.common.AttributeKey +import io.opentelemetry.api.common.Attributes import io.opentelemetry.api.trace.SpanContext import io.opentelemetry.api.trace.SpanKind import io.opentelemetry.api.trace.TraceFlags import io.opentelemetry.api.trace.TraceState -import io.opentelemetry.sdk.internal.AttributesMap import io.opentelemetry.sdk.trace.data.SpanData import io.opentelemetry.semconv.HttpAttributes import io.opentelemetry.semconv.UrlAttributes @@ -22,14 +22,14 @@ class SpanDescriptionExtractorTest { private class Fixture { val sentrySpan = mock() val otelSpan = mock() - val attributes = AttributesMap.create(100, 100) + var attributes: Attributes = Attributes.empty() var parentSpanContext = SpanContext.getInvalid() var spanKind = SpanKind.INTERNAL var spanName: String? = null var spanDescription: String? = null fun setup() { - whenever(otelSpan.attributes).thenReturn(attributes) + whenever(otelSpan.attributes).thenAnswer { attributes } whenever(otelSpan.parentSpanContext).thenReturn(parentSpanContext) whenever(otelSpan.kind).thenReturn(spanKind) spanName?.let { whenever(otelSpan.name).thenReturn(it) } @@ -271,7 +271,22 @@ class SpanDescriptionExtractorTest { } private fun givenAttributes(map: Map, Any>) { - map.forEach { k, v -> fixture.attributes.put(k, v) } + fixture.attributes = buildAttributes(map) + } + + private fun buildAttributes(map: Map, Any>): Attributes { + val builder = Attributes.builder() + map.forEach { (key, value) -> putAttribute(builder, key, value) } + return builder.build() + } + + @Suppress("UNCHECKED_CAST") + private fun putAttribute( + builder: io.opentelemetry.api.common.AttributesBuilder, + key: AttributeKey, + value: Any, + ) { + builder.put(key as AttributeKey, value) } private fun whenExtractingSpanInfo(): OtelSpanInfo {