From 32a74e900edf8270659202e93892f684f5fa6e3f Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Mon, 4 May 2026 10:24:57 +0200 Subject: [PATCH 1/5] make semconv version in catalog have priority over upstream --- .../kotlin/elastic-otel.java-conventions.gradle.kts | 12 ++++++++++++ gradle/libs.versions.toml | 4 ++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/buildSrc/src/main/kotlin/elastic-otel.java-conventions.gradle.kts b/buildSrc/src/main/kotlin/elastic-otel.java-conventions.gradle.kts index 35c7369b..24e8f244 100644 --- a/buildSrc/src/main/kotlin/elastic-otel.java-conventions.gradle.kts +++ b/buildSrc/src/main/kotlin/elastic-otel.java-conventions.gradle.kts @@ -19,6 +19,18 @@ repositories { //https://github.com/gradle/gradle/issues/15383 val catalog = extensions.getByType().named("catalog") + +configurations.all { + resolutionStrategy { + // Force the semconv version to be the one we explicitly set into version catalog and override + // the upstream version, hence allowing to use a different version than upstream. + force( + "io.opentelemetry.semconv:opentelemetry-semconv:${catalog.findVersion("opentelemetrySemconv").get()}", + "io.opentelemetry.semconv:opentelemetry-semconv-incubating:${catalog.findVersion("opentelemetrySemconvAlpha").get()}" + ) + } +} + dependencies { implementation(platform(catalog.findLibrary("opentelemetryInstrumentationAlphaBom").get())) diff --git a/gradle/libs.versions.toml b/gradle/libs.versions.toml index f4953536..716fb090 100644 --- a/gradle/libs.versions.toml +++ b/gradle/libs.versions.toml @@ -21,8 +21,8 @@ opentelemetryContribAlpha = "1.55.0-alpha" # updated from upstream agent with .ci/update-upstream.sh # While the semconv stable/incubating artifacts are provided as transitive dependencies, keeping # an explicit version here allows to easily override to a not-yet-released version. -opentelemetrySemconv = "1.40.0" -opentelemetrySemconvAlpha = "1.40.0-alpha" +opentelemetrySemconv = "1.41.0" +opentelemetrySemconvAlpha = "1.41.0-alpha" [libraries] From c3c2f39e42d8843912c381f03fde58b96dcb2b5e Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Mon, 4 May 2026 11:36:16 +0200 Subject: [PATCH 2/5] migreate to stable telemetry semconv --- .../java/co/elastic/otel/ElasticDistroResource.java | 6 +++--- .../smoketest/DeclarativeConfigSmokeTest.java | 4 ++-- .../src/test/java/DistroResourceAttributesTest.java | 10 +++++----- 3 files changed, 10 insertions(+), 10 deletions(-) diff --git a/custom/src/main/java/co/elastic/otel/ElasticDistroResource.java b/custom/src/main/java/co/elastic/otel/ElasticDistroResource.java index 16a6a2b4..ee915706 100644 --- a/custom/src/main/java/co/elastic/otel/ElasticDistroResource.java +++ b/custom/src/main/java/co/elastic/otel/ElasticDistroResource.java @@ -21,7 +21,7 @@ import io.opentelemetry.api.common.Attributes; import io.opentelemetry.javaagent.tooling.AgentVersion; import io.opentelemetry.sdk.resources.Resource; -import io.opentelemetry.semconv.incubating.TelemetryIncubatingAttributes; +import io.opentelemetry.semconv.TelemetryAttributes; public class ElasticDistroResource { @@ -40,9 +40,9 @@ public static Resource get() { } return Resource.create( Attributes.of( - TelemetryIncubatingAttributes.TELEMETRY_DISTRO_NAME, + TelemetryAttributes.TELEMETRY_DISTRO_NAME, "elastic", - TelemetryIncubatingAttributes.TELEMETRY_DISTRO_VERSION, + TelemetryAttributes.TELEMETRY_DISTRO_VERSION, AgentVersion.VERSION)); } } diff --git a/smoke-tests/src/test/java/com/example/javaagent/smoketest/DeclarativeConfigSmokeTest.java b/smoke-tests/src/test/java/com/example/javaagent/smoketest/DeclarativeConfigSmokeTest.java index 2d4a9c05..cb111d64 100644 --- a/smoke-tests/src/test/java/com/example/javaagent/smoketest/DeclarativeConfigSmokeTest.java +++ b/smoke-tests/src/test/java/com/example/javaagent/smoketest/DeclarativeConfigSmokeTest.java @@ -27,8 +27,8 @@ import static io.opentelemetry.semconv.incubating.OsIncubatingAttributes.OS_VERSION; import static io.opentelemetry.semconv.incubating.ProcessIncubatingAttributes.PROCESS_COMMAND_ARGS; import static io.opentelemetry.semconv.incubating.ProcessIncubatingAttributes.PROCESS_PID; -import static io.opentelemetry.semconv.incubating.TelemetryIncubatingAttributes.TELEMETRY_DISTRO_NAME; -import static io.opentelemetry.semconv.incubating.TelemetryIncubatingAttributes.TELEMETRY_DISTRO_VERSION; +import static io.opentelemetry.semconv.TelemetryAttributes.TELEMETRY_DISTRO_NAME; +import static io.opentelemetry.semconv.TelemetryAttributes.TELEMETRY_DISTRO_VERSION; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.tuple; diff --git a/testing/integration-tests/agent-internals/src/test/java/DistroResourceAttributesTest.java b/testing/integration-tests/agent-internals/src/test/java/DistroResourceAttributesTest.java index fe1173b2..3ae098a0 100644 --- a/testing/integration-tests/agent-internals/src/test/java/DistroResourceAttributesTest.java +++ b/testing/integration-tests/agent-internals/src/test/java/DistroResourceAttributesTest.java @@ -22,7 +22,7 @@ import io.opentelemetry.api.trace.Span; import io.opentelemetry.instrumentation.testing.junit.AgentInstrumentationExtension; import io.opentelemetry.sdk.resources.Resource; -import io.opentelemetry.semconv.incubating.TelemetryIncubatingAttributes; +import io.opentelemetry.semconv.TelemetryAttributes; import org.junit.jupiter.api.Test; import org.junit.jupiter.api.extension.RegisterExtension; @@ -43,16 +43,16 @@ public void checkDistroName() { if (isRunningDistro) { assertThat(resource.getAttributes()) - .containsEntry(TelemetryIncubatingAttributes.TELEMETRY_DISTRO_NAME, "elastic"); + .containsEntry(TelemetryAttributes.TELEMETRY_DISTRO_NAME, "elastic"); assertThat(resource.getAttributes()) - .containsKey(TelemetryIncubatingAttributes.TELEMETRY_DISTRO_VERSION); + .containsKey(TelemetryAttributes.TELEMETRY_DISTRO_VERSION); } else { // we are running with the vanilla agent as extension: we should not be setting the distro // name assertThat(resource.getAttributes()) - .doesNotContainKey(TelemetryIncubatingAttributes.TELEMETRY_DISTRO_NAME); + .doesNotContainKey(TelemetryAttributes.TELEMETRY_DISTRO_NAME); assertThat(resource.getAttributes()) - .doesNotContainKey(TelemetryIncubatingAttributes.TELEMETRY_DISTRO_VERSION); + .doesNotContainKey(TelemetryAttributes.TELEMETRY_DISTRO_VERSION); } } } From c136ebe65a952da1155222b81f7f342426415686 Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Mon, 4 May 2026 11:47:20 +0200 Subject: [PATCH 3/5] deployment.environment.name is now stable --- ...icAutoConfigurationCustomizerProvider.java | 9 +++-- .../otel/dynamicconfig/CentralConfig.java | 5 ++- .../dynamicconfig/internal/OpampManager.java | 4 +- .../java/co/elastic/otel/SemconvTest.java | 37 ------------------- 4 files changed, 12 insertions(+), 43 deletions(-) delete mode 100644 custom/src/test/java/co/elastic/otel/SemconvTest.java diff --git a/custom/src/main/java/co/elastic/otel/ElasticAutoConfigurationCustomizerProvider.java b/custom/src/main/java/co/elastic/otel/ElasticAutoConfigurationCustomizerProvider.java index 874e119e..4e44e4f4 100644 --- a/custom/src/main/java/co/elastic/otel/ElasticAutoConfigurationCustomizerProvider.java +++ b/custom/src/main/java/co/elastic/otel/ElasticAutoConfigurationCustomizerProvider.java @@ -30,12 +30,15 @@ import io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizerProvider; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.resources.Resource; +import io.opentelemetry.semconv.DeploymentAttributes; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.function.BiFunction; +import static io.opentelemetry.semconv.DeploymentAttributes.DEPLOYMENT_ENVIRONMENT_NAME; + @AutoService(AutoConfigurationCustomizerProvider.class) public class ElasticAutoConfigurationCustomizerProvider implements AutoConfigurationCustomizerProvider { @@ -59,8 +62,6 @@ public class ElasticAutoConfigurationCustomizerProvider private static final AttributeKey DEPLOYMENT_LEGACY = AttributeKey.stringKey("deployment.environment"); - private static final AttributeKey DEPLOYMENT = - AttributeKey.stringKey("deployment.environment.name"); private static final String OTEL_JAVAAGENT_EXPERIMENTAL_INDY = "otel.javaagent.experimental.indy"; @Override @@ -118,8 +119,8 @@ static BiFunction resourceProviders() { // duplicate deprecated deployment.environment to deployment.environment.name as a convenience String deploymentLegacy = resource.getAttribute(DEPLOYMENT_LEGACY); - if (deploymentLegacy != null && resource.getAttribute(DEPLOYMENT) == null) { - resource = resource.toBuilder().put(DEPLOYMENT, deploymentLegacy).build(); + if (deploymentLegacy != null && resource.getAttribute(DEPLOYMENT_ENVIRONMENT_NAME) == null) { + resource = resource.toBuilder().put(DEPLOYMENT_ENVIRONMENT_NAME, deploymentLegacy).build(); } return resource; diff --git a/custom/src/main/java/co/elastic/otel/dynamicconfig/CentralConfig.java b/custom/src/main/java/co/elastic/otel/dynamicconfig/CentralConfig.java index 25c06460..bb66b9b7 100644 --- a/custom/src/main/java/co/elastic/otel/dynamicconfig/CentralConfig.java +++ b/custom/src/main/java/co/elastic/otel/dynamicconfig/CentralConfig.java @@ -25,6 +25,7 @@ import io.opentelemetry.contrib.inferredspans.InferredSpans; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.trace.SdkTracerProviderBuilder; +import io.opentelemetry.semconv.DeploymentAttributes; import java.io.IOException; import java.text.MessageFormat; import java.time.Duration; @@ -38,6 +39,8 @@ import java.util.stream.Stream; import javax.annotation.Nullable; +import static io.opentelemetry.semconv.DeploymentAttributes.DEPLOYMENT_ENVIRONMENT_NAME; + public class CentralConfig { private static final Logger logger = Logger.getLogger(CentralConfig.class.getName()); @@ -138,7 +141,7 @@ static String getServiceName(ConfigProperties properties) { @Nullable static String getServiceEnvironment(ConfigProperties properties) { Map resourceMap = properties.getMap("otel.resource.attributes"); - String environment = resourceMap.get("deployment.environment.name"); // semconv + String environment = resourceMap.get(DEPLOYMENT_ENVIRONMENT_NAME.getKey()); if (environment != null) { return environment; } diff --git a/custom/src/main/java/co/elastic/otel/dynamicconfig/internal/OpampManager.java b/custom/src/main/java/co/elastic/otel/dynamicconfig/internal/OpampManager.java index dd25b468..d59aed12 100644 --- a/custom/src/main/java/co/elastic/otel/dynamicconfig/internal/OpampManager.java +++ b/custom/src/main/java/co/elastic/otel/dynamicconfig/internal/OpampManager.java @@ -47,6 +47,8 @@ import opamp.proto.RemoteConfigStatuses; import opamp.proto.ServerErrorResponse; +import static io.opentelemetry.semconv.DeploymentAttributes.DEPLOYMENT_ENVIRONMENT_NAME; + public final class OpampManager implements Closeable { private final Configuration configuration; private volatile OpampClient client; @@ -85,7 +87,7 @@ public void start(CentralConfigurationProcessor processor) { builder.putIdentifyingAttribute("service.name", configuration.serviceName); } if (configuration.environment != null) { - builder.putIdentifyingAttribute("deployment.environment.name", configuration.environment); + builder.putIdentifyingAttribute(DEPLOYMENT_ENVIRONMENT_NAME.getKey(), configuration.environment); } PeriodicDelay retryDelay = RetryPeriodicDelay.create(configuration.pollingInterval); builder.setRequestService(HttpRequestService.create(httpSender, pollingDelay, retryDelay)); diff --git a/custom/src/test/java/co/elastic/otel/SemconvTest.java b/custom/src/test/java/co/elastic/otel/SemconvTest.java deleted file mode 100644 index 7a4abe53..00000000 --- a/custom/src/test/java/co/elastic/otel/SemconvTest.java +++ /dev/null @@ -1,37 +0,0 @@ -/* - * Licensed to Elasticsearch B.V. under one or more contributor - * license agreements. See the NOTICE file distributed with - * this work for additional information regarding copyright - * ownership. Elasticsearch B.V. licenses this file to you under - * the Apache License, Version 2.0 (the "License"); you may - * not use this file except in compliance with the License. - * You may obtain a copy of the License at - * - * http://www.apache.org/licenses/LICENSE-2.0 - * - * Unless required by applicable law or agreed to in writing, - * software distributed under the License is distributed on an - * "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY - * KIND, either express or implied. See the License for the - * specific language governing permissions and limitations - * under the License. - */ -package co.elastic.otel; - -import static org.assertj.core.api.Assertions.assertThat; - -import io.opentelemetry.semconv.incubating.DeploymentIncubatingAttributes; -import org.junit.jupiter.api.Test; - -public class SemconvTest { - - @Test - void checkIncubatingAttributes() { - // Some of the incubating attributes are important, and we need to ensure that their definition - // do not change or breaks. Doing a basic name check is the bare minimum we can do to easily - // detect when something is getting deprecated or promoted to stable. - - assertThat(DeploymentIncubatingAttributes.DEPLOYMENT_ENVIRONMENT_NAME.getKey()) - .isEqualTo("deployment.environment.name"); - } -} From 349454b39d32ff6471cdc468581ebe315546931e Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Mon, 4 May 2026 11:53:39 +0200 Subject: [PATCH 4/5] add changelog entry --- docs/changelog/1093.yaml | 7 +++++++ 1 file changed, 7 insertions(+) create mode 100644 docs/changelog/1093.yaml diff --git a/docs/changelog/1093.yaml b/docs/changelog/1093.yaml new file mode 100644 index 00000000..639d627b --- /dev/null +++ b/docs/changelog/1093.yaml @@ -0,0 +1,7 @@ +prs: +- "1093" +type: enhancement +products: +- product: edot-java + lifecycle: ga +title: semconv 1.41.0 update From 0beab04285ca4baf11a3253962e4a42bd95e2ccd Mon Sep 17 00:00:00 2001 From: Sylvain Juge <763082+SylvainJuge@users.noreply.github.com> Date: Mon, 4 May 2026 12:00:51 +0200 Subject: [PATCH 5/5] spotless --- .../otel/ElasticAutoConfigurationCustomizerProvider.java | 5 ++--- .../java/co/elastic/otel/dynamicconfig/CentralConfig.java | 5 ++--- .../elastic/otel/dynamicconfig/internal/OpampManager.java | 7 ++++--- .../javaagent/smoketest/DeclarativeConfigSmokeTest.java | 4 ++-- 4 files changed, 10 insertions(+), 11 deletions(-) diff --git a/custom/src/main/java/co/elastic/otel/ElasticAutoConfigurationCustomizerProvider.java b/custom/src/main/java/co/elastic/otel/ElasticAutoConfigurationCustomizerProvider.java index 4e44e4f4..18faee3c 100644 --- a/custom/src/main/java/co/elastic/otel/ElasticAutoConfigurationCustomizerProvider.java +++ b/custom/src/main/java/co/elastic/otel/ElasticAutoConfigurationCustomizerProvider.java @@ -18,6 +18,8 @@ */ package co.elastic.otel; +import static io.opentelemetry.semconv.DeploymentAttributes.DEPLOYMENT_ENVIRONMENT_NAME; + import co.elastic.otel.config.ConfigLoggingAgentListener; import co.elastic.otel.dynamicconfig.BlockableLogRecordExporter; import co.elastic.otel.dynamicconfig.BlockableMetricExporter; @@ -30,15 +32,12 @@ import io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizerProvider; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.resources.Resource; -import io.opentelemetry.semconv.DeploymentAttributes; import java.util.HashMap; import java.util.HashSet; import java.util.Map; import java.util.Set; import java.util.function.BiFunction; -import static io.opentelemetry.semconv.DeploymentAttributes.DEPLOYMENT_ENVIRONMENT_NAME; - @AutoService(AutoConfigurationCustomizerProvider.class) public class ElasticAutoConfigurationCustomizerProvider implements AutoConfigurationCustomizerProvider { diff --git a/custom/src/main/java/co/elastic/otel/dynamicconfig/CentralConfig.java b/custom/src/main/java/co/elastic/otel/dynamicconfig/CentralConfig.java index bb66b9b7..02233a81 100644 --- a/custom/src/main/java/co/elastic/otel/dynamicconfig/CentralConfig.java +++ b/custom/src/main/java/co/elastic/otel/dynamicconfig/CentralConfig.java @@ -18,6 +18,8 @@ */ package co.elastic.otel.dynamicconfig; +import static io.opentelemetry.semconv.DeploymentAttributes.DEPLOYMENT_ENVIRONMENT_NAME; + import co.elastic.otel.compositesampling.DynamicCompositeParentBasedTraceIdRatioBasedSampler; import co.elastic.otel.config.ConfigLoggingAgentListener; import co.elastic.otel.dynamicconfig.internal.OpampManager; @@ -25,7 +27,6 @@ import io.opentelemetry.contrib.inferredspans.InferredSpans; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.trace.SdkTracerProviderBuilder; -import io.opentelemetry.semconv.DeploymentAttributes; import java.io.IOException; import java.text.MessageFormat; import java.time.Duration; @@ -39,8 +40,6 @@ import java.util.stream.Stream; import javax.annotation.Nullable; -import static io.opentelemetry.semconv.DeploymentAttributes.DEPLOYMENT_ENVIRONMENT_NAME; - public class CentralConfig { private static final Logger logger = Logger.getLogger(CentralConfig.class.getName()); diff --git a/custom/src/main/java/co/elastic/otel/dynamicconfig/internal/OpampManager.java b/custom/src/main/java/co/elastic/otel/dynamicconfig/internal/OpampManager.java index d59aed12..52a7e020 100644 --- a/custom/src/main/java/co/elastic/otel/dynamicconfig/internal/OpampManager.java +++ b/custom/src/main/java/co/elastic/otel/dynamicconfig/internal/OpampManager.java @@ -18,6 +18,8 @@ */ package co.elastic.otel.dynamicconfig.internal; +import static io.opentelemetry.semconv.DeploymentAttributes.DEPLOYMENT_ENVIRONMENT_NAME; + import com.dslplatform.json.DslJson; import com.dslplatform.json.JsonReader; import com.dslplatform.json.MapConverter; @@ -47,8 +49,6 @@ import opamp.proto.RemoteConfigStatuses; import opamp.proto.ServerErrorResponse; -import static io.opentelemetry.semconv.DeploymentAttributes.DEPLOYMENT_ENVIRONMENT_NAME; - public final class OpampManager implements Closeable { private final Configuration configuration; private volatile OpampClient client; @@ -87,7 +87,8 @@ public void start(CentralConfigurationProcessor processor) { builder.putIdentifyingAttribute("service.name", configuration.serviceName); } if (configuration.environment != null) { - builder.putIdentifyingAttribute(DEPLOYMENT_ENVIRONMENT_NAME.getKey(), configuration.environment); + builder.putIdentifyingAttribute( + DEPLOYMENT_ENVIRONMENT_NAME.getKey(), configuration.environment); } PeriodicDelay retryDelay = RetryPeriodicDelay.create(configuration.pollingInterval); builder.setRequestService(HttpRequestService.create(httpSender, pollingDelay, retryDelay)); diff --git a/smoke-tests/src/test/java/com/example/javaagent/smoketest/DeclarativeConfigSmokeTest.java b/smoke-tests/src/test/java/com/example/javaagent/smoketest/DeclarativeConfigSmokeTest.java index cb111d64..601db1ab 100644 --- a/smoke-tests/src/test/java/com/example/javaagent/smoketest/DeclarativeConfigSmokeTest.java +++ b/smoke-tests/src/test/java/com/example/javaagent/smoketest/DeclarativeConfigSmokeTest.java @@ -20,6 +20,8 @@ import static io.opentelemetry.semconv.ServiceAttributes.SERVICE_INSTANCE_ID; import static io.opentelemetry.semconv.ServiceAttributes.SERVICE_NAME; +import static io.opentelemetry.semconv.TelemetryAttributes.TELEMETRY_DISTRO_NAME; +import static io.opentelemetry.semconv.TelemetryAttributes.TELEMETRY_DISTRO_VERSION; import static io.opentelemetry.semconv.incubating.ContainerIncubatingAttributes.CONTAINER_ID; import static io.opentelemetry.semconv.incubating.HostIncubatingAttributes.HOST_ARCH; import static io.opentelemetry.semconv.incubating.HostIncubatingAttributes.HOST_NAME; @@ -27,8 +29,6 @@ import static io.opentelemetry.semconv.incubating.OsIncubatingAttributes.OS_VERSION; import static io.opentelemetry.semconv.incubating.ProcessIncubatingAttributes.PROCESS_COMMAND_ARGS; import static io.opentelemetry.semconv.incubating.ProcessIncubatingAttributes.PROCESS_PID; -import static io.opentelemetry.semconv.TelemetryAttributes.TELEMETRY_DISTRO_NAME; -import static io.opentelemetry.semconv.TelemetryAttributes.TELEMETRY_DISTRO_VERSION; import static org.assertj.core.api.Assertions.assertThat; import static org.assertj.core.api.Assertions.tuple;