From 86c9dc6d4513d69a127028439dcae831a68e1eae Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Mon, 17 Nov 2025 17:31:57 +0100 Subject: [PATCH 01/79] add system properties bridge --- .../api/internal/ConfigPropertiesUtil.java | 64 +++++++++++++++++++ .../jdbc/OpenTelemetryDriver.java | 22 ++++--- .../internal/JdbcInstrumenterFactory.java | 10 +-- 3 files changed, 81 insertions(+), 15 deletions(-) diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java index 862cd6b13588..68aa7d99fd43 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java @@ -5,23 +5,63 @@ package io.opentelemetry.instrumentation.api.internal; +import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.api.incubator.ExtendedOpenTelemetry; +import io.opentelemetry.api.incubator.config.ConfigProvider; +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import java.util.Arrays; import java.util.List; import java.util.Locale; import java.util.stream.Collectors; import javax.annotation.Nullable; +import static io.opentelemetry.api.incubator.config.DeclarativeConfigProperties.empty; + /** * This class is internal and is hence not for public use. Its APIs are unstable and can change at * any time. */ public final class ConfigPropertiesUtil { + private static final boolean isIncubator = isIncubator(); + + private static boolean isIncubator() { + try { + Class.forName("io.opentelemetry.api.incubator.ExtendedOpenTelemetry"); + return true; + } catch (ClassNotFoundException e) { + // The incubator module is not available. + // This only happens in OpenTelemetry API instrumentation tests, where an older version of + // OpenTelemetry API is used that does not have ExtendedOpenTelemetry. + // Having the incubator module without ExtendedOpenTelemetry class should still return false + // for those tests to avoid a ClassNotFoundException. + return false; + } + } + + /** + * @deprecated use {@link #getBoolean(OpenTelemetry, boolean, String...)} instead + */ + @Deprecated public static boolean getBoolean(String propertyName, boolean defaultValue) { String strValue = getString(propertyName); return strValue == null ? defaultValue : Boolean.parseBoolean(strValue); } + /** + * Returns the boolean value of the given property name from Declarative Config if available, + * otherwise falls back to system properties and environment variables. + */ + public static boolean getBoolean( + OpenTelemetry openTelemetry, boolean defaultValue, String... propertyName) { + + DeclarativeConfigProperties node = getDeclarativeConfigNode(openTelemetry, propertyName); + if (node != null) { + return node.getBoolean(propertyName[propertyName.length - 1], defaultValue); + } + return getBoolean(toSystemProperty(propertyName), defaultValue); + } + public static int getInt(String propertyName, int defaultValue) { String strValue = getString(propertyName); if (strValue == null) { @@ -67,5 +107,29 @@ private static String toEnvVarName(String propertyName) { return propertyName.toUpperCase(Locale.ROOT).replace('-', '_').replace('.', '_'); } + @Nullable + private static DeclarativeConfigProperties getDeclarativeConfigNode( + OpenTelemetry openTelemetry, String... propertyName) { + if (isIncubator && openTelemetry instanceof ExtendedOpenTelemetry) { + ExtendedOpenTelemetry extendedOpenTelemetry = (ExtendedOpenTelemetry) openTelemetry; + ConfigProvider configProvider = extendedOpenTelemetry.getConfigProvider(); + DeclarativeConfigProperties instrumentationConfig = configProvider.getInstrumentationConfig(); + if (instrumentationConfig == null) { + return empty(); + } + DeclarativeConfigProperties node = instrumentationConfig.getStructured("java", empty()); + // last part is the leaf property + for (int i = 0; i < propertyName.length - 1; i++) { + node = node.getStructured(propertyName[i], empty()); + } + return node; + } + return null; + } + + private static String toSystemProperty(String[] propertyName) { + return String.join(".", propertyName).replace('_', '-'); + } + private ConfigPropertiesUtil() {} } diff --git a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/OpenTelemetryDriver.java b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/OpenTelemetryDriver.java index 617da2b99f03..dd8ed9c3a219 100644 --- a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/OpenTelemetryDriver.java +++ b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/OpenTelemetryDriver.java @@ -63,14 +63,16 @@ public final class OpenTelemetryDriver implements Driver { private static final AtomicBoolean REGISTERED = new AtomicBoolean(); private static final List DRIVER_CANDIDATES = new CopyOnWriteArrayList<>(); - private static final SqlCommenter sqlCommenter = - SqlCommenter.builder() - .setEnabled( - ConfigPropertiesUtil.getBoolean( - "otel.instrumentation.jdbc.experimental.sqlcommenter.enabled", - ConfigPropertiesUtil.getBoolean( - "otel.instrumentation.common.experimental.db-sqlcommenter.enabled", false))) - .build(); + private static SqlCommenter getSqlCommenter(OpenTelemetry openTelemetry) { + boolean defaultValue = + ConfigPropertiesUtil.getBoolean( + openTelemetry, false, "common", "experimental", "db_sqlcommenter", "enabled"); + return SqlCommenter.builder() + .setEnabled( + ConfigPropertiesUtil.getBoolean( + openTelemetry, defaultValue, "jdbc", "experimental", "sqlcommenter", "enabled")) + .build(); + } static { try { @@ -256,7 +258,7 @@ public Connection connect(String url, Properties info) throws SQLException { Instrumenter statementInstrumenter = JdbcInstrumenterFactory.createStatementInstrumenter(openTelemetry); - boolean captureQueryParameters = JdbcInstrumenterFactory.captureQueryParameters(); + boolean captureQueryParameters = JdbcInstrumenterFactory.captureQueryParameters(openTelemetry); Instrumenter transactionInstrumenter = JdbcInstrumenterFactory.createTransactionInstrumenter(openTelemetry); @@ -266,7 +268,7 @@ public Connection connect(String url, Properties info) throws SQLException { statementInstrumenter, transactionInstrumenter, captureQueryParameters, - sqlCommenter); + getSqlCommenter(openTelemetry)); } @Override diff --git a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/JdbcInstrumenterFactory.java b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/JdbcInstrumenterFactory.java index 9748181d713e..07c08fbd34e4 100644 --- a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/JdbcInstrumenterFactory.java +++ b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/JdbcInstrumenterFactory.java @@ -28,14 +28,14 @@ public final class JdbcInstrumenterFactory { public static final String INSTRUMENTATION_NAME = "io.opentelemetry.jdbc"; - public static boolean captureQueryParameters() { + public static boolean captureQueryParameters(OpenTelemetry openTelemetry) { return ConfigPropertiesUtil.getBoolean( - "otel.instrumentation.jdbc.experimental.capture-query-parameters", false); + openTelemetry, false, "jdbc", "experimental", "capture_query_parameters"); } public static Instrumenter createStatementInstrumenter( OpenTelemetry openTelemetry) { - return createStatementInstrumenter(openTelemetry, captureQueryParameters()); + return createStatementInstrumenter(openTelemetry, captureQueryParameters(openTelemetry)); } static Instrumenter createStatementInstrumenter( @@ -45,7 +45,7 @@ static Instrumenter createStatementInstrumenter( emptyList(), true, ConfigPropertiesUtil.getBoolean( - "otel.instrumentation.common.db-statement-sanitizer.enabled", true), + openTelemetry, true, "common", "db_statement_sanitizer", "enabled"), captureQueryParameters); } @@ -95,7 +95,7 @@ public static Instrumenter createTransactionInstrumenter( return createTransactionInstrumenter( openTelemetry, ConfigPropertiesUtil.getBoolean( - "otel.instrumentation.jdbc.experimental.transaction.enabled", false)); + openTelemetry, false, "jdbc", "experimental", "transaction", "enabled")); } public static Instrumenter createTransactionInstrumenter( From 1538cf5703675cf89dfb8551165342ef079b4eca Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Mon, 17 Nov 2025 18:04:29 +0100 Subject: [PATCH 02/79] add system properties bridge --- instrumentation-api/build.gradle.kts | 1 + .../api/internal/ConfigPropertiesUtil.java | 17 ++++++---- .../internal/ConfigPropertiesUtilTest.java | 33 +++++++++++++++++++ 3 files changed, 44 insertions(+), 7 deletions(-) diff --git a/instrumentation-api/build.gradle.kts b/instrumentation-api/build.gradle.kts index 3b798b826de2..38dfcbf8a6a5 100644 --- a/instrumentation-api/build.gradle.kts +++ b/instrumentation-api/build.gradle.kts @@ -22,6 +22,7 @@ dependencies { testImplementation("io.opentelemetry.javaagent:opentelemetry-testing-common") testImplementation("io.opentelemetry:opentelemetry-sdk-testing") testImplementation("io.opentelemetry:opentelemetry-exporter-common") + testImplementation("io.opentelemetry:opentelemetry-sdk-extension-incubator") testImplementation("org.junit-pioneer:junit-pioneer") jmhImplementation(project(":instrumentation-api-incubator")) diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java index 68aa7d99fd43..905e6e0ef706 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java @@ -5,6 +5,8 @@ package io.opentelemetry.instrumentation.api.internal; +import static io.opentelemetry.api.incubator.config.DeclarativeConfigProperties.empty; + import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.api.incubator.ExtendedOpenTelemetry; import io.opentelemetry.api.incubator.config.ConfigProvider; @@ -15,8 +17,6 @@ import java.util.stream.Collectors; import javax.annotation.Nullable; -import static io.opentelemetry.api.incubator.config.DeclarativeConfigProperties.empty; - /** * This class is internal and is hence not for public use. Its APIs are unstable and can change at * any time. @@ -40,9 +40,12 @@ private static boolean isIncubator() { } /** - * @deprecated use {@link #getBoolean(OpenTelemetry, boolean, String...)} instead + * Returns the boolean value of the given property name from system properties and environment + * variables. + * + *

It's recommended to use {@link #getBoolean(OpenTelemetry, boolean, String...)} instead to + * support Declarative Config. */ - @Deprecated public static boolean getBoolean(String propertyName, boolean defaultValue) { String strValue = getString(propertyName); return strValue == null ? defaultValue : Boolean.parseBoolean(strValue); @@ -54,7 +57,6 @@ public static boolean getBoolean(String propertyName, boolean defaultValue) { */ public static boolean getBoolean( OpenTelemetry openTelemetry, boolean defaultValue, String... propertyName) { - DeclarativeConfigProperties node = getDeclarativeConfigNode(openTelemetry, propertyName); if (node != null) { return node.getBoolean(propertyName[propertyName.length - 1], defaultValue); @@ -127,8 +129,9 @@ private static DeclarativeConfigProperties getDeclarativeConfigNode( return null; } - private static String toSystemProperty(String[] propertyName) { - return String.join(".", propertyName).replace('_', '-'); + // Visible for testing + static String toSystemProperty(String[] propertyName) { + return "otel.instrumentation." + String.join(".", propertyName).replace('_', '-'); } private ConfigPropertiesUtil() {} diff --git a/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java b/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java index 8a496322b6e0..f1ecff66ee23 100644 --- a/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java +++ b/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java @@ -7,6 +7,12 @@ import static org.assertj.core.api.Assertions.assertThat; +import io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfiguration; +import io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfigurationBuilder; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalLanguageSpecificInstrumentationModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.InstrumentationModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel; +import java.util.Collections; import org.junit.jupiter.api.Test; import org.junitpioneer.jupiter.SetEnvironmentVariable; import org.junitpioneer.jupiter.SetSystemProperty; @@ -72,4 +78,31 @@ void getBoolean_environmentVariable() { void getBoolean_none() { assertThat(ConfigPropertiesUtil.getBoolean("test.property.boolean", false)).isFalse(); } + + @Test + void getBoolean_declarativeConfig() { + assertThat( + ConfigPropertiesUtil.getBoolean( + DeclarativeConfiguration.create(model(true)), false, "foo", "bar")) + .isTrue(); + } + + private static OpenTelemetryConfigurationModel model(Object value) { + return new DeclarativeConfigurationBuilder() + .customizeModel( + new OpenTelemetryConfigurationModel() + .withFileFormat("1.0-rc.1") + .withInstrumentationDevelopment( + new InstrumentationModel() + .withJava( + new ExperimentalLanguageSpecificInstrumentationModel() + .withAdditionalProperty( + "foo", Collections.singletonMap("bar", value))))); + } + + @Test + void toSystemProperty() { + assertThat(ConfigPropertiesUtil.toSystemProperty(new String[] {"a_b", "c", "d"})) + .isEqualTo("otel.instrumentation.a-b.c.d"); + } } From b68ada40db8a95547936d3347dff03c9c0c54fb8 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Mon, 17 Nov 2025 18:37:36 +0100 Subject: [PATCH 03/79] add tests --- .../internal/ConfigPropertiesUtilTest.java | 44 ++++++++++++++----- 1 file changed, 34 insertions(+), 10 deletions(-) diff --git a/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java b/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java index f1ecff66ee23..34de9f72de2b 100644 --- a/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java +++ b/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java @@ -7,13 +7,18 @@ import static org.assertj.core.api.Assertions.assertThat; +import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfiguration; import io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfigurationBuilder; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalLanguageSpecificInstrumentationModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.InstrumentationModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel; import java.util.Collections; +import java.util.stream.Stream; import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; import org.junitpioneer.jupiter.SetEnvironmentVariable; import org.junitpioneer.jupiter.SetSystemProperty; @@ -61,30 +66,49 @@ void getInt_invalidNumber() { assertThat(ConfigPropertiesUtil.getInt("test.property.int", -1)).isEqualTo(-1); } - @SetEnvironmentVariable(key = "TEST_PROPERTY_BOOLEAN", value = "false") - @SetSystemProperty(key = "test.property.boolean", value = "true") + @SetEnvironmentVariable(key = "OTEL_INSTRUMENTATION_TEST_PROPERTY_BOOLEAN", value = "false") + @SetSystemProperty(key = "otel.instrumentation.test.property.boolean", value = "true") @Test void getBoolean_systemProperty() { - assertThat(ConfigPropertiesUtil.getBoolean("test.property.boolean", false)).isTrue(); + assertBoolean(true); } - @SetEnvironmentVariable(key = "TEST_PROPERTY_BOOLEAN", value = "true") + @SetEnvironmentVariable(key = "OTEL_INSTRUMENTATION_TEST_PROPERTY_BOOLEAN", value = "true") @Test void getBoolean_environmentVariable() { - assertThat(ConfigPropertiesUtil.getBoolean("test.property.boolean", false)).isTrue(); + assertBoolean(true); } @Test void getBoolean_none() { - assertThat(ConfigPropertiesUtil.getBoolean("test.property.boolean", false)).isFalse(); + assertBoolean(false); } - @Test - void getBoolean_declarativeConfig() { + private static void assertBoolean(boolean expected) { + assertThat(ConfigPropertiesUtil.getBoolean("otel.instrumentation.test.property.boolean", false)) + .isEqualTo(expected); + assertThat( + ConfigPropertiesUtil.getBoolean( + OpenTelemetry.noop(), false, "test", "property", "boolean")) + .isEqualTo(expected); + } + + public static Stream booleanValuesProvider() { + return Stream.of( + Arguments.of(true, true), + Arguments.of(false, false), + Arguments.of("invalid", false), + Arguments.of("true", false), // no type coercion in declarative config + Arguments.of(null, false)); + } + + @ParameterizedTest + @MethodSource("booleanValuesProvider") + void getBoolean_declarativeConfig(Object property, boolean expected) { assertThat( ConfigPropertiesUtil.getBoolean( - DeclarativeConfiguration.create(model(true)), false, "foo", "bar")) - .isTrue(); + DeclarativeConfiguration.create(model(property)), false, "foo", "bar")) + .isEqualTo(expected); } private static OpenTelemetryConfigurationModel model(Object value) { From c9e630c770a7f4af5660326f89b607d9c48e818b Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Tue, 18 Nov 2025 07:37:07 +0100 Subject: [PATCH 04/79] add list --- .../api/internal/ConfigPropertiesUtil.java | 15 ++++- .../internal/ConfigPropertiesUtilTest.java | 58 +++++++++++++++++++ .../autoconfigure/TracingRequestHandler.java | 30 +++++----- 3 files changed, 89 insertions(+), 14 deletions(-) diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java index 905e6e0ef706..b1642c4309f2 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java @@ -59,7 +59,7 @@ public static boolean getBoolean( OpenTelemetry openTelemetry, boolean defaultValue, String... propertyName) { DeclarativeConfigProperties node = getDeclarativeConfigNode(openTelemetry, propertyName); if (node != null) { - return node.getBoolean(propertyName[propertyName.length - 1], defaultValue); + return node.getBoolean(leaf(propertyName), defaultValue); } return getBoolean(toSystemProperty(propertyName), defaultValue); } @@ -98,6 +98,15 @@ public static List getList(String propertyName, List defaultValu return filterBlanksAndNulls(value.split(",")); } + public static List getList( + OpenTelemetry openTelemetry, List defaultValue, String... propertyName) { + DeclarativeConfigProperties node = getDeclarativeConfigNode(openTelemetry, propertyName); + if (node != null) { + return node.getScalarList(leaf(propertyName), String.class, defaultValue); + } + return getList(toSystemProperty(propertyName), defaultValue); + } + private static List filterBlanksAndNulls(String[] values) { return Arrays.stream(values) .map(String::trim) @@ -109,6 +118,10 @@ private static String toEnvVarName(String propertyName) { return propertyName.toUpperCase(Locale.ROOT).replace('-', '_').replace('.', '_'); } + private static String leaf(String[] propertyName) { + return propertyName[propertyName.length - 1]; + } + @Nullable private static DeclarativeConfigProperties getDeclarativeConfigNode( OpenTelemetry openTelemetry, String... propertyName) { diff --git a/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java b/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java index 34de9f72de2b..3a529be10979 100644 --- a/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java +++ b/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java @@ -129,4 +129,62 @@ void toSystemProperty() { assertThat(ConfigPropertiesUtil.toSystemProperty(new String[] {"a_b", "c", "d"})) .isEqualTo("otel.instrumentation.a-b.c.d"); } + + @SetEnvironmentVariable(key = "OTEL_INSTRUMENTATION_TEST_PROPERTY_LIST", value = "a,b,c") + @SetSystemProperty(key = "otel.instrumentation.test.property.list", value = "x,y,z") + @Test + void getList_systemProperty() { + assertList(java.util.Arrays.asList("x", "y", "z")); + } + + @SetEnvironmentVariable(key = "OTEL_INSTRUMENTATION_TEST_PROPERTY_LIST", value = "a,b,c") + @Test + void getList_environmentVariable() { + assertList(java.util.Arrays.asList("a", "b", "c")); + } + + @Test + void getList_none() { + assertList(Collections.emptyList()); + } + + private static void assertList(java.util.List expected) { + assertThat(ConfigPropertiesUtil.getList("otel.instrumentation.test.property.list", Collections.emptyList())) + .isEqualTo(expected); + assertThat( + ConfigPropertiesUtil.getList( + OpenTelemetry.noop(), Collections.emptyList(), "test", "property", "list")) + .isEqualTo(expected); + } + + public static Stream listValuesProvider() { + return Stream.of( + Arguments.of(java.util.Arrays.asList("a", "b", "c"), java.util.Arrays.asList("a", "b", "c")), + Arguments.of(java.util.Arrays.asList("single"), java.util.Arrays.asList("single")), + Arguments.of(Collections.emptyList(), Collections.emptyList()), + Arguments.of(java.util.Arrays.asList(""), Collections.emptyList()), + Arguments.of(null, Collections.emptyList())); + } + + @ParameterizedTest + @MethodSource("listValuesProvider") + void getList_declarativeConfig(java.util.List property, java.util.List expected) { + assertThat( + ConfigPropertiesUtil.getList( + DeclarativeConfiguration.create(modelForList(property)), Collections.emptyList(), "foo", "bar")) + .isEqualTo(expected); + } + + private static OpenTelemetryConfigurationModel modelForList(java.util.List value) { + return new DeclarativeConfigurationBuilder() + .customizeModel( + new OpenTelemetryConfigurationModel() + .withFileFormat("1.0-rc.1") + .withInstrumentationDevelopment( + new InstrumentationModel() + .withJava( + new ExperimentalLanguageSpecificInstrumentationModel() + .withAdditionalProperty( + "foo", Collections.singletonMap("bar", value))))); + } } diff --git a/instrumentation/aws-sdk/aws-sdk-1.11/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v1_11/autoconfigure/TracingRequestHandler.java b/instrumentation/aws-sdk/aws-sdk-1.11/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v1_11/autoconfigure/TracingRequestHandler.java index 2d92c041c0be..9916edc09c17 100644 --- a/instrumentation/aws-sdk/aws-sdk-1.11/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v1_11/autoconfigure/TracingRequestHandler.java +++ b/instrumentation/aws-sdk/aws-sdk-1.11/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v1_11/autoconfigure/TracingRequestHandler.java @@ -12,6 +12,7 @@ import com.amazonaws.Response; import com.amazonaws.handlers.RequestHandler2; import io.opentelemetry.api.GlobalOpenTelemetry; +import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.instrumentation.api.internal.ConfigPropertiesUtil; import io.opentelemetry.instrumentation.awssdk.v1_11.AwsSdkTelemetry; @@ -20,19 +21,22 @@ */ public class TracingRequestHandler extends RequestHandler2 { - private static final RequestHandler2 DELEGATE = - AwsSdkTelemetry.builder(GlobalOpenTelemetry.get()) - .setCaptureExperimentalSpanAttributes( - ConfigPropertiesUtil.getBoolean( - "otel.instrumentation.aws-sdk.experimental-span-attributes", false)) - .setMessagingReceiveInstrumentationEnabled( - ConfigPropertiesUtil.getBoolean( - "otel.instrumentation.messaging.experimental.receive-telemetry.enabled", false)) - .setCapturedHeaders( - ConfigPropertiesUtil.getList( - "otel.instrumentation.messaging.experimental.capture-headers", emptyList())) - .build() - .newRequestHandler(); + private static final RequestHandler2 DELEGATE = buildDelegate(GlobalOpenTelemetry.get()); + + private static RequestHandler2 buildDelegate(OpenTelemetry openTelemetry) { + return AwsSdkTelemetry.builder(openTelemetry) + .setCaptureExperimentalSpanAttributes( + ConfigPropertiesUtil.getBoolean( + openTelemetry, false, "aws-sdk", "experimental-span-attributes")) + .setMessagingReceiveInstrumentationEnabled( + ConfigPropertiesUtil.getBoolean( + openTelemetry, false, "messaging", "experimental", "receive-telemetry.enabled")) + .setCapturedHeaders( + ConfigPropertiesUtil.getList( + openTelemetry, emptyList(), "messaging.experimental.capture-headers")) + .build() + .newRequestHandler(); + } @Override public void beforeRequest(Request request) { From ca0249b1a23d51bc979f82922c3df34d921ccc57 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Tue, 18 Nov 2025 07:47:47 +0100 Subject: [PATCH 05/79] refactor --- .../api/internal/ConfigPropertiesUtil.java | 34 +++++++++++++------ 1 file changed, 24 insertions(+), 10 deletions(-) diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java index b1642c4309f2..c953e3a3bf74 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java @@ -14,6 +14,8 @@ import java.util.Arrays; import java.util.List; import java.util.Locale; +import java.util.function.BiFunction; +import java.util.function.Function; import java.util.stream.Collectors; import javax.annotation.Nullable; @@ -57,11 +59,11 @@ public static boolean getBoolean(String propertyName, boolean defaultValue) { */ public static boolean getBoolean( OpenTelemetry openTelemetry, boolean defaultValue, String... propertyName) { - DeclarativeConfigProperties node = getDeclarativeConfigNode(openTelemetry, propertyName); - if (node != null) { - return node.getBoolean(leaf(propertyName), defaultValue); - } - return getBoolean(toSystemProperty(propertyName), defaultValue); + return getDeclarativeConfigOrFallback( + openTelemetry, + propertyName, + (node, key) -> node.getBoolean(key, defaultValue), + (key) -> getBoolean(key, defaultValue)); } public static int getInt(String propertyName, int defaultValue) { @@ -100,11 +102,11 @@ public static List getList(String propertyName, List defaultValu public static List getList( OpenTelemetry openTelemetry, List defaultValue, String... propertyName) { - DeclarativeConfigProperties node = getDeclarativeConfigNode(openTelemetry, propertyName); - if (node != null) { - return node.getScalarList(leaf(propertyName), String.class, defaultValue); - } - return getList(toSystemProperty(propertyName), defaultValue); + return getDeclarativeConfigOrFallback( + openTelemetry, + propertyName, + (node, key) -> node.getScalarList(key, String.class, defaultValue), + (key) -> getList(key, defaultValue)); } private static List filterBlanksAndNulls(String[] values) { @@ -118,6 +120,18 @@ private static String toEnvVarName(String propertyName) { return propertyName.toUpperCase(Locale.ROOT).replace('-', '_').replace('.', '_'); } + private static T getDeclarativeConfigOrFallback( + OpenTelemetry openTelemetry, + String[] propertyName, + BiFunction getter, + Function fallback) { + DeclarativeConfigProperties node = getDeclarativeConfigNode(openTelemetry, propertyName); + if (node != null) { + return getter.apply(node, leaf(propertyName)); + } + return fallback.apply(toSystemProperty(propertyName)); + } + private static String leaf(String[] propertyName) { return propertyName[propertyName.length - 1]; } From e8238c8505e2573b5c1298dc386e64f495eefc7b Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Tue, 18 Nov 2025 08:14:22 +0100 Subject: [PATCH 06/79] refactor --- .../api/internal/ConfigPropertiesUtil.java | 15 ++++--- .../internal/ConfigPropertiesUtilTest.java | 43 ++++++++----------- 2 files changed, 27 insertions(+), 31 deletions(-) diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java index c953e3a3bf74..fce5dee2b09a 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java @@ -92,6 +92,15 @@ public static String getString(String propertyName, String defaultValue) { return strValue == null ? defaultValue : strValue; } + public static String getString( + OpenTelemetry openTelemetry, String defaultValue, String... propertyName) { + return getDeclarativeConfigOrFallback( + openTelemetry, + propertyName, + (node, key) -> node.getString(key, defaultValue), + (key) -> getString(key, defaultValue)); + } + public static List getList(String propertyName, List defaultValue) { String value = getString(propertyName); if (value == null) { @@ -127,15 +136,11 @@ private static T getDeclarativeConfigOrFallback( Function fallback) { DeclarativeConfigProperties node = getDeclarativeConfigNode(openTelemetry, propertyName); if (node != null) { - return getter.apply(node, leaf(propertyName)); + return getter.apply(node, propertyName[propertyName.length - 1]); } return fallback.apply(toSystemProperty(propertyName)); } - private static String leaf(String[] propertyName) { - return propertyName[propertyName.length - 1]; - } - @Nullable private static DeclarativeConfigProperties getDeclarativeConfigNode( OpenTelemetry openTelemetry, String... propertyName) { diff --git a/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java b/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java index 3a529be10979..7ad98fe6ded4 100644 --- a/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java +++ b/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java @@ -5,6 +5,9 @@ package io.opentelemetry.instrumentation.api.internal; +import static java.util.Arrays.asList; +import static java.util.Collections.emptyList; +import static java.util.Collections.singletonList; import static org.assertj.core.api.Assertions.assertThat; import io.opentelemetry.api.OpenTelemetry; @@ -14,6 +17,7 @@ import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.InstrumentationModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel; import java.util.Collections; +import java.util.List; import java.util.stream.Stream; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; @@ -134,57 +138,44 @@ void toSystemProperty() { @SetSystemProperty(key = "otel.instrumentation.test.property.list", value = "x,y,z") @Test void getList_systemProperty() { - assertList(java.util.Arrays.asList("x", "y", "z")); + assertList(asList("x", "y", "z")); } @SetEnvironmentVariable(key = "OTEL_INSTRUMENTATION_TEST_PROPERTY_LIST", value = "a,b,c") @Test void getList_environmentVariable() { - assertList(java.util.Arrays.asList("a", "b", "c")); + assertList(asList("a", "b", "c")); } @Test void getList_none() { - assertList(Collections.emptyList()); + assertList(emptyList()); } - private static void assertList(java.util.List expected) { - assertThat(ConfigPropertiesUtil.getList("otel.instrumentation.test.property.list", Collections.emptyList())) + private static void assertList(List expected) { + assertThat(ConfigPropertiesUtil.getList("otel.instrumentation.test.property.list", emptyList())) .isEqualTo(expected); assertThat( ConfigPropertiesUtil.getList( - OpenTelemetry.noop(), Collections.emptyList(), "test", "property", "list")) + OpenTelemetry.noop(), emptyList(), "test", "property", "list")) .isEqualTo(expected); } public static Stream listValuesProvider() { return Stream.of( - Arguments.of(java.util.Arrays.asList("a", "b", "c"), java.util.Arrays.asList("a", "b", "c")), - Arguments.of(java.util.Arrays.asList("single"), java.util.Arrays.asList("single")), - Arguments.of(Collections.emptyList(), Collections.emptyList()), - Arguments.of(java.util.Arrays.asList(""), Collections.emptyList()), - Arguments.of(null, Collections.emptyList())); + Arguments.of(asList("a", "b", "c"), asList("a", "b", "c")), + Arguments.of(singletonList("single"), singletonList("single")), + Arguments.of(emptyList(), emptyList()), + Arguments.of("invalid", emptyList()), + Arguments.of(null, emptyList())); } @ParameterizedTest @MethodSource("listValuesProvider") - void getList_declarativeConfig(java.util.List property, java.util.List expected) { + void getList_declarativeConfig(Object property, List expected) { assertThat( ConfigPropertiesUtil.getList( - DeclarativeConfiguration.create(modelForList(property)), Collections.emptyList(), "foo", "bar")) + DeclarativeConfiguration.create(model(property)), emptyList(), "foo", "bar")) .isEqualTo(expected); } - - private static OpenTelemetryConfigurationModel modelForList(java.util.List value) { - return new DeclarativeConfigurationBuilder() - .customizeModel( - new OpenTelemetryConfigurationModel() - .withFileFormat("1.0-rc.1") - .withInstrumentationDevelopment( - new InstrumentationModel() - .withJava( - new ExperimentalLanguageSpecificInstrumentationModel() - .withAdditionalProperty( - "foo", Collections.singletonMap("bar", value))))); - } } From 1b6a9554262af04f05a01e7dea514fe964233b2a Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Tue, 18 Nov 2025 08:19:36 +0100 Subject: [PATCH 07/79] string --- .../internal/ConfigPropertiesUtilTest.java | 46 +++++++++++++++++++ .../autoconfigure/TracingRequestHandler.java | 6 +-- .../v2_2/autoconfigure/AwsSdkSingletons.java | 9 +++- 3 files changed, 56 insertions(+), 5 deletions(-) diff --git a/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java b/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java index 7ad98fe6ded4..d416d812ed7d 100644 --- a/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java +++ b/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java @@ -46,6 +46,52 @@ void getString_none() { assertThat(ConfigPropertiesUtil.getString("test.property.string")).isNull(); } + @SetEnvironmentVariable(key = "OTEL_INSTRUMENTATION_TEST_PROPERTY_STRING", value = "env_value") + @SetSystemProperty(key = "otel.instrumentation.test.property.string", value = "sys_value") + @Test + void getString_withOpenTelemetry_systemProperty() { + assertString("sys_value"); + } + + @SetEnvironmentVariable(key = "OTEL_INSTRUMENTATION_TEST_PROPERTY_STRING", value = "env_value") + @Test + void getString_withOpenTelemetry_environmentVariable() { + assertString("env_value"); + } + + @Test + void getString_withOpenTelemetry_none() { + assertString("default_value"); + } + + private static void assertString(String expected) { + assertThat( + ConfigPropertiesUtil.getString("otel.instrumentation.test.property.string", "default_value")) + .isEqualTo(expected); + assertThat( + ConfigPropertiesUtil.getString( + OpenTelemetry.noop(), "default_value", "test", "property", "string")) + .isEqualTo(expected); + } + + public static Stream stringValuesProvider() { + return Stream.of( + Arguments.of("value1", "value1"), + Arguments.of("", ""), + Arguments.of(null, "default_value"), + Arguments.of(123, "default_value"), // no type coercion in declarative config + Arguments.of(true, "default_value")); // no type coercion in declarative config + } + + @ParameterizedTest + @MethodSource("stringValuesProvider") + void getString_declarativeConfig(Object property, String expected) { + assertThat( + ConfigPropertiesUtil.getString( + DeclarativeConfiguration.create(model(property)), "default_value", "foo", "bar")) + .isEqualTo(expected); + } + @SetEnvironmentVariable(key = "TEST_PROPERTY_INT", value = "12") @SetSystemProperty(key = "test.property.int", value = "42") @Test diff --git a/instrumentation/aws-sdk/aws-sdk-1.11/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v1_11/autoconfigure/TracingRequestHandler.java b/instrumentation/aws-sdk/aws-sdk-1.11/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v1_11/autoconfigure/TracingRequestHandler.java index 9916edc09c17..8900f1d89764 100644 --- a/instrumentation/aws-sdk/aws-sdk-1.11/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v1_11/autoconfigure/TracingRequestHandler.java +++ b/instrumentation/aws-sdk/aws-sdk-1.11/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v1_11/autoconfigure/TracingRequestHandler.java @@ -27,13 +27,13 @@ private static RequestHandler2 buildDelegate(OpenTelemetry openTelemetry) { return AwsSdkTelemetry.builder(openTelemetry) .setCaptureExperimentalSpanAttributes( ConfigPropertiesUtil.getBoolean( - openTelemetry, false, "aws-sdk", "experimental-span-attributes")) + openTelemetry, false, "aws_sdk", "experimental_span_attributes")) .setMessagingReceiveInstrumentationEnabled( ConfigPropertiesUtil.getBoolean( - openTelemetry, false, "messaging", "experimental", "receive-telemetry.enabled")) + openTelemetry, false, "messaging", "experimental", "receive_telemetry", "enabled")) .setCapturedHeaders( ConfigPropertiesUtil.getList( - openTelemetry, emptyList(), "messaging.experimental.capture-headers")) + openTelemetry, emptyList(), "messaging", "experimental", "capture_headers")) .build() .newRequestHandler(); } diff --git a/instrumentation/aws-sdk/aws-sdk-2.2/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/autoconfigure/AwsSdkSingletons.java b/instrumentation/aws-sdk/aws-sdk-2.2/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/autoconfigure/AwsSdkSingletons.java index 089757bea505..8f96a3cfe93d 100644 --- a/instrumentation/aws-sdk/aws-sdk-2.2/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/autoconfigure/AwsSdkSingletons.java +++ b/instrumentation/aws-sdk/aws-sdk-2.2/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/autoconfigure/AwsSdkSingletons.java @@ -7,6 +7,7 @@ import static java.util.Collections.emptyList; +import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.instrumentation.api.internal.ConfigPropertiesUtil; import io.opentelemetry.instrumentation.awssdk.v2_2.AwsSdkTelemetry; import io.opentelemetry.instrumentation.awssdk.v2_2.internal.AbstractAwsSdkTelemetryFactory; @@ -25,13 +26,17 @@ private static class AwsSdkTelemetryFactory extends AbstractAwsSdkTelemetryFacto @Override protected List getCapturedHeaders() { return ConfigPropertiesUtil.getList( - "otel.instrumentation.messaging.experimental.capture-headers", emptyList()); + GlobalOpenTelemetry.get(), + emptyList(), + "messaging", "experimental", "capture_headers"); } @Override protected boolean messagingReceiveInstrumentationEnabled() { return ConfigPropertiesUtil.getBoolean( - "otel.instrumentation.messaging.experimental.receive-telemetry.enabled", false); + GlobalOpenTelemetry.get(), + false, + "messaging", "experimental", "receive_telemetry", "enabled"); } @Override From 6d1472dfa06941a097579ea0e66822aae92a860d Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Tue, 18 Nov 2025 08:31:04 +0100 Subject: [PATCH 08/79] string --- .../v2_17/internal/ContextDataKeys.java | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/instrumentation/log4j/log4j-context-data/log4j-context-data-2.17/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/log4j/contextdata/v2_17/internal/ContextDataKeys.java b/instrumentation/log4j/log4j-context-data/log4j-context-data-2.17/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/log4j/contextdata/v2_17/internal/ContextDataKeys.java index a57da53ba61c..54fbe5d5890d 100644 --- a/instrumentation/log4j/log4j-context-data/log4j-context-data-2.17/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/log4j/contextdata/v2_17/internal/ContextDataKeys.java +++ b/instrumentation/log4j/log4j-context-data/log4j-context-data-2.17/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/log4j/contextdata/v2_17/internal/ContextDataKeys.java @@ -5,6 +5,7 @@ package io.opentelemetry.instrumentation.log4j.contextdata.v2_17.internal; +import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.instrumentation.api.incubator.log.LoggingContextConstants; import io.opentelemetry.instrumentation.api.internal.ConfigPropertiesUtil; @@ -15,13 +16,25 @@ public final class ContextDataKeys { public static final String TRACE_ID_KEY = ConfigPropertiesUtil.getString( - "otel.instrumentation.common.logging.trace-id", LoggingContextConstants.TRACE_ID); + GlobalOpenTelemetry.get(), + LoggingContextConstants.TRACE_ID, + "common", + "logging", + "trace_id"); public static final String SPAN_ID_KEY = ConfigPropertiesUtil.getString( - "otel.instrumentation.common.logging.span-id", LoggingContextConstants.SPAN_ID); + GlobalOpenTelemetry.get(), + LoggingContextConstants.SPAN_ID, + "common", + "logging", + "span_id"); public static final String TRACE_FLAGS_KEY = ConfigPropertiesUtil.getString( - "otel.instrumentation.common.logging.trace-flags", LoggingContextConstants.TRACE_FLAGS); + GlobalOpenTelemetry.get(), + LoggingContextConstants.TRACE_FLAGS, + "common", + "logging", + "trace_flags"); private ContextDataKeys() {} } From 15ff6caaaa741f4ee73ccb78b0b4c33fd99a7829 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Tue, 18 Nov 2025 08:45:28 +0100 Subject: [PATCH 09/79] string --- .../api/internal/ConfigPropertiesUtil.java | 4 +-- .../internal/ConfigPropertiesUtilTest.java | 5 ---- .../v2_6/TracingConsumerInterceptor.java | 27 ++++++++++++------- .../v2_6/TracingProducerInterceptor.java | 18 ++++++++----- .../OpenTelemetryContextDataProvider.java | 6 ++++- 5 files changed, 37 insertions(+), 23 deletions(-) diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java index fce5dee2b09a..f978e2601e4f 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java @@ -87,7 +87,7 @@ public static String getString(String propertyName) { return System.getenv(toEnvVarName(propertyName)); } - public static String getString(String propertyName, String defaultValue) { + private static String getString(String propertyName, String defaultValue) { String strValue = getString(propertyName); return strValue == null ? defaultValue : strValue; } @@ -101,7 +101,7 @@ public static String getString( (key) -> getString(key, defaultValue)); } - public static List getList(String propertyName, List defaultValue) { + private static List getList(String propertyName, List defaultValue) { String value = getString(propertyName); if (value == null) { return defaultValue; diff --git a/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java b/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java index d416d812ed7d..6631263df632 100644 --- a/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java +++ b/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java @@ -65,9 +65,6 @@ void getString_withOpenTelemetry_none() { } private static void assertString(String expected) { - assertThat( - ConfigPropertiesUtil.getString("otel.instrumentation.test.property.string", "default_value")) - .isEqualTo(expected); assertThat( ConfigPropertiesUtil.getString( OpenTelemetry.noop(), "default_value", "test", "property", "string")) @@ -199,8 +196,6 @@ void getList_none() { } private static void assertList(List expected) { - assertThat(ConfigPropertiesUtil.getList("otel.instrumentation.test.property.list", emptyList())) - .isEqualTo(expected); assertThat( ConfigPropertiesUtil.getList( OpenTelemetry.noop(), emptyList(), "test", "property", "list")) diff --git a/instrumentation/kafka/kafka-clients/kafka-clients-2.6/library/src/main/java/io/opentelemetry/instrumentation/kafkaclients/v2_6/TracingConsumerInterceptor.java b/instrumentation/kafka/kafka-clients/kafka-clients-2.6/library/src/main/java/io/opentelemetry/instrumentation/kafkaclients/v2_6/TracingConsumerInterceptor.java index 96c040074088..4a70da1053f1 100644 --- a/instrumentation/kafka/kafka-clients/kafka-clients-2.6/library/src/main/java/io/opentelemetry/instrumentation/kafkaclients/v2_6/TracingConsumerInterceptor.java +++ b/instrumentation/kafka/kafka-clients/kafka-clients-2.6/library/src/main/java/io/opentelemetry/instrumentation/kafkaclients/v2_6/TracingConsumerInterceptor.java @@ -9,6 +9,7 @@ import com.google.errorprone.annotations.CanIgnoreReturnValue; import io.opentelemetry.api.GlobalOpenTelemetry; +import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.context.Context; import io.opentelemetry.instrumentation.api.internal.ConfigPropertiesUtil; import io.opentelemetry.instrumentation.api.internal.Timer; @@ -32,15 +33,23 @@ @Deprecated public class TracingConsumerInterceptor implements ConsumerInterceptor { - private static final KafkaTelemetry telemetry = - KafkaTelemetry.builder(GlobalOpenTelemetry.get()) - .setMessagingReceiveInstrumentationEnabled( - ConfigPropertiesUtil.getBoolean( - "otel.instrumentation.messaging.experimental.receive-telemetry.enabled", false)) - .setCapturedHeaders( - ConfigPropertiesUtil.getList( - "otel.instrumentation.messaging.experimental.capture-headers", emptyList())) - .build(); + private static final KafkaTelemetry telemetry; + + static { + OpenTelemetry openTelemetry = GlobalOpenTelemetry.get(); + telemetry = KafkaTelemetry.builder(openTelemetry) + .setMessagingReceiveInstrumentationEnabled( + ConfigPropertiesUtil.getBoolean( + openTelemetry, + false, + "messaging", "experimental", "receive_telemetry", "enabled")) + .setCapturedHeaders( + ConfigPropertiesUtil.getList( + openTelemetry, + emptyList(), + "messaging", "experimental", "capture_headers")) + .build(); + } private String consumerGroup; private String clientId; diff --git a/instrumentation/kafka/kafka-clients/kafka-clients-2.6/library/src/main/java/io/opentelemetry/instrumentation/kafkaclients/v2_6/TracingProducerInterceptor.java b/instrumentation/kafka/kafka-clients/kafka-clients-2.6/library/src/main/java/io/opentelemetry/instrumentation/kafkaclients/v2_6/TracingProducerInterceptor.java index 007e1df51d4b..b5af34a6d2d8 100644 --- a/instrumentation/kafka/kafka-clients/kafka-clients-2.6/library/src/main/java/io/opentelemetry/instrumentation/kafkaclients/v2_6/TracingProducerInterceptor.java +++ b/instrumentation/kafka/kafka-clients/kafka-clients-2.6/library/src/main/java/io/opentelemetry/instrumentation/kafkaclients/v2_6/TracingProducerInterceptor.java @@ -9,6 +9,7 @@ import com.google.errorprone.annotations.CanIgnoreReturnValue; import io.opentelemetry.api.GlobalOpenTelemetry; +import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.instrumentation.api.internal.ConfigPropertiesUtil; import java.util.Map; import java.util.Objects; @@ -28,12 +29,17 @@ @Deprecated public class TracingProducerInterceptor implements ProducerInterceptor { - private static final KafkaTelemetry telemetry = - KafkaTelemetry.builder(GlobalOpenTelemetry.get()) - .setCapturedHeaders( - ConfigPropertiesUtil.getList( - "otel.instrumentation.messaging.experimental.capture-headers", emptyList())) - .build(); + private static final KafkaTelemetry telemetry; + + static { + OpenTelemetry openTelemetry = GlobalOpenTelemetry.get(); + telemetry = + KafkaTelemetry.builder(openTelemetry) + .setCapturedHeaders( + ConfigPropertiesUtil.getList( + openTelemetry, emptyList(), "messaging", "experimental", "capture_headers")) + .build(); + } @Nullable private String clientId; diff --git a/instrumentation/log4j/log4j-context-data/log4j-context-data-2.17/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/log4j/contextdata/v2_17/OpenTelemetryContextDataProvider.java b/instrumentation/log4j/log4j-context-data/log4j-context-data-2.17/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/log4j/contextdata/v2_17/OpenTelemetryContextDataProvider.java index 57024ded7c3c..596b3e98574c 100644 --- a/instrumentation/log4j/log4j-context-data/log4j-context-data-2.17/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/log4j/contextdata/v2_17/OpenTelemetryContextDataProvider.java +++ b/instrumentation/log4j/log4j-context-data/log4j-context-data-2.17/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/log4j/contextdata/v2_17/OpenTelemetryContextDataProvider.java @@ -5,6 +5,7 @@ package io.opentelemetry.instrumentation.log4j.contextdata.v2_17; +import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.baggage.Baggage; import io.opentelemetry.api.baggage.BaggageEntry; import io.opentelemetry.api.trace.Span; @@ -25,7 +26,10 @@ */ public class OpenTelemetryContextDataProvider implements ContextDataProvider { private static final boolean BAGGAGE_ENABLED = - ConfigPropertiesUtil.getBoolean("otel.instrumentation.log4j-context-data.add-baggage", false); + ConfigPropertiesUtil.getBoolean( + GlobalOpenTelemetry.get(), + false, + "log4j_context_data", "add_baggage"); private static final boolean configuredResourceAttributeAccessible = isConfiguredResourceAttributeAccessible(); private static final Map staticContextData = getStaticContextData(); From 2da57746ee00dfcb41d0ec07329291783e334428 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Tue, 18 Nov 2025 08:47:38 +0100 Subject: [PATCH 10/79] string --- .../v2_2/internal/AbstractAwsSdkTelemetryFactory.java | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/instrumentation/aws-sdk/aws-sdk-2.2/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/internal/AbstractAwsSdkTelemetryFactory.java b/instrumentation/aws-sdk/aws-sdk-2.2/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/internal/AbstractAwsSdkTelemetryFactory.java index 574c8e214ef9..c27c03cb5f78 100644 --- a/instrumentation/aws-sdk/aws-sdk-2.2/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/internal/AbstractAwsSdkTelemetryFactory.java +++ b/instrumentation/aws-sdk/aws-sdk-2.2/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/internal/AbstractAwsSdkTelemetryFactory.java @@ -17,26 +17,26 @@ public abstract class AbstractAwsSdkTelemetryFactory { protected abstract List getCapturedHeaders(); private boolean captureExperimentalSpanAttributes() { - return getBoolean("otel.instrumentation.aws-sdk.experimental-span-attributes", false); + return getBoolean(false, "otel.instrumentation.aws-sdk.experimental-span-attributes"); } protected abstract boolean messagingReceiveInstrumentationEnabled(); private boolean useMessagingPropagator() { return getBoolean( - "otel.instrumentation.aws-sdk.experimental-use-propagator-for-messaging", false); + false, "otel.instrumentation.aws-sdk.experimental-use-propagator-for-messaging"); } private boolean recordIndividualHttpError() { return getBoolean( - "otel.instrumentation.aws-sdk.experimental-record-individual-http-error", false); + false, "otel.instrumentation.aws-sdk.experimental-record-individual-http-error"); } private boolean genaiCaptureMessageContent() { - return getBoolean("otel.instrumentation.genai.capture-message-content", false); + return getBoolean(false, "otel.instrumentation.genai.capture-message-content"); } - protected abstract boolean getBoolean(String name, boolean defaultValue); + protected abstract boolean getBoolean(boolean defaultValue, String... name); public AwsSdkTelemetry telemetry() { return AwsSdkTelemetry.builder(GlobalOpenTelemetry.get()) From 8414a8d8cf5d41dd25ae99fcf6f0627971dd509c Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Tue, 18 Nov 2025 08:48:08 +0100 Subject: [PATCH 11/79] string --- .../v2_6/TracingConsumerInterceptor.java | 26 ++++++++++--------- .../OpenTelemetryContextDataProvider.java | 4 +-- 2 files changed, 15 insertions(+), 15 deletions(-) diff --git a/instrumentation/kafka/kafka-clients/kafka-clients-2.6/library/src/main/java/io/opentelemetry/instrumentation/kafkaclients/v2_6/TracingConsumerInterceptor.java b/instrumentation/kafka/kafka-clients/kafka-clients-2.6/library/src/main/java/io/opentelemetry/instrumentation/kafkaclients/v2_6/TracingConsumerInterceptor.java index 4a70da1053f1..cce4f94f7e79 100644 --- a/instrumentation/kafka/kafka-clients/kafka-clients-2.6/library/src/main/java/io/opentelemetry/instrumentation/kafkaclients/v2_6/TracingConsumerInterceptor.java +++ b/instrumentation/kafka/kafka-clients/kafka-clients-2.6/library/src/main/java/io/opentelemetry/instrumentation/kafkaclients/v2_6/TracingConsumerInterceptor.java @@ -37,18 +37,20 @@ public class TracingConsumerInterceptor implements ConsumerInterceptor staticContextData = getStaticContextData(); From 75f1a1b8f1813355fa66fb27542d009ebb95cc4e Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Tue, 18 Nov 2025 08:53:46 +0100 Subject: [PATCH 12/79] string --- .../api/internal/ConfigPropertiesUtil.java | 3 +-- .../awssdk/v2_2/AwsSdkSingletons.java | 6 ++++-- .../awssdk/v2_2/autoconfigure/AwsSdkSingletons.java | 13 +++++++------ .../internal/AbstractAwsSdkTelemetryFactory.java | 10 ++++------ 4 files changed, 16 insertions(+), 16 deletions(-) diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java index f978e2601e4f..7e65a83fd811 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java @@ -161,8 +161,7 @@ private static DeclarativeConfigProperties getDeclarativeConfigNode( return null; } - // Visible for testing - static String toSystemProperty(String[] propertyName) { + public static String toSystemProperty(String[] propertyName) { return "otel.instrumentation." + String.join(".", propertyName).replace('_', '-'); } diff --git a/instrumentation/aws-sdk/aws-sdk-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v2_2/AwsSdkSingletons.java b/instrumentation/aws-sdk/aws-sdk-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v2_2/AwsSdkSingletons.java index f84cd5590e99..33ee1679f21a 100644 --- a/instrumentation/aws-sdk/aws-sdk-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v2_2/AwsSdkSingletons.java +++ b/instrumentation/aws-sdk/aws-sdk-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v2_2/AwsSdkSingletons.java @@ -5,6 +5,7 @@ package io.opentelemetry.javaagent.instrumentation.awssdk.v2_2; +import io.opentelemetry.instrumentation.api.internal.ConfigPropertiesUtil; import io.opentelemetry.instrumentation.awssdk.v2_2.AwsSdkTelemetry; import io.opentelemetry.instrumentation.awssdk.v2_2.internal.AbstractAwsSdkTelemetryFactory; import io.opentelemetry.javaagent.bootstrap.internal.AgentInstrumentationConfig; @@ -32,8 +33,9 @@ protected boolean messagingReceiveInstrumentationEnabled() { } @Override - protected boolean getBoolean(String name, boolean defaultValue) { - return AgentInstrumentationConfig.get().getBoolean(name, defaultValue); + protected boolean getBoolean(boolean defaultValue, String... name) { + return AgentInstrumentationConfig.get() + .getBoolean(ConfigPropertiesUtil.toSystemProperty(name), defaultValue); } } diff --git a/instrumentation/aws-sdk/aws-sdk-2.2/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/autoconfigure/AwsSdkSingletons.java b/instrumentation/aws-sdk/aws-sdk-2.2/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/autoconfigure/AwsSdkSingletons.java index 8f96a3cfe93d..4d4dd601e631 100644 --- a/instrumentation/aws-sdk/aws-sdk-2.2/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/autoconfigure/AwsSdkSingletons.java +++ b/instrumentation/aws-sdk/aws-sdk-2.2/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/autoconfigure/AwsSdkSingletons.java @@ -26,9 +26,7 @@ private static class AwsSdkTelemetryFactory extends AbstractAwsSdkTelemetryFacto @Override protected List getCapturedHeaders() { return ConfigPropertiesUtil.getList( - GlobalOpenTelemetry.get(), - emptyList(), - "messaging", "experimental", "capture_headers"); + GlobalOpenTelemetry.get(), emptyList(), "messaging", "experimental", "capture_headers"); } @Override @@ -36,12 +34,15 @@ protected boolean messagingReceiveInstrumentationEnabled() { return ConfigPropertiesUtil.getBoolean( GlobalOpenTelemetry.get(), false, - "messaging", "experimental", "receive_telemetry", "enabled"); + "messaging", + "experimental", + "receive_telemetry", + "enabled"); } @Override - protected boolean getBoolean(String name, boolean defaultValue) { - return ConfigPropertiesUtil.getBoolean(name, defaultValue); + protected boolean getBoolean(boolean defaultValue, String... name) { + return ConfigPropertiesUtil.getBoolean(GlobalOpenTelemetry.get(), defaultValue, name); } } diff --git a/instrumentation/aws-sdk/aws-sdk-2.2/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/internal/AbstractAwsSdkTelemetryFactory.java b/instrumentation/aws-sdk/aws-sdk-2.2/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/internal/AbstractAwsSdkTelemetryFactory.java index c27c03cb5f78..97701d3242c8 100644 --- a/instrumentation/aws-sdk/aws-sdk-2.2/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/internal/AbstractAwsSdkTelemetryFactory.java +++ b/instrumentation/aws-sdk/aws-sdk-2.2/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/internal/AbstractAwsSdkTelemetryFactory.java @@ -17,23 +17,21 @@ public abstract class AbstractAwsSdkTelemetryFactory { protected abstract List getCapturedHeaders(); private boolean captureExperimentalSpanAttributes() { - return getBoolean(false, "otel.instrumentation.aws-sdk.experimental-span-attributes"); + return getBoolean(false, "aws_sdk", "experimental_span_attributes"); } protected abstract boolean messagingReceiveInstrumentationEnabled(); private boolean useMessagingPropagator() { - return getBoolean( - false, "otel.instrumentation.aws-sdk.experimental-use-propagator-for-messaging"); + return getBoolean(false, "aws_sdk", "experimental_use_propagator_for_messaging"); } private boolean recordIndividualHttpError() { - return getBoolean( - false, "otel.instrumentation.aws-sdk.experimental-record-individual-http-error"); + return getBoolean(false, "aws_sdk", "experimental_record_individual_http_error"); } private boolean genaiCaptureMessageContent() { - return getBoolean(false, "otel.instrumentation.genai.capture-message-content"); + return getBoolean(false, "genai", "capture_message_content"); } protected abstract boolean getBoolean(boolean defaultValue, String... name); From a3aae6f8983c06324cf3e76d74bf5fb4b1454b96 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Tue, 18 Nov 2025 09:09:48 +0100 Subject: [PATCH 13/79] string --- .../api/instrumenter/InstrumenterBuilder.java | 10 +++--- .../api/internal/ConfigPropertiesUtil.java | 32 +++++++++++++------ 2 files changed, 26 insertions(+), 16 deletions(-) diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/InstrumenterBuilder.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/InstrumenterBuilder.java index 422d357349a3..aff2026a3fda 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/InstrumenterBuilder.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/InstrumenterBuilder.java @@ -49,11 +49,6 @@ public final class InstrumenterBuilder { private static final Logger logger = Logger.getLogger(InstrumenterBuilder.class.getName()); - private static final SpanSuppressionStrategy spanSuppressionStrategy = - SpanSuppressionStrategy.fromConfig( - ConfigPropertiesUtil.getString( - "otel.instrumentation.experimental.span-suppression-strategy")); - final OpenTelemetry openTelemetry; final String instrumentationName; SpanNameExtractor spanNameExtractor; @@ -374,7 +369,10 @@ private String getSchemaUrl() { SpanSuppressor buildSpanSuppressor() { return new SpanSuppressors.ByContextKey( - spanSuppressionStrategy.create(getSpanKeysFromAttributesExtractors())); + SpanSuppressionStrategy.fromConfig( + ConfigPropertiesUtil.getNullableString( + openTelemetry, "experimental", "span_suppression_strategy")) + .create(getSpanKeysFromAttributesExtractors())); } private Set getSpanKeysFromAttributesExtractors() { diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java index 7e65a83fd811..36911ab7b7f3 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java @@ -6,6 +6,7 @@ package io.opentelemetry.instrumentation.api.internal; import static io.opentelemetry.api.incubator.config.DeclarativeConfigProperties.empty; +import static java.util.Objects.requireNonNull; import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.api.incubator.ExtendedOpenTelemetry; @@ -87,18 +88,29 @@ public static String getString(String propertyName) { return System.getenv(toEnvVarName(propertyName)); } - private static String getString(String propertyName, String defaultValue) { - String strValue = getString(propertyName); - return strValue == null ? defaultValue : strValue; - } - public static String getString( OpenTelemetry openTelemetry, String defaultValue, String... propertyName) { - return getDeclarativeConfigOrFallback( - openTelemetry, - propertyName, - (node, key) -> node.getString(key, defaultValue), - (key) -> getString(key, defaultValue)); + return requireNonNull(getStringImpl(openTelemetry, defaultValue, propertyName)); + } + + @Nullable + public static String getStringImpl( + OpenTelemetry openTelemetry, @Nullable String defaultValue, String... propertyName) { + String result = + getDeclarativeConfigOrFallback( + openTelemetry, + propertyName, + (node, key) -> node.getString(key), + (key) -> getString(key)); + if (result == null) { + return defaultValue; + } + return result; + } + + @Nullable + public static String getNullableString(OpenTelemetry openTelemetry, String... propertyName) { + return getStringImpl(openTelemetry, null, propertyName); } private static List getList(String propertyName, List defaultValue) { From 2a5bedb78230dfe508dc0baf4516b99e35f5e604 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Tue, 18 Nov 2025 09:14:59 +0100 Subject: [PATCH 14/79] string --- .../api/instrumenter/InstrumenterBuilder.java | 4 +-- .../instrumenter/SpanSuppressionStrategy.java | 6 +--- .../api/internal/ConfigPropertiesUtil.java | 30 +++++-------------- .../SpanSuppressionStrategyTest.java | 3 +- 4 files changed, 12 insertions(+), 31 deletions(-) diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/InstrumenterBuilder.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/InstrumenterBuilder.java index aff2026a3fda..146a52648b93 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/InstrumenterBuilder.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/InstrumenterBuilder.java @@ -370,8 +370,8 @@ private String getSchemaUrl() { SpanSuppressor buildSpanSuppressor() { return new SpanSuppressors.ByContextKey( SpanSuppressionStrategy.fromConfig( - ConfigPropertiesUtil.getNullableString( - openTelemetry, "experimental", "span_suppression_strategy")) + ConfigPropertiesUtil.getString( + openTelemetry, "semconv", "experimental", "span_suppression_strategy")) .create(getSpanKeysFromAttributesExtractors())); } diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/SpanSuppressionStrategy.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/SpanSuppressionStrategy.java index 6210a74c8154..d9a40e89f164 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/SpanSuppressionStrategy.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/SpanSuppressionStrategy.java @@ -17,7 +17,6 @@ import java.util.Locale; import java.util.Map; import java.util.Set; -import javax.annotation.Nullable; enum SpanSuppressionStrategy { /** Do not suppress spans at all. */ @@ -74,10 +73,7 @@ SpanSuppressor create(Set spanKeys) { abstract SpanSuppressor create(Set spanKeys); - static SpanSuppressionStrategy fromConfig(@Nullable String value) { - if (value == null) { - value = "semconv"; - } + static SpanSuppressionStrategy fromConfig(String value) { switch (value.toLowerCase(Locale.ROOT)) { case "none": return NONE; diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java index 36911ab7b7f3..1f85537caf79 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java @@ -6,7 +6,6 @@ package io.opentelemetry.instrumentation.api.internal; import static io.opentelemetry.api.incubator.config.DeclarativeConfigProperties.empty; -import static java.util.Objects.requireNonNull; import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.api.incubator.ExtendedOpenTelemetry; @@ -90,27 +89,14 @@ public static String getString(String propertyName) { public static String getString( OpenTelemetry openTelemetry, String defaultValue, String... propertyName) { - return requireNonNull(getStringImpl(openTelemetry, defaultValue, propertyName)); - } - - @Nullable - public static String getStringImpl( - OpenTelemetry openTelemetry, @Nullable String defaultValue, String... propertyName) { - String result = - getDeclarativeConfigOrFallback( - openTelemetry, - propertyName, - (node, key) -> node.getString(key), - (key) -> getString(key)); - if (result == null) { - return defaultValue; - } - return result; - } - - @Nullable - public static String getNullableString(OpenTelemetry openTelemetry, String... propertyName) { - return getStringImpl(openTelemetry, null, propertyName); + return getDeclarativeConfigOrFallback( + openTelemetry, + propertyName, + (node, key) -> node.getString(key, defaultValue), + (key) -> { + String strValue = getString(key); + return strValue == null ? defaultValue : strValue; + }); } private static List getList(String propertyName, List defaultValue) { diff --git a/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/instrumenter/SpanSuppressionStrategyTest.java b/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/instrumenter/SpanSuppressionStrategyTest.java index 6091c512dea3..d15f564d080f 100644 --- a/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/instrumenter/SpanSuppressionStrategyTest.java +++ b/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/instrumenter/SpanSuppressionStrategyTest.java @@ -45,8 +45,7 @@ private static Stream configArgs() { Arguments.of("Span-Kind", SpanSuppressionStrategy.SPAN_KIND), Arguments.of("semconv", SpanSuppressionStrategy.SEMCONV), Arguments.of("SemConv", SpanSuppressionStrategy.SEMCONV), - Arguments.of("asdfasdfasdf", SpanSuppressionStrategy.SEMCONV), - Arguments.of(null, SpanSuppressionStrategy.SEMCONV)); + Arguments.of("asdfasdfasdf", SpanSuppressionStrategy.SEMCONV)); } @ParameterizedTest From 22df64bfb38776de0807659ecc957d7171b5a349 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Tue, 18 Nov 2025 09:27:06 +0100 Subject: [PATCH 15/79] javadoc --- .../api/internal/ConfigPropertiesUtil.java | 35 ++++++++++++++----- 1 file changed, 26 insertions(+), 9 deletions(-) diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java index 1f85537caf79..5c4e530bb007 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java @@ -66,6 +66,10 @@ public static boolean getBoolean( (key) -> getBoolean(key, defaultValue)); } + /** + * Returns the int value of the given property name from system properties and environment + * variables. + */ public static int getInt(String propertyName, int defaultValue) { String strValue = getString(propertyName); if (strValue == null) { @@ -78,6 +82,13 @@ public static int getInt(String propertyName, int defaultValue) { } } + /** + * Returns the string value of the given property name from system properties and environment + * variables. + * + *

It's recommended to use {@link #getString(OpenTelemetry, String, String...)} instead to + * support Declarative Config. + */ @Nullable public static String getString(String propertyName) { String value = System.getProperty(propertyName); @@ -87,6 +98,10 @@ public static String getString(String propertyName) { return System.getenv(toEnvVarName(propertyName)); } + /** + * Returns the string value of the given property name from Declarative Config if available, + * otherwise falls back to system properties and environment variables. + */ public static String getString( OpenTelemetry openTelemetry, String defaultValue, String... propertyName) { return getDeclarativeConfigOrFallback( @@ -99,21 +114,23 @@ public static String getString( }); } - private static List getList(String propertyName, List defaultValue) { - String value = getString(propertyName); - if (value == null) { - return defaultValue; - } - return filterBlanksAndNulls(value.split(",")); - } - + /** + * Returns the list of strings value of the given property name from Declarative Config if + * available, otherwise falls back to system properties and environment variables. + */ public static List getList( OpenTelemetry openTelemetry, List defaultValue, String... propertyName) { return getDeclarativeConfigOrFallback( openTelemetry, propertyName, (node, key) -> node.getScalarList(key, String.class, defaultValue), - (key) -> getList(key, defaultValue)); + (key) -> { + String value = getString(key); + if (value == null) { + return defaultValue; + } + return filterBlanksAndNulls(value.split(",")); + }); } private static List filterBlanksAndNulls(String[] values) { From 8b028e4abd6a9291bc637ca277791e52085a393d Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Tue, 18 Nov 2025 10:04:08 +0100 Subject: [PATCH 16/79] add contract --- instrumentation-api/build.gradle.kts | 1 + .../api/instrumenter/InstrumenterBuilder.java | 14 ++++++++++---- .../api/instrumenter/SpanSuppressionStrategy.java | 6 +++++- .../api/internal/ConfigPropertiesUtil.java | 11 +++++++++-- .../servlet/ExperimentalSnippetHolder.java | 11 ++++++++++- 5 files changed, 35 insertions(+), 8 deletions(-) diff --git a/instrumentation-api/build.gradle.kts b/instrumentation-api/build.gradle.kts index 38dfcbf8a6a5..257dfda342af 100644 --- a/instrumentation-api/build.gradle.kts +++ b/instrumentation-api/build.gradle.kts @@ -17,6 +17,7 @@ dependencies { implementation("io.opentelemetry.semconv:opentelemetry-semconv") compileOnly("com.google.auto.value:auto-value-annotations") + compileOnly("org.jetbrains:annotations:26.0.2") annotationProcessor("com.google.auto.value:auto-value") testImplementation("io.opentelemetry.javaagent:opentelemetry-testing-common") diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/InstrumenterBuilder.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/InstrumenterBuilder.java index 146a52648b93..9245b6ab3711 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/InstrumenterBuilder.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/InstrumenterBuilder.java @@ -368,11 +368,17 @@ private String getSchemaUrl() { } SpanSuppressor buildSpanSuppressor() { + // otel.instrumentation.experimental.* doesn't fit the usual pattern of configuration properties + // for instrumentations, so we need to handle both declarative and non-declarative configs here + + String value = + ConfigPropertiesUtil.isDeclarativeConfig(openTelemetry) + ? ConfigPropertiesUtil.getString( + openTelemetry, null, "common", "experimental", "span_suppression_strategy") + : ConfigPropertiesUtil.getString( + "otel.instrumentation.experimental.span-suppression-strategy"); return new SpanSuppressors.ByContextKey( - SpanSuppressionStrategy.fromConfig( - ConfigPropertiesUtil.getString( - openTelemetry, "semconv", "experimental", "span_suppression_strategy")) - .create(getSpanKeysFromAttributesExtractors())); + SpanSuppressionStrategy.fromConfig(value).create(getSpanKeysFromAttributesExtractors())); } private Set getSpanKeysFromAttributesExtractors() { diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/SpanSuppressionStrategy.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/SpanSuppressionStrategy.java index d9a40e89f164..6210a74c8154 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/SpanSuppressionStrategy.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/SpanSuppressionStrategy.java @@ -17,6 +17,7 @@ import java.util.Locale; import java.util.Map; import java.util.Set; +import javax.annotation.Nullable; enum SpanSuppressionStrategy { /** Do not suppress spans at all. */ @@ -73,7 +74,10 @@ SpanSuppressor create(Set spanKeys) { abstract SpanSuppressor create(Set spanKeys); - static SpanSuppressionStrategy fromConfig(String value) { + static SpanSuppressionStrategy fromConfig(@Nullable String value) { + if (value == null) { + value = "semconv"; + } switch (value.toLowerCase(Locale.ROOT)) { case "none": return NONE; diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java index 5c4e530bb007..7538fc860d2d 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java @@ -11,6 +11,7 @@ import io.opentelemetry.api.incubator.ExtendedOpenTelemetry; import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; +import org.jetbrains.annotations.Contract; import java.util.Arrays; import java.util.List; import java.util.Locale; @@ -102,8 +103,9 @@ public static String getString(String propertyName) { * Returns the string value of the given property name from Declarative Config if available, * otherwise falls back to system properties and environment variables. */ + @Contract("_, !null, _ -> !null") public static String getString( - OpenTelemetry openTelemetry, String defaultValue, String... propertyName) { + OpenTelemetry openTelemetry, @Nullable String defaultValue, String... propertyName) { return getDeclarativeConfigOrFallback( openTelemetry, propertyName, @@ -133,6 +135,11 @@ public static List getList( }); } + /** Returns true if the given OpenTelemetry instance supports Declarative Config. */ + public static boolean isDeclarativeConfig(OpenTelemetry openTelemetry) { + return isIncubator && openTelemetry instanceof ExtendedOpenTelemetry; + } + private static List filterBlanksAndNulls(String[] values) { return Arrays.stream(values) .map(String::trim) @@ -159,7 +166,7 @@ private static T getDeclarativeConfigOrFallback( @Nullable private static DeclarativeConfigProperties getDeclarativeConfigNode( OpenTelemetry openTelemetry, String... propertyName) { - if (isIncubator && openTelemetry instanceof ExtendedOpenTelemetry) { + if (isDeclarativeConfig(openTelemetry)) { ExtendedOpenTelemetry extendedOpenTelemetry = (ExtendedOpenTelemetry) openTelemetry; ConfigProvider configProvider = extendedOpenTelemetry.getConfigProvider(); DeclarativeConfigProperties instrumentationConfig = configProvider.getInstrumentationConfig(); diff --git a/instrumentation/servlet/servlet-common/bootstrap/src/main/java/io/opentelemetry/javaagent/bootstrap/servlet/ExperimentalSnippetHolder.java b/instrumentation/servlet/servlet-common/bootstrap/src/main/java/io/opentelemetry/javaagent/bootstrap/servlet/ExperimentalSnippetHolder.java index ebfc41e7b72b..9c1d44b65449 100644 --- a/instrumentation/servlet/servlet-common/bootstrap/src/main/java/io/opentelemetry/javaagent/bootstrap/servlet/ExperimentalSnippetHolder.java +++ b/instrumentation/servlet/servlet-common/bootstrap/src/main/java/io/opentelemetry/javaagent/bootstrap/servlet/ExperimentalSnippetHolder.java @@ -5,6 +5,8 @@ package io.opentelemetry.javaagent.bootstrap.servlet; +import io.opentelemetry.api.GlobalOpenTelemetry; +import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.instrumentation.api.internal.ConfigPropertiesUtil; public class ExperimentalSnippetHolder { @@ -12,7 +14,14 @@ public class ExperimentalSnippetHolder { private static volatile String snippet = getSnippetSetting(); private static String getSnippetSetting() { - String result = ConfigPropertiesUtil.getString("otel.experimental.javascript-snippet"); + OpenTelemetry openTelemetry = GlobalOpenTelemetry.get(); + String result = + // otel.experimental.* does not fit the usual pattern of configuration properties for + // instrumentations, so we need to handle both declarative and non-declarative configs here + ConfigPropertiesUtil.isDeclarativeConfig(openTelemetry) + ? ConfigPropertiesUtil.getString( + openTelemetry, null, "servlet", "experimental", "javascript-snippet") + : ConfigPropertiesUtil.getString("otel.experimental.javascript-snippet"); return result == null ? "" : result; } From 949d4438c4738be105d5fb34d438874889a7c666 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Tue, 18 Nov 2025 10:04:36 +0100 Subject: [PATCH 17/79] add contract --- .../instrumentation/api/instrumenter/InstrumenterBuilder.java | 1 - .../instrumentation/api/internal/ConfigPropertiesUtil.java | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/InstrumenterBuilder.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/InstrumenterBuilder.java index 9245b6ab3711..e95b30cdbb8c 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/InstrumenterBuilder.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/InstrumenterBuilder.java @@ -370,7 +370,6 @@ private String getSchemaUrl() { SpanSuppressor buildSpanSuppressor() { // otel.instrumentation.experimental.* doesn't fit the usual pattern of configuration properties // for instrumentations, so we need to handle both declarative and non-declarative configs here - String value = ConfigPropertiesUtil.isDeclarativeConfig(openTelemetry) ? ConfigPropertiesUtil.getString( diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java index 7538fc860d2d..66bc95bbb09d 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java @@ -11,7 +11,6 @@ import io.opentelemetry.api.incubator.ExtendedOpenTelemetry; import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; -import org.jetbrains.annotations.Contract; import java.util.Arrays; import java.util.List; import java.util.Locale; @@ -19,6 +18,7 @@ import java.util.function.Function; import java.util.stream.Collectors; import javax.annotation.Nullable; +import org.jetbrains.annotations.Contract; /** * This class is internal and is hence not for public use. Its APIs are unstable and can change at From 2856550ae7db0a528bf89d42d7357f06563e5710 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Tue, 18 Nov 2025 10:14:51 +0100 Subject: [PATCH 18/79] remove contract --- instrumentation-api/build.gradle.kts | 1 - .../api/instrumenter/InstrumenterBuilder.java | 2 +- .../api/internal/ConfigPropertiesUtil.java | 27 +++++++++++-------- .../internal/ConfigPropertiesUtilTest.java | 4 +-- .../v2_17/internal/ContextDataKeys.java | 6 ++--- .../servlet/ExperimentalSnippetHolder.java | 2 +- 6 files changed, 23 insertions(+), 19 deletions(-) diff --git a/instrumentation-api/build.gradle.kts b/instrumentation-api/build.gradle.kts index 257dfda342af..38dfcbf8a6a5 100644 --- a/instrumentation-api/build.gradle.kts +++ b/instrumentation-api/build.gradle.kts @@ -17,7 +17,6 @@ dependencies { implementation("io.opentelemetry.semconv:opentelemetry-semconv") compileOnly("com.google.auto.value:auto-value-annotations") - compileOnly("org.jetbrains:annotations:26.0.2") annotationProcessor("com.google.auto.value:auto-value") testImplementation("io.opentelemetry.javaagent:opentelemetry-testing-common") diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/InstrumenterBuilder.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/InstrumenterBuilder.java index e95b30cdbb8c..11801a509c5d 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/InstrumenterBuilder.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/InstrumenterBuilder.java @@ -373,7 +373,7 @@ SpanSuppressor buildSpanSuppressor() { String value = ConfigPropertiesUtil.isDeclarativeConfig(openTelemetry) ? ConfigPropertiesUtil.getString( - openTelemetry, null, "common", "experimental", "span_suppression_strategy") + openTelemetry, "common", "experimental", "span_suppression_strategy") : ConfigPropertiesUtil.getString( "otel.instrumentation.experimental.span-suppression-strategy"); return new SpanSuppressors.ByContextKey( diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java index 66bc95bbb09d..45f8a739c21a 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java @@ -18,7 +18,6 @@ import java.util.function.Function; import java.util.stream.Collectors; import javax.annotation.Nullable; -import org.jetbrains.annotations.Contract; /** * This class is internal and is hence not for public use. Its APIs are unstable and can change at @@ -103,17 +102,23 @@ public static String getString(String propertyName) { * Returns the string value of the given property name from Declarative Config if available, * otherwise falls back to system properties and environment variables. */ - @Contract("_, !null, _ -> !null") - public static String getString( - OpenTelemetry openTelemetry, @Nullable String defaultValue, String... propertyName) { + @Nullable + public static String getString(OpenTelemetry openTelemetry, String... propertyName) { return getDeclarativeConfigOrFallback( - openTelemetry, - propertyName, - (node, key) -> node.getString(key, defaultValue), - (key) -> { - String strValue = getString(key); - return strValue == null ? defaultValue : strValue; - }); + openTelemetry, propertyName, (node, key) -> node.getString(key), (key) -> getString(key)); + } + + /** + * Returns the string value of the given property name from Declarative Config if available, + * otherwise falls back to system properties and environment variables. + */ + public static String getStringOrFallback( + OpenTelemetry openTelemetry, String defaultValue, String... propertyName) { + String value = getString(openTelemetry, propertyName); + if (value == null) { + return defaultValue; + } + return value; } /** diff --git a/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java b/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java index 6631263df632..8985c67ca95f 100644 --- a/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java +++ b/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java @@ -66,7 +66,7 @@ void getString_withOpenTelemetry_none() { private static void assertString(String expected) { assertThat( - ConfigPropertiesUtil.getString( + ConfigPropertiesUtil.getStringOrFallback( OpenTelemetry.noop(), "default_value", "test", "property", "string")) .isEqualTo(expected); } @@ -84,7 +84,7 @@ public static Stream stringValuesProvider() { @MethodSource("stringValuesProvider") void getString_declarativeConfig(Object property, String expected) { assertThat( - ConfigPropertiesUtil.getString( + ConfigPropertiesUtil.getStringOrFallback( DeclarativeConfiguration.create(model(property)), "default_value", "foo", "bar")) .isEqualTo(expected); } diff --git a/instrumentation/log4j/log4j-context-data/log4j-context-data-2.17/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/log4j/contextdata/v2_17/internal/ContextDataKeys.java b/instrumentation/log4j/log4j-context-data/log4j-context-data-2.17/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/log4j/contextdata/v2_17/internal/ContextDataKeys.java index 54fbe5d5890d..082248d0dff8 100644 --- a/instrumentation/log4j/log4j-context-data/log4j-context-data-2.17/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/log4j/contextdata/v2_17/internal/ContextDataKeys.java +++ b/instrumentation/log4j/log4j-context-data/log4j-context-data-2.17/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/log4j/contextdata/v2_17/internal/ContextDataKeys.java @@ -15,21 +15,21 @@ */ public final class ContextDataKeys { public static final String TRACE_ID_KEY = - ConfigPropertiesUtil.getString( + ConfigPropertiesUtil.getStringOrFallback( GlobalOpenTelemetry.get(), LoggingContextConstants.TRACE_ID, "common", "logging", "trace_id"); public static final String SPAN_ID_KEY = - ConfigPropertiesUtil.getString( + ConfigPropertiesUtil.getStringOrFallback( GlobalOpenTelemetry.get(), LoggingContextConstants.SPAN_ID, "common", "logging", "span_id"); public static final String TRACE_FLAGS_KEY = - ConfigPropertiesUtil.getString( + ConfigPropertiesUtil.getStringOrFallback( GlobalOpenTelemetry.get(), LoggingContextConstants.TRACE_FLAGS, "common", diff --git a/instrumentation/servlet/servlet-common/bootstrap/src/main/java/io/opentelemetry/javaagent/bootstrap/servlet/ExperimentalSnippetHolder.java b/instrumentation/servlet/servlet-common/bootstrap/src/main/java/io/opentelemetry/javaagent/bootstrap/servlet/ExperimentalSnippetHolder.java index 9c1d44b65449..a8033fcceb92 100644 --- a/instrumentation/servlet/servlet-common/bootstrap/src/main/java/io/opentelemetry/javaagent/bootstrap/servlet/ExperimentalSnippetHolder.java +++ b/instrumentation/servlet/servlet-common/bootstrap/src/main/java/io/opentelemetry/javaagent/bootstrap/servlet/ExperimentalSnippetHolder.java @@ -20,7 +20,7 @@ private static String getSnippetSetting() { // instrumentations, so we need to handle both declarative and non-declarative configs here ConfigPropertiesUtil.isDeclarativeConfig(openTelemetry) ? ConfigPropertiesUtil.getString( - openTelemetry, null, "servlet", "experimental", "javascript-snippet") + openTelemetry, "servlet", "experimental", "javascript-snippet") : ConfigPropertiesUtil.getString("otel.experimental.javascript-snippet"); return result == null ? "" : result; } From fea44fa82af9d2d653f161d0b0231b5b06ff9fbf Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Tue, 18 Nov 2025 10:46:37 +0100 Subject: [PATCH 19/79] remove contract --- .../instrumentation/api/internal/ConfigPropertiesUtil.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java index 45f8a739c21a..09971e145356 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java @@ -86,7 +86,7 @@ public static int getInt(String propertyName, int defaultValue) { * Returns the string value of the given property name from system properties and environment * variables. * - *

It's recommended to use {@link #getString(OpenTelemetry, String, String...)} instead to + *

It's recommended to use {@link #getString(OpenTelemetry, String...)} instead to * support Declarative Config. */ @Nullable From 29b691ecf34e81f9cd94fffbef2aedae1e98f452 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Tue, 18 Nov 2025 10:53:43 +0100 Subject: [PATCH 20/79] inline method to avoid class not found exception for DeclarativeConfigProperties --- .../api/internal/ConfigPropertiesUtil.java | 55 ++++++++----------- 1 file changed, 23 insertions(+), 32 deletions(-) diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java index 09971e145356..edd6bd0754ae 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java @@ -14,8 +14,6 @@ import java.util.Arrays; import java.util.List; import java.util.Locale; -import java.util.function.BiFunction; -import java.util.function.Function; import java.util.stream.Collectors; import javax.annotation.Nullable; @@ -59,11 +57,11 @@ public static boolean getBoolean(String propertyName, boolean defaultValue) { */ public static boolean getBoolean( OpenTelemetry openTelemetry, boolean defaultValue, String... propertyName) { - return getDeclarativeConfigOrFallback( - openTelemetry, - propertyName, - (node, key) -> node.getBoolean(key, defaultValue), - (key) -> getBoolean(key, defaultValue)); + DeclarativeConfigProperties node = getDeclarativeConfigNode(openTelemetry, propertyName); + if (node != null) { + return node.getBoolean(leaf(propertyName), defaultValue); + } + return getBoolean(toSystemProperty(propertyName), defaultValue); } /** @@ -86,8 +84,8 @@ public static int getInt(String propertyName, int defaultValue) { * Returns the string value of the given property name from system properties and environment * variables. * - *

It's recommended to use {@link #getString(OpenTelemetry, String...)} instead to - * support Declarative Config. + *

It's recommended to use {@link #getString(OpenTelemetry, String...)} instead to support + * Declarative Config. */ @Nullable public static String getString(String propertyName) { @@ -104,8 +102,11 @@ public static String getString(String propertyName) { */ @Nullable public static String getString(OpenTelemetry openTelemetry, String... propertyName) { - return getDeclarativeConfigOrFallback( - openTelemetry, propertyName, (node, key) -> node.getString(key), (key) -> getString(key)); + DeclarativeConfigProperties node = getDeclarativeConfigNode(openTelemetry, propertyName); + if (node != null) { + return node.getString(leaf(propertyName)); + } + return getString(toSystemProperty(propertyName)); } /** @@ -127,17 +128,15 @@ public static String getStringOrFallback( */ public static List getList( OpenTelemetry openTelemetry, List defaultValue, String... propertyName) { - return getDeclarativeConfigOrFallback( - openTelemetry, - propertyName, - (node, key) -> node.getScalarList(key, String.class, defaultValue), - (key) -> { - String value = getString(key); - if (value == null) { - return defaultValue; - } - return filterBlanksAndNulls(value.split(",")); - }); + DeclarativeConfigProperties node = getDeclarativeConfigNode(openTelemetry, propertyName); + if (node != null) { + return node.getScalarList(leaf(propertyName), String.class, defaultValue); + } + String value = getString(toSystemProperty(propertyName)); + if (value == null) { + return defaultValue; + } + return filterBlanksAndNulls(value.split(",")); } /** Returns true if the given OpenTelemetry instance supports Declarative Config. */ @@ -156,16 +155,8 @@ private static String toEnvVarName(String propertyName) { return propertyName.toUpperCase(Locale.ROOT).replace('-', '_').replace('.', '_'); } - private static T getDeclarativeConfigOrFallback( - OpenTelemetry openTelemetry, - String[] propertyName, - BiFunction getter, - Function fallback) { - DeclarativeConfigProperties node = getDeclarativeConfigNode(openTelemetry, propertyName); - if (node != null) { - return getter.apply(node, propertyName[propertyName.length - 1]); - } - return fallback.apply(toSystemProperty(propertyName)); + private static String leaf(String[] propertyName) { + return propertyName[propertyName.length - 1]; } @Nullable From bf79af8ed794bd4d6a21b0306c1f2317c7ed6d87 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Tue, 25 Nov 2025 08:18:58 +0100 Subject: [PATCH 21/79] pr review --- .../instrumentation/api/internal/ConfigPropertiesUtil.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java index edd6bd0754ae..df207d752aa5 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java @@ -23,9 +23,9 @@ */ public final class ConfigPropertiesUtil { - private static final boolean isIncubator = isIncubator(); + private static final boolean supportsDeclarativeConfig = supportsDeclarativeConfig(); - private static boolean isIncubator() { + private static boolean supportsDeclarativeConfig() { try { Class.forName("io.opentelemetry.api.incubator.ExtendedOpenTelemetry"); return true; @@ -141,7 +141,7 @@ public static List getList( /** Returns true if the given OpenTelemetry instance supports Declarative Config. */ public static boolean isDeclarativeConfig(OpenTelemetry openTelemetry) { - return isIncubator && openTelemetry instanceof ExtendedOpenTelemetry; + return supportsDeclarativeConfig && openTelemetry instanceof ExtendedOpenTelemetry; } private static List filterBlanksAndNulls(String[] values) { From b3148b2cf676fbfdfa0d0252ee5a295df026ef31 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Tue, 25 Nov 2025 08:41:54 +0100 Subject: [PATCH 22/79] use optional instead of providing default for boolean --- .../api/internal/ConfigPropertiesUtil.java | 17 ++++++++--------- .../api/internal/ContextPropagationDebug.java | 9 ++++++--- .../api/internal/SupportabilityMetrics.java | 2 +- .../api/internal/ConfigPropertiesUtilTest.java | 11 +++++++---- .../autoconfigure/TracingRequestHandler.java | 6 ++++-- .../v2_2/autoconfigure/AwsSdkSingletons.java | 14 +++++++------- .../awssdk/v2_2/AbstractAws2ClientCoreTest.java | 3 ++- .../AbstractAws2ClientRecordHttpErrorTest.java | 3 ++- .../awssdk/v2_2/AbstractAws2SqsBaseTest.java | 3 ++- .../jdbc/OpenTelemetryDriver.java | 6 ++++-- .../jdbc/internal/JdbcInstrumenterFactory.java | 9 ++++++--- .../v2_6/TracingConsumerInterceptor.java | 8 ++------ .../v2_17/OpenTelemetryContextDataProvider.java | 4 +++- .../javaagent/bootstrap/AgentInitializer.java | 2 +- .../tooling/SpanLoggingCustomizerProvider.java | 2 +- .../tooling/config/EarlyInitAgentConfig.java | 2 +- 16 files changed, 57 insertions(+), 44 deletions(-) diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java index df207d752aa5..2bef34221e31 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java @@ -14,6 +14,7 @@ import java.util.Arrays; import java.util.List; import java.util.Locale; +import java.util.Optional; import java.util.stream.Collectors; import javax.annotation.Nullable; @@ -43,25 +44,23 @@ private static boolean supportsDeclarativeConfig() { * Returns the boolean value of the given property name from system properties and environment * variables. * - *

It's recommended to use {@link #getBoolean(OpenTelemetry, boolean, String...)} instead to - * support Declarative Config. + *

It's recommended to use {@link #getBoolean(OpenTelemetry, String...)} instead to support + * Declarative Config. */ - public static boolean getBoolean(String propertyName, boolean defaultValue) { - String strValue = getString(propertyName); - return strValue == null ? defaultValue : Boolean.parseBoolean(strValue); + public static Optional getBoolean(String propertyName) { + return Optional.ofNullable(getString(propertyName)).map(Boolean::parseBoolean); } /** * Returns the boolean value of the given property name from Declarative Config if available, * otherwise falls back to system properties and environment variables. */ - public static boolean getBoolean( - OpenTelemetry openTelemetry, boolean defaultValue, String... propertyName) { + public static Optional getBoolean(OpenTelemetry openTelemetry, String... propertyName) { DeclarativeConfigProperties node = getDeclarativeConfigNode(openTelemetry, propertyName); if (node != null) { - return node.getBoolean(leaf(propertyName), defaultValue); + return Optional.ofNullable(node.getBoolean(leaf(propertyName))); } - return getBoolean(toSystemProperty(propertyName), defaultValue); + return getBoolean(toSystemProperty(propertyName)); } /** diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ContextPropagationDebug.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ContextPropagationDebug.java index cf698069fc05..4e74e7c50522 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ContextPropagationDebug.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ContextPropagationDebug.java @@ -32,13 +32,16 @@ public final class ContextPropagationDebug { private static final boolean FAIL_ON_CONTEXT_LEAK; static { - boolean agentDebugEnabled = ConfigPropertiesUtil.getBoolean("otel.javaagent.debug", false); + boolean agentDebugEnabled = + ConfigPropertiesUtil.getBoolean("otel.javaagent.debug").orElse(false); THREAD_PROPAGATION_DEBUGGER = ConfigPropertiesUtil.getBoolean( - "otel.javaagent.experimental.thread-propagation-debugger.enabled", agentDebugEnabled); + "otel.javaagent.experimental.thread-propagation-debugger.enabled") + .orElse(agentDebugEnabled); FAIL_ON_CONTEXT_LEAK = - ConfigPropertiesUtil.getBoolean("otel.javaagent.testing.fail-on-context-leak", false); + ConfigPropertiesUtil.getBoolean("otel.javaagent.testing.fail-on-context-leak") + .orElse(false); } // context to which debug locations were added diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/SupportabilityMetrics.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/SupportabilityMetrics.java index cf91c4274c32..4e4130c4824c 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/SupportabilityMetrics.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/SupportabilityMetrics.java @@ -30,7 +30,7 @@ public final class SupportabilityMetrics { private static final SupportabilityMetrics INSTANCE = new SupportabilityMetrics( - ConfigPropertiesUtil.getBoolean("otel.javaagent.debug", false), logger::fine) + ConfigPropertiesUtil.getBoolean("otel.javaagent.debug").orElse(false), logger::fine) .start(); public static SupportabilityMetrics instance() { diff --git a/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java b/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java index 8985c67ca95f..e844a6caab75 100644 --- a/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java +++ b/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java @@ -132,11 +132,13 @@ void getBoolean_none() { } private static void assertBoolean(boolean expected) { - assertThat(ConfigPropertiesUtil.getBoolean("otel.instrumentation.test.property.boolean", false)) + assertThat( + ConfigPropertiesUtil.getBoolean("otel.instrumentation.test.property.boolean") + .orElse(false)) .isEqualTo(expected); assertThat( - ConfigPropertiesUtil.getBoolean( - OpenTelemetry.noop(), false, "test", "property", "boolean")) + ConfigPropertiesUtil.getBoolean(OpenTelemetry.noop(), "test", "property", "boolean") + .orElse(false)) .isEqualTo(expected); } @@ -154,7 +156,8 @@ public static Stream booleanValuesProvider() { void getBoolean_declarativeConfig(Object property, boolean expected) { assertThat( ConfigPropertiesUtil.getBoolean( - DeclarativeConfiguration.create(model(property)), false, "foo", "bar")) + DeclarativeConfiguration.create(model(property)), "foo", "bar") + .orElse(false)) .isEqualTo(expected); } diff --git a/instrumentation/aws-sdk/aws-sdk-1.11/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v1_11/autoconfigure/TracingRequestHandler.java b/instrumentation/aws-sdk/aws-sdk-1.11/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v1_11/autoconfigure/TracingRequestHandler.java index 8900f1d89764..ea449e6e6ddb 100644 --- a/instrumentation/aws-sdk/aws-sdk-1.11/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v1_11/autoconfigure/TracingRequestHandler.java +++ b/instrumentation/aws-sdk/aws-sdk-1.11/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v1_11/autoconfigure/TracingRequestHandler.java @@ -27,10 +27,12 @@ private static RequestHandler2 buildDelegate(OpenTelemetry openTelemetry) { return AwsSdkTelemetry.builder(openTelemetry) .setCaptureExperimentalSpanAttributes( ConfigPropertiesUtil.getBoolean( - openTelemetry, false, "aws_sdk", "experimental_span_attributes")) + openTelemetry, "aws_sdk", "experimental_span_attributes") + .orElse(false)) .setMessagingReceiveInstrumentationEnabled( ConfigPropertiesUtil.getBoolean( - openTelemetry, false, "messaging", "experimental", "receive_telemetry", "enabled")) + openTelemetry, "messaging", "experimental", "receive_telemetry", "enabled") + .orElse(false)) .setCapturedHeaders( ConfigPropertiesUtil.getList( openTelemetry, emptyList(), "messaging", "experimental", "capture_headers")) diff --git a/instrumentation/aws-sdk/aws-sdk-2.2/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/autoconfigure/AwsSdkSingletons.java b/instrumentation/aws-sdk/aws-sdk-2.2/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/autoconfigure/AwsSdkSingletons.java index 4d4dd601e631..60d9a167de99 100644 --- a/instrumentation/aws-sdk/aws-sdk-2.2/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/autoconfigure/AwsSdkSingletons.java +++ b/instrumentation/aws-sdk/aws-sdk-2.2/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/autoconfigure/AwsSdkSingletons.java @@ -32,17 +32,17 @@ protected List getCapturedHeaders() { @Override protected boolean messagingReceiveInstrumentationEnabled() { return ConfigPropertiesUtil.getBoolean( - GlobalOpenTelemetry.get(), - false, - "messaging", - "experimental", - "receive_telemetry", - "enabled"); + GlobalOpenTelemetry.get(), + "messaging", + "experimental", + "receive_telemetry", + "enabled") + .orElse(false); } @Override protected boolean getBoolean(boolean defaultValue, String... name) { - return ConfigPropertiesUtil.getBoolean(GlobalOpenTelemetry.get(), defaultValue, name); + return ConfigPropertiesUtil.getBoolean(GlobalOpenTelemetry.get(), name).orElse(defaultValue); } } diff --git a/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2ClientCoreTest.java b/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2ClientCoreTest.java index f34767d4a771..de9de748436f 100644 --- a/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2ClientCoreTest.java +++ b/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2ClientCoreTest.java @@ -101,7 +101,8 @@ public abstract class AbstractAws2ClientCoreTest { protected static boolean isSqsAttributeInjectionEnabled() { // See io.opentelemetry.instrumentation.awssdk.v2_2.autoconfigure.TracingExecutionInterceptor return ConfigPropertiesUtil.getBoolean( - "otel.instrumentation.aws-sdk.experimental-use-propagator-for-messaging", false); + "otel.instrumentation.aws-sdk.experimental-use-propagator-for-messaging") + .orElse(false); } protected void configureSdkClient(SdkClientBuilder builder) { diff --git a/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2ClientRecordHttpErrorTest.java b/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2ClientRecordHttpErrorTest.java index 582af3e4a941..9825935d4b9c 100644 --- a/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2ClientRecordHttpErrorTest.java +++ b/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2ClientRecordHttpErrorTest.java @@ -126,7 +126,8 @@ private static void cleanResponses() { public boolean isRecordIndividualHttpErrorEnabled() { // See io.opentelemetry.instrumentation.awssdk.v2_2.autoconfigure.TracingExecutionInterceptor return ConfigPropertiesUtil.getBoolean( - "otel.instrumentation.aws-sdk.experimental-record-individual-http-error", false); + "otel.instrumentation.aws-sdk.experimental-record-individual-http-error") + .orElse(false); } @SuppressWarnings("deprecation") // using deprecated semconv diff --git a/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2SqsBaseTest.java b/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2SqsBaseTest.java index 3fb1636d551a..fd435a84c6b2 100644 --- a/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2SqsBaseTest.java +++ b/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2SqsBaseTest.java @@ -132,7 +132,8 @@ protected void configureSdkClient(SqsAsyncClientBuilder builder) throws URISynta protected boolean isSqsAttributeInjectionEnabled() { // See io.opentelemetry.instrumentation.awssdk.v2_2.autoconfigure.TracingExecutionInterceptor return ConfigPropertiesUtil.getBoolean( - "otel.instrumentation.aws-sdk.experimental-use-propagator-for-messaging", false); + "otel.instrumentation.aws-sdk.experimental-use-propagator-for-messaging") + .orElse(false); } @BeforeAll diff --git a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/OpenTelemetryDriver.java b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/OpenTelemetryDriver.java index dd8ed9c3a219..1a4a2803bf66 100644 --- a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/OpenTelemetryDriver.java +++ b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/OpenTelemetryDriver.java @@ -66,11 +66,13 @@ public final class OpenTelemetryDriver implements Driver { private static SqlCommenter getSqlCommenter(OpenTelemetry openTelemetry) { boolean defaultValue = ConfigPropertiesUtil.getBoolean( - openTelemetry, false, "common", "experimental", "db_sqlcommenter", "enabled"); + openTelemetry, "common", "experimental", "db_sqlcommenter", "enabled") + .orElse(false); return SqlCommenter.builder() .setEnabled( ConfigPropertiesUtil.getBoolean( - openTelemetry, defaultValue, "jdbc", "experimental", "sqlcommenter", "enabled")) + openTelemetry, "jdbc", "experimental", "sqlcommenter", "enabled") + .orElse(defaultValue)) .build(); } diff --git a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/JdbcInstrumenterFactory.java b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/JdbcInstrumenterFactory.java index 07c08fbd34e4..f810a8d345ad 100644 --- a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/JdbcInstrumenterFactory.java +++ b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/JdbcInstrumenterFactory.java @@ -30,7 +30,8 @@ public final class JdbcInstrumenterFactory { public static boolean captureQueryParameters(OpenTelemetry openTelemetry) { return ConfigPropertiesUtil.getBoolean( - openTelemetry, false, "jdbc", "experimental", "capture_query_parameters"); + openTelemetry, "jdbc", "experimental", "capture_query_parameters") + .orElse(false); } public static Instrumenter createStatementInstrumenter( @@ -45,7 +46,8 @@ static Instrumenter createStatementInstrumenter( emptyList(), true, ConfigPropertiesUtil.getBoolean( - openTelemetry, true, "common", "db_statement_sanitizer", "enabled"), + openTelemetry, "common", "db_statement_sanitizer", "enabled") + .orElse(true), captureQueryParameters); } @@ -95,7 +97,8 @@ public static Instrumenter createTransactionInstrumenter( return createTransactionInstrumenter( openTelemetry, ConfigPropertiesUtil.getBoolean( - openTelemetry, false, "jdbc", "experimental", "transaction", "enabled")); + openTelemetry, "jdbc", "experimental", "transaction", "enabled") + .orElse(false)); } public static Instrumenter createTransactionInstrumenter( diff --git a/instrumentation/kafka/kafka-clients/kafka-clients-2.6/library/src/main/java/io/opentelemetry/instrumentation/kafkaclients/v2_6/TracingConsumerInterceptor.java b/instrumentation/kafka/kafka-clients/kafka-clients-2.6/library/src/main/java/io/opentelemetry/instrumentation/kafkaclients/v2_6/TracingConsumerInterceptor.java index cce4f94f7e79..1828f97ec8de 100644 --- a/instrumentation/kafka/kafka-clients/kafka-clients-2.6/library/src/main/java/io/opentelemetry/instrumentation/kafkaclients/v2_6/TracingConsumerInterceptor.java +++ b/instrumentation/kafka/kafka-clients/kafka-clients-2.6/library/src/main/java/io/opentelemetry/instrumentation/kafkaclients/v2_6/TracingConsumerInterceptor.java @@ -41,12 +41,8 @@ public class TracingConsumerInterceptor implements ConsumerInterceptor staticContextData = getStaticContextData(); diff --git a/javaagent-bootstrap/src/main/java/io/opentelemetry/javaagent/bootstrap/AgentInitializer.java b/javaagent-bootstrap/src/main/java/io/opentelemetry/javaagent/bootstrap/AgentInitializer.java index 509d13964d3b..dcd41a32e83e 100644 --- a/javaagent-bootstrap/src/main/java/io/opentelemetry/javaagent/bootstrap/AgentInitializer.java +++ b/javaagent-bootstrap/src/main/java/io/opentelemetry/javaagent/bootstrap/AgentInitializer.java @@ -94,7 +94,7 @@ private static boolean getBoolean(String property, boolean defaultValue) { new PrivilegedAction() { @Override public Boolean run() { - return ConfigPropertiesUtil.getBoolean(property, defaultValue); + return ConfigPropertiesUtil.getBoolean(property).orElse(defaultValue); } }); } diff --git a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/SpanLoggingCustomizerProvider.java b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/SpanLoggingCustomizerProvider.java index 00634e858503..14d0fde72e97 100644 --- a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/SpanLoggingCustomizerProvider.java +++ b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/SpanLoggingCustomizerProvider.java @@ -19,6 +19,6 @@ public class SpanLoggingCustomizerProvider extends AbstractSpanLoggingCustomizer protected boolean isEnabled(OpenTelemetryConfigurationModel model) { // read from system properties as it's an early init property and the config bridge is not // available here - return ConfigPropertiesUtil.getBoolean("otel.javaagent.debug", false); + return ConfigPropertiesUtil.getBoolean("otel.javaagent.debug").orElse(false); } } diff --git a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/EarlyInitAgentConfig.java b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/EarlyInitAgentConfig.java index d39f1b9cfd6a..3e4a601877e2 100644 --- a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/EarlyInitAgentConfig.java +++ b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/EarlyInitAgentConfig.java @@ -38,7 +38,7 @@ public boolean getBoolean(String propertyName, boolean defaultValue) { String configFileValueStr = configFileContents.get(propertyName); boolean configFileValue = configFileValueStr == null ? defaultValue : Boolean.parseBoolean(configFileValueStr); - return ConfigPropertiesUtil.getBoolean(propertyName, configFileValue); + return ConfigPropertiesUtil.getBoolean(propertyName).orElse(configFileValue); } public int getInt(String propertyName, int defaultValue) { From 77e228ebc21a67ddf293d12a9922e97ca3a51510 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Tue, 25 Nov 2025 08:49:28 +0100 Subject: [PATCH 23/79] use optional instead of providing default for int --- .../api/internal/ConfigPropertiesUtil.java | 20 +++++++++---------- .../internal/ConfigPropertiesUtilTest.java | 8 ++++---- .../tooling/config/EarlyInitAgentConfig.java | 2 +- 3 files changed, 15 insertions(+), 15 deletions(-) diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java index 2bef34221e31..99ef4708a1a2 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java @@ -67,16 +67,16 @@ public static Optional getBoolean(OpenTelemetry openTelemetry, String.. * Returns the int value of the given property name from system properties and environment * variables. */ - public static int getInt(String propertyName, int defaultValue) { - String strValue = getString(propertyName); - if (strValue == null) { - return defaultValue; - } - try { - return Integer.parseInt(strValue); - } catch (NumberFormatException ignored) { - return defaultValue; - } + public static Optional getInt(String propertyName) { + return Optional.ofNullable(getString(propertyName)) + .flatMap( + s -> { + try { + return Optional.of(Integer.parseInt(s)); + } catch (NumberFormatException ignored) { + return Optional.empty(); + } + }); } /** diff --git a/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java b/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java index e844a6caab75..e10354052693 100644 --- a/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java +++ b/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java @@ -93,24 +93,24 @@ void getString_declarativeConfig(Object property, String expected) { @SetSystemProperty(key = "test.property.int", value = "42") @Test void getInt_systemProperty() { - assertThat(ConfigPropertiesUtil.getInt("test.property.int", -1)).isEqualTo(42); + assertThat(ConfigPropertiesUtil.getInt("test.property.int")).hasValue(42); } @SetEnvironmentVariable(key = "TEST_PROPERTY_INT", value = "12") @Test void getInt_environmentVariable() { - assertThat(ConfigPropertiesUtil.getInt("test.property.int", -1)).isEqualTo(12); + assertThat(ConfigPropertiesUtil.getInt("test.property.int")).hasValue(12); } @Test void getInt_none() { - assertThat(ConfigPropertiesUtil.getInt("test.property.int", -1)).isEqualTo(-1); + assertThat(ConfigPropertiesUtil.getInt("test.property.int")).isEmpty(); } @SetSystemProperty(key = "test.property.int", value = "not a number") @Test void getInt_invalidNumber() { - assertThat(ConfigPropertiesUtil.getInt("test.property.int", -1)).isEqualTo(-1); + assertThat(ConfigPropertiesUtil.getInt("test.property.int")).isEmpty(); } @SetEnvironmentVariable(key = "OTEL_INSTRUMENTATION_TEST_PROPERTY_BOOLEAN", value = "false") diff --git a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/EarlyInitAgentConfig.java b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/EarlyInitAgentConfig.java index 3e4a601877e2..b1ee741a9e8e 100644 --- a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/EarlyInitAgentConfig.java +++ b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/EarlyInitAgentConfig.java @@ -46,7 +46,7 @@ public int getInt(String propertyName, int defaultValue) { String configFileValueStr = configFileContents.get(propertyName); int configFileValue = configFileValueStr == null ? defaultValue : Integer.parseInt(configFileValueStr); - return ConfigPropertiesUtil.getInt(propertyName, configFileValue); + return ConfigPropertiesUtil.getInt(propertyName).orElse(configFileValue); } catch (NumberFormatException ignored) { return defaultValue; } From 516fce8f8184d59f44a3c90a32b8b092156e6bbc Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Tue, 25 Nov 2025 08:51:21 +0100 Subject: [PATCH 24/79] use optional instead of providing default for list --- .../api/internal/ConfigPropertiesUtil.java | 8 ++++---- .../api/internal/ConfigPropertiesUtilTest.java | 6 ++---- .../awssdk/v1_11/autoconfigure/TracingRequestHandler.java | 4 +--- .../awssdk/v2_2/autoconfigure/AwsSdkSingletons.java | 4 +--- .../kafkaclients/v2_6/TracingConsumerInterceptor.java | 4 +--- .../kafkaclients/v2_6/TracingProducerInterceptor.java | 4 +--- 6 files changed, 10 insertions(+), 20 deletions(-) diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java index 99ef4708a1a2..feccde0e4c84 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java @@ -6,6 +6,7 @@ package io.opentelemetry.instrumentation.api.internal; import static io.opentelemetry.api.incubator.config.DeclarativeConfigProperties.empty; +import static java.util.Collections.emptyList; import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.api.incubator.ExtendedOpenTelemetry; @@ -125,15 +126,14 @@ public static String getStringOrFallback( * Returns the list of strings value of the given property name from Declarative Config if * available, otherwise falls back to system properties and environment variables. */ - public static List getList( - OpenTelemetry openTelemetry, List defaultValue, String... propertyName) { + public static List getList(OpenTelemetry openTelemetry, String... propertyName) { DeclarativeConfigProperties node = getDeclarativeConfigNode(openTelemetry, propertyName); if (node != null) { - return node.getScalarList(leaf(propertyName), String.class, defaultValue); + return node.getScalarList(leaf(propertyName), String.class, emptyList()); } String value = getString(toSystemProperty(propertyName)); if (value == null) { - return defaultValue; + return emptyList(); } return filterBlanksAndNulls(value.split(",")); } diff --git a/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java b/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java index e10354052693..2500f6227ce0 100644 --- a/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java +++ b/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java @@ -199,9 +199,7 @@ void getList_none() { } private static void assertList(List expected) { - assertThat( - ConfigPropertiesUtil.getList( - OpenTelemetry.noop(), emptyList(), "test", "property", "list")) + assertThat(ConfigPropertiesUtil.getList(OpenTelemetry.noop(), "test", "property", "list")) .isEqualTo(expected); } @@ -219,7 +217,7 @@ public static Stream listValuesProvider() { void getList_declarativeConfig(Object property, List expected) { assertThat( ConfigPropertiesUtil.getList( - DeclarativeConfiguration.create(model(property)), emptyList(), "foo", "bar")) + DeclarativeConfiguration.create(model(property)), "foo", "bar")) .isEqualTo(expected); } } diff --git a/instrumentation/aws-sdk/aws-sdk-1.11/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v1_11/autoconfigure/TracingRequestHandler.java b/instrumentation/aws-sdk/aws-sdk-1.11/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v1_11/autoconfigure/TracingRequestHandler.java index ea449e6e6ddb..d7a81f290725 100644 --- a/instrumentation/aws-sdk/aws-sdk-1.11/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v1_11/autoconfigure/TracingRequestHandler.java +++ b/instrumentation/aws-sdk/aws-sdk-1.11/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v1_11/autoconfigure/TracingRequestHandler.java @@ -5,8 +5,6 @@ package io.opentelemetry.instrumentation.awssdk.v1_11.autoconfigure; -import static java.util.Collections.emptyList; - import com.amazonaws.AmazonWebServiceRequest; import com.amazonaws.Request; import com.amazonaws.Response; @@ -35,7 +33,7 @@ private static RequestHandler2 buildDelegate(OpenTelemetry openTelemetry) { .orElse(false)) .setCapturedHeaders( ConfigPropertiesUtil.getList( - openTelemetry, emptyList(), "messaging", "experimental", "capture_headers")) + openTelemetry, "messaging", "experimental", "capture_headers")) .build() .newRequestHandler(); } diff --git a/instrumentation/aws-sdk/aws-sdk-2.2/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/autoconfigure/AwsSdkSingletons.java b/instrumentation/aws-sdk/aws-sdk-2.2/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/autoconfigure/AwsSdkSingletons.java index 60d9a167de99..cf5b7b1daada 100644 --- a/instrumentation/aws-sdk/aws-sdk-2.2/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/autoconfigure/AwsSdkSingletons.java +++ b/instrumentation/aws-sdk/aws-sdk-2.2/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/autoconfigure/AwsSdkSingletons.java @@ -5,8 +5,6 @@ package io.opentelemetry.instrumentation.awssdk.v2_2.autoconfigure; -import static java.util.Collections.emptyList; - import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.instrumentation.api.internal.ConfigPropertiesUtil; import io.opentelemetry.instrumentation.awssdk.v2_2.AwsSdkTelemetry; @@ -26,7 +24,7 @@ private static class AwsSdkTelemetryFactory extends AbstractAwsSdkTelemetryFacto @Override protected List getCapturedHeaders() { return ConfigPropertiesUtil.getList( - GlobalOpenTelemetry.get(), emptyList(), "messaging", "experimental", "capture_headers"); + GlobalOpenTelemetry.get(), "messaging", "experimental", "capture_headers"); } @Override diff --git a/instrumentation/kafka/kafka-clients/kafka-clients-2.6/library/src/main/java/io/opentelemetry/instrumentation/kafkaclients/v2_6/TracingConsumerInterceptor.java b/instrumentation/kafka/kafka-clients/kafka-clients-2.6/library/src/main/java/io/opentelemetry/instrumentation/kafkaclients/v2_6/TracingConsumerInterceptor.java index 1828f97ec8de..08b6f0bdd5b9 100644 --- a/instrumentation/kafka/kafka-clients/kafka-clients-2.6/library/src/main/java/io/opentelemetry/instrumentation/kafkaclients/v2_6/TracingConsumerInterceptor.java +++ b/instrumentation/kafka/kafka-clients/kafka-clients-2.6/library/src/main/java/io/opentelemetry/instrumentation/kafkaclients/v2_6/TracingConsumerInterceptor.java @@ -5,8 +5,6 @@ package io.opentelemetry.instrumentation.kafkaclients.v2_6; -import static java.util.Collections.emptyList; - import com.google.errorprone.annotations.CanIgnoreReturnValue; import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.OpenTelemetry; @@ -45,7 +43,7 @@ public class TracingConsumerInterceptor implements ConsumerInterceptor implements ProducerInterceptor Date: Tue, 25 Nov 2025 09:05:46 +0100 Subject: [PATCH 25/79] use optional instead of providing default for string --- .../api/instrumenter/InstrumenterBuilder.java | 6 ++- .../api/internal/ConfigPropertiesUtil.java | 37 +++++-------------- .../api/internal/SemconvStability.java | 2 +- .../internal/ConfigPropertiesUtilTest.java | 16 ++++---- .../v2_17/internal/ContextDataKeys.java | 26 ++++--------- .../servlet/ExperimentalSnippetHolder.java | 5 ++- .../tooling/config/ConfigurationFile.java | 3 +- .../tooling/config/EarlyInitAgentConfig.java | 7 +--- 8 files changed, 39 insertions(+), 63 deletions(-) diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/InstrumenterBuilder.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/InstrumenterBuilder.java index 11801a509c5d..a7875bf96e3c 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/InstrumenterBuilder.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/InstrumenterBuilder.java @@ -373,9 +373,11 @@ SpanSuppressor buildSpanSuppressor() { String value = ConfigPropertiesUtil.isDeclarativeConfig(openTelemetry) ? ConfigPropertiesUtil.getString( - openTelemetry, "common", "experimental", "span_suppression_strategy") + openTelemetry, "common", "experimental", "span_suppression_strategy") + .orElse(null) : ConfigPropertiesUtil.getString( - "otel.instrumentation.experimental.span-suppression-strategy"); + "otel.instrumentation.experimental.span-suppression-strategy") + .orElse(null); return new SpanSuppressors.ByContextKey( SpanSuppressionStrategy.fromConfig(value).create(getSpanKeysFromAttributesExtractors())); } diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java index feccde0e4c84..7ad30e2f00e8 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java @@ -49,7 +49,7 @@ private static boolean supportsDeclarativeConfig() { * Declarative Config. */ public static Optional getBoolean(String propertyName) { - return Optional.ofNullable(getString(propertyName)).map(Boolean::parseBoolean); + return getString(propertyName).map(Boolean::parseBoolean); } /** @@ -69,7 +69,7 @@ public static Optional getBoolean(OpenTelemetry openTelemetry, String.. * variables. */ public static Optional getInt(String propertyName) { - return Optional.ofNullable(getString(propertyName)) + return getString(propertyName) .flatMap( s -> { try { @@ -87,41 +87,26 @@ public static Optional getInt(String propertyName) { *

It's recommended to use {@link #getString(OpenTelemetry, String...)} instead to support * Declarative Config. */ - @Nullable - public static String getString(String propertyName) { + public static Optional getString(String propertyName) { String value = System.getProperty(propertyName); if (value != null) { - return value; + return Optional.of(value); } - return System.getenv(toEnvVarName(propertyName)); + return Optional.ofNullable(System.getenv(toEnvVarName(propertyName))); } /** * Returns the string value of the given property name from Declarative Config if available, * otherwise falls back to system properties and environment variables. */ - @Nullable - public static String getString(OpenTelemetry openTelemetry, String... propertyName) { + public static Optional getString(OpenTelemetry openTelemetry, String... propertyName) { DeclarativeConfigProperties node = getDeclarativeConfigNode(openTelemetry, propertyName); if (node != null) { - return node.getString(leaf(propertyName)); + return Optional.ofNullable(node.getString(leaf(propertyName))); } return getString(toSystemProperty(propertyName)); } - /** - * Returns the string value of the given property name from Declarative Config if available, - * otherwise falls back to system properties and environment variables. - */ - public static String getStringOrFallback( - OpenTelemetry openTelemetry, String defaultValue, String... propertyName) { - String value = getString(openTelemetry, propertyName); - if (value == null) { - return defaultValue; - } - return value; - } - /** * Returns the list of strings value of the given property name from Declarative Config if * available, otherwise falls back to system properties and environment variables. @@ -131,11 +116,9 @@ public static List getList(OpenTelemetry openTelemetry, String... proper if (node != null) { return node.getScalarList(leaf(propertyName), String.class, emptyList()); } - String value = getString(toSystemProperty(propertyName)); - if (value == null) { - return emptyList(); - } - return filterBlanksAndNulls(value.split(",")); + return getString(toSystemProperty(propertyName)) + .map(value -> filterBlanksAndNulls(value.split(","))) + .orElse(emptyList()); } /** Returns true if the given OpenTelemetry instance supports Declarative Config. */ diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/SemconvStability.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/SemconvStability.java index e54a62530b67..bc76ae088bab 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/SemconvStability.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/SemconvStability.java @@ -31,7 +31,7 @@ public final class SemconvStability { boolean oldCode = true; boolean stableCode = false; - String value = ConfigPropertiesUtil.getString("otel.semconv-stability.opt-in"); + String value = ConfigPropertiesUtil.getString("otel.semconv-stability.opt-in").orElse(null); if (value != null) { Set values = new HashSet<>(asList(value.split(","))); diff --git a/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java b/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java index 2500f6227ce0..5de2f0b87f3e 100644 --- a/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java +++ b/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java @@ -32,18 +32,18 @@ class ConfigPropertiesUtilTest { @SetSystemProperty(key = "test.property.string", value = "sys") @Test void getString_systemProperty() { - assertThat(ConfigPropertiesUtil.getString("test.property.string")).isEqualTo("sys"); + assertThat(ConfigPropertiesUtil.getString("test.property.string")).hasValue("sys"); } @SetEnvironmentVariable(key = "TEST_PROPERTY_STRING", value = "env") @Test void getString_environmentVariable() { - assertThat(ConfigPropertiesUtil.getString("test.property.string")).isEqualTo("env"); + assertThat(ConfigPropertiesUtil.getString("test.property.string")).hasValue("env"); } @Test void getString_none() { - assertThat(ConfigPropertiesUtil.getString("test.property.string")).isNull(); + assertThat(ConfigPropertiesUtil.getString("test.property.string")).isEmpty(); } @SetEnvironmentVariable(key = "OTEL_INSTRUMENTATION_TEST_PROPERTY_STRING", value = "env_value") @@ -66,8 +66,9 @@ void getString_withOpenTelemetry_none() { private static void assertString(String expected) { assertThat( - ConfigPropertiesUtil.getStringOrFallback( - OpenTelemetry.noop(), "default_value", "test", "property", "string")) + ConfigPropertiesUtil.getString( + OpenTelemetry.noop(), new String[] {"test", "property", "string"}) + .orElse("default_value")) .isEqualTo(expected); } @@ -83,9 +84,10 @@ public static Stream stringValuesProvider() { @ParameterizedTest @MethodSource("stringValuesProvider") void getString_declarativeConfig(Object property, String expected) { + OpenTelemetry openTelemetry = DeclarativeConfiguration.create(model(property)); assertThat( - ConfigPropertiesUtil.getStringOrFallback( - DeclarativeConfiguration.create(model(property)), "default_value", "foo", "bar")) + ConfigPropertiesUtil.getString(openTelemetry, new String[] {"foo", "bar"}) + .orElse("default_value")) .isEqualTo(expected); } diff --git a/instrumentation/log4j/log4j-context-data/log4j-context-data-2.17/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/log4j/contextdata/v2_17/internal/ContextDataKeys.java b/instrumentation/log4j/log4j-context-data/log4j-context-data-2.17/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/log4j/contextdata/v2_17/internal/ContextDataKeys.java index 082248d0dff8..ed471c1a155a 100644 --- a/instrumentation/log4j/log4j-context-data/log4j-context-data-2.17/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/log4j/contextdata/v2_17/internal/ContextDataKeys.java +++ b/instrumentation/log4j/log4j-context-data/log4j-context-data-2.17/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/log4j/contextdata/v2_17/internal/ContextDataKeys.java @@ -15,26 +15,16 @@ */ public final class ContextDataKeys { public static final String TRACE_ID_KEY = - ConfigPropertiesUtil.getStringOrFallback( - GlobalOpenTelemetry.get(), - LoggingContextConstants.TRACE_ID, - "common", - "logging", - "trace_id"); + ConfigPropertiesUtil.getString(GlobalOpenTelemetry.get(), "common", "logging", "trace_id") + .orElse(LoggingContextConstants.TRACE_ID); + public static final String SPAN_ID_KEY = - ConfigPropertiesUtil.getStringOrFallback( - GlobalOpenTelemetry.get(), - LoggingContextConstants.SPAN_ID, - "common", - "logging", - "span_id"); + ConfigPropertiesUtil.getString(GlobalOpenTelemetry.get(), "common", "logging", "span_id") + .orElse(LoggingContextConstants.SPAN_ID); + public static final String TRACE_FLAGS_KEY = - ConfigPropertiesUtil.getStringOrFallback( - GlobalOpenTelemetry.get(), - LoggingContextConstants.TRACE_FLAGS, - "common", - "logging", - "trace_flags"); + ConfigPropertiesUtil.getString(GlobalOpenTelemetry.get(), "common", "logging", "trace_flags") + .orElse(LoggingContextConstants.TRACE_FLAGS); private ContextDataKeys() {} } diff --git a/instrumentation/servlet/servlet-common/bootstrap/src/main/java/io/opentelemetry/javaagent/bootstrap/servlet/ExperimentalSnippetHolder.java b/instrumentation/servlet/servlet-common/bootstrap/src/main/java/io/opentelemetry/javaagent/bootstrap/servlet/ExperimentalSnippetHolder.java index a8033fcceb92..cc5f10c40e07 100644 --- a/instrumentation/servlet/servlet-common/bootstrap/src/main/java/io/opentelemetry/javaagent/bootstrap/servlet/ExperimentalSnippetHolder.java +++ b/instrumentation/servlet/servlet-common/bootstrap/src/main/java/io/opentelemetry/javaagent/bootstrap/servlet/ExperimentalSnippetHolder.java @@ -8,6 +8,7 @@ import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.instrumentation.api.internal.ConfigPropertiesUtil; +import java.util.Optional; public class ExperimentalSnippetHolder { @@ -15,14 +16,14 @@ public class ExperimentalSnippetHolder { private static String getSnippetSetting() { OpenTelemetry openTelemetry = GlobalOpenTelemetry.get(); - String result = + Optional result = // otel.experimental.* does not fit the usual pattern of configuration properties for // instrumentations, so we need to handle both declarative and non-declarative configs here ConfigPropertiesUtil.isDeclarativeConfig(openTelemetry) ? ConfigPropertiesUtil.getString( openTelemetry, "servlet", "experimental", "javascript-snippet") : ConfigPropertiesUtil.getString("otel.experimental.javascript-snippet"); - return result == null ? "" : result; + return result.orElse(""); } public static void setSnippet(String newValue) { diff --git a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/ConfigurationFile.java b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/ConfigurationFile.java index 4da9ca45f1fb..ddc6e5f740bf 100644 --- a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/ConfigurationFile.java +++ b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/ConfigurationFile.java @@ -47,7 +47,8 @@ static void resetForTest() { // visible for tests static Map loadConfigFile() { // Reading from system property first and from env after - String configurationFilePath = ConfigPropertiesUtil.getString(CONFIGURATION_FILE_PROPERTY); + String configurationFilePath = + ConfigPropertiesUtil.getString(CONFIGURATION_FILE_PROPERTY).orElse(null); if (configurationFilePath == null) { return emptyMap(); } diff --git a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/EarlyInitAgentConfig.java b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/EarlyInitAgentConfig.java index b1ee741a9e8e..e9bb11bfc780 100644 --- a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/EarlyInitAgentConfig.java +++ b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/EarlyInitAgentConfig.java @@ -27,11 +27,8 @@ private EarlyInitAgentConfig(Map configFileContents) { @Nullable public String getString(String propertyName) { - String value = ConfigPropertiesUtil.getString(propertyName); - if (value != null) { - return value; - } - return configFileContents.get(propertyName); + return ConfigPropertiesUtil.getString(propertyName) + .orElseGet(() -> configFileContents.get(propertyName)); } public boolean getBoolean(String propertyName, boolean defaultValue) { From 42a24951da4952d5be50fd2acd09aa568f631818 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Tue, 25 Nov 2025 10:36:42 +0100 Subject: [PATCH 26/79] fix --- .../api/internal/ConfigPropertiesUtilTest.java | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java b/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java index 5de2f0b87f3e..a25e8ca1f3d9 100644 --- a/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java +++ b/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java @@ -66,8 +66,7 @@ void getString_withOpenTelemetry_none() { private static void assertString(String expected) { assertThat( - ConfigPropertiesUtil.getString( - OpenTelemetry.noop(), new String[] {"test", "property", "string"}) + ConfigPropertiesUtil.getString(OpenTelemetry.noop(), "test", "property", "string") .orElse("default_value")) .isEqualTo(expected); } @@ -85,9 +84,7 @@ public static Stream stringValuesProvider() { @MethodSource("stringValuesProvider") void getString_declarativeConfig(Object property, String expected) { OpenTelemetry openTelemetry = DeclarativeConfiguration.create(model(property)); - assertThat( - ConfigPropertiesUtil.getString(openTelemetry, new String[] {"foo", "bar"}) - .orElse("default_value")) + assertThat(ConfigPropertiesUtil.getString(openTelemetry, "foo", "bar").orElse("default_value")) .isEqualTo(expected); } From 68d05e2a428ce7efb29a05f3ddc0e7d3460f0d9e Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Tue, 25 Nov 2025 17:09:46 +0100 Subject: [PATCH 27/79] fix --- .../api/internal/ConfigPropertiesUtil.java | 26 ++++++++++++------- 1 file changed, 16 insertions(+), 10 deletions(-) diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java index 7ad30e2f00e8..4116d4b03543 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java @@ -49,7 +49,12 @@ private static boolean supportsDeclarativeConfig() { * Declarative Config. */ public static Optional getBoolean(String propertyName) { - return getString(propertyName).map(Boolean::parseBoolean); + Optional string = getString(propertyName); + // lambdas must not be used here in early initialization phase on early JDK8 versions + if (string.isPresent()) { + return Optional.ofNullable(Boolean.parseBoolean(string.get())); + } + return Optional.empty(); } /** @@ -69,15 +74,16 @@ public static Optional getBoolean(OpenTelemetry openTelemetry, String.. * variables. */ public static Optional getInt(String propertyName) { - return getString(propertyName) - .flatMap( - s -> { - try { - return Optional.of(Integer.parseInt(s)); - } catch (NumberFormatException ignored) { - return Optional.empty(); - } - }); + Optional string = getString(propertyName); + // lambdas must not be used here in early initialization phase on early JDK8 versions + if (string.isPresent()) { + try { + return Optional.of(Integer.parseInt(string.get())); + } catch (NumberFormatException ignored) { + // ignored + } + } + return Optional.empty(); } /** From 013caa98d260f0506f43043c5aa92625680d4047 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Tue, 25 Nov 2025 17:23:26 +0100 Subject: [PATCH 28/79] fix --- .../instrumentation/api/internal/ConfigPropertiesUtil.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java index 4116d4b03543..020eca085f5b 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java @@ -52,7 +52,7 @@ public static Optional getBoolean(String propertyName) { Optional string = getString(propertyName); // lambdas must not be used here in early initialization phase on early JDK8 versions if (string.isPresent()) { - return Optional.ofNullable(Boolean.parseBoolean(string.get())); + return Optional.of(Boolean.parseBoolean(string.get())); } return Optional.empty(); } From 70fa1299bfadfc166761021bb7aa1e1dee802eb8 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Thu, 27 Nov 2025 13:50:34 +0100 Subject: [PATCH 29/79] split pr --- .../api/internal/ConfigPropertiesUtil.java | 66 ++++++++++--------- 1 file changed, 36 insertions(+), 30 deletions(-) diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java index 020eca085f5b..ba49c23ccfaf 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java @@ -6,7 +6,6 @@ package io.opentelemetry.instrumentation.api.internal; import static io.opentelemetry.api.incubator.config.DeclarativeConfigProperties.empty; -import static java.util.Collections.emptyList; import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.api.incubator.ExtendedOpenTelemetry; @@ -48,13 +47,9 @@ private static boolean supportsDeclarativeConfig() { *

It's recommended to use {@link #getBoolean(OpenTelemetry, String...)} instead to support * Declarative Config. */ - public static Optional getBoolean(String propertyName) { - Optional string = getString(propertyName); - // lambdas must not be used here in early initialization phase on early JDK8 versions - if (string.isPresent()) { - return Optional.of(Boolean.parseBoolean(string.get())); - } - return Optional.empty(); + public static boolean getBoolean(String propertyName, boolean defaultValue) { + String strValue = getString(propertyName); + return strValue == null ? defaultValue : Boolean.parseBoolean(strValue); } /** @@ -66,24 +61,24 @@ public static Optional getBoolean(OpenTelemetry openTelemetry, String.. if (node != null) { return Optional.ofNullable(node.getBoolean(leaf(propertyName))); } - return getBoolean(toSystemProperty(propertyName)); + String strValue = getString(toSystemProperty(propertyName)); + return strValue == null ? Optional.empty() : Optional.of(Boolean.parseBoolean(strValue)); } /** * Returns the int value of the given property name from system properties and environment * variables. */ - public static Optional getInt(String propertyName) { - Optional string = getString(propertyName); - // lambdas must not be used here in early initialization phase on early JDK8 versions - if (string.isPresent()) { - try { - return Optional.of(Integer.parseInt(string.get())); - } catch (NumberFormatException ignored) { - // ignored - } + public static int getInt(String propertyName, int defaultValue) { + String strValue = getString(propertyName); + if (strValue == null) { + return defaultValue; + } + try { + return Integer.parseInt(strValue); + } catch (NumberFormatException ignored) { + return defaultValue; } - return Optional.empty(); } /** @@ -93,12 +88,25 @@ public static Optional getInt(String propertyName) { *

It's recommended to use {@link #getString(OpenTelemetry, String...)} instead to support * Declarative Config. */ - public static Optional getString(String propertyName) { + @Nullable + public static String getString(String propertyName) { String value = System.getProperty(propertyName); if (value != null) { - return Optional.of(value); + return value; } - return Optional.ofNullable(System.getenv(toEnvVarName(propertyName))); + return System.getenv(toEnvVarName(propertyName)); + } + + /** + * Returns the string value of the given property name from system properties and environment + * variables. + * + *

It's recommended to use {@link #getString(OpenTelemetry, String...)} instead to support + * Declarative Config. + */ + public static String getString(String propertyName, String defaultValue) { + String strValue = getString(propertyName); + return strValue == null ? defaultValue : strValue; } /** @@ -110,21 +118,19 @@ public static Optional getString(OpenTelemetry openTelemetry, String... if (node != null) { return Optional.ofNullable(node.getString(leaf(propertyName))); } - return getString(toSystemProperty(propertyName)); + return Optional.ofNullable(getString(toSystemProperty(propertyName))); } /** * Returns the list of strings value of the given property name from Declarative Config if * available, otherwise falls back to system properties and environment variables. */ - public static List getList(OpenTelemetry openTelemetry, String... propertyName) { - DeclarativeConfigProperties node = getDeclarativeConfigNode(openTelemetry, propertyName); - if (node != null) { - return node.getScalarList(leaf(propertyName), String.class, emptyList()); + public static List getList(String propertyName, List defaultValue) { + String value = getString(propertyName); + if (value == null) { + return defaultValue; } - return getString(toSystemProperty(propertyName)) - .map(value -> filterBlanksAndNulls(value.split(","))) - .orElse(emptyList()); + return filterBlanksAndNulls(value.split(",")); } /** Returns true if the given OpenTelemetry instance supports Declarative Config. */ From 6564d1dbc6c4b5e33fd954d238d039cc63aca7c6 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Thu, 27 Nov 2025 14:15:07 +0100 Subject: [PATCH 30/79] split pr --- .../api/instrumenter/InstrumenterBuilder.java | 3 +-- .../api/internal/ConfigPropertiesUtil.java | 25 ++++++------------- .../api/internal/ContextPropagationDebug.java | 9 +++---- .../api/internal/SemconvStability.java | 2 +- .../api/internal/SupportabilityMetrics.java | 2 +- .../SpanSuppressionStrategyTest.java | 3 ++- .../internal/ConfigPropertiesUtilTest.java | 18 ++++++------- .../v2_2/AbstractAws2ClientCoreTest.java | 3 ++- ...AbstractAws2ClientRecordHttpErrorTest.java | 1 + .../awssdk/v2_2/AbstractAws2SqsBaseTest.java | 1 + ...clarativeConfigProperties156Incubator.java | 5 ++-- .../servlet/ExperimentalSnippetHolder.java | 3 ++- .../javaagent/bootstrap/AgentInitializer.java | 2 +- .../SpanLoggingCustomizerProvider.java | 2 +- .../tooling/config/ConfigurationFile.java | 3 +-- .../tooling/config/EarlyInitAgentConfig.java | 11 +++++--- 16 files changed, 42 insertions(+), 51 deletions(-) diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/InstrumenterBuilder.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/InstrumenterBuilder.java index a7875bf96e3c..2125804d4514 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/InstrumenterBuilder.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/InstrumenterBuilder.java @@ -376,8 +376,7 @@ SpanSuppressor buildSpanSuppressor() { openTelemetry, "common", "experimental", "span_suppression_strategy") .orElse(null) : ConfigPropertiesUtil.getString( - "otel.instrumentation.experimental.span-suppression-strategy") - .orElse(null); + "otel.instrumentation.experimental.span-suppression-strategy"); return new SpanSuppressors.ByContextKey( SpanSuppressionStrategy.fromConfig(value).create(getSpanKeysFromAttributesExtractors())); } diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java index ba49c23ccfaf..c35a6e5fbcb7 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java @@ -6,6 +6,7 @@ package io.opentelemetry.instrumentation.api.internal; import static io.opentelemetry.api.incubator.config.DeclarativeConfigProperties.empty; +import static java.util.Collections.emptyList; import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.api.incubator.ExtendedOpenTelemetry; @@ -97,18 +98,6 @@ public static String getString(String propertyName) { return System.getenv(toEnvVarName(propertyName)); } - /** - * Returns the string value of the given property name from system properties and environment - * variables. - * - *

It's recommended to use {@link #getString(OpenTelemetry, String...)} instead to support - * Declarative Config. - */ - public static String getString(String propertyName, String defaultValue) { - String strValue = getString(propertyName); - return strValue == null ? defaultValue : strValue; - } - /** * Returns the string value of the given property name from Declarative Config if available, * otherwise falls back to system properties and environment variables. @@ -125,12 +114,14 @@ public static Optional getString(OpenTelemetry openTelemetry, String... * Returns the list of strings value of the given property name from Declarative Config if * available, otherwise falls back to system properties and environment variables. */ - public static List getList(String propertyName, List defaultValue) { - String value = getString(propertyName); - if (value == null) { - return defaultValue; + public static List getList(OpenTelemetry openTelemetry, String... propertyName) { + DeclarativeConfigProperties node = getDeclarativeConfigNode(openTelemetry, propertyName); + if (node != null) { + return node.getScalarList(leaf(propertyName), String.class, emptyList()); } - return filterBlanksAndNulls(value.split(",")); + return Optional.ofNullable(getString(toSystemProperty(propertyName))) + .map(value -> filterBlanksAndNulls(value.split(","))) + .orElse(emptyList()); } /** Returns true if the given OpenTelemetry instance supports Declarative Config. */ diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ContextPropagationDebug.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ContextPropagationDebug.java index 4e74e7c50522..cf698069fc05 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ContextPropagationDebug.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ContextPropagationDebug.java @@ -32,16 +32,13 @@ public final class ContextPropagationDebug { private static final boolean FAIL_ON_CONTEXT_LEAK; static { - boolean agentDebugEnabled = - ConfigPropertiesUtil.getBoolean("otel.javaagent.debug").orElse(false); + boolean agentDebugEnabled = ConfigPropertiesUtil.getBoolean("otel.javaagent.debug", false); THREAD_PROPAGATION_DEBUGGER = ConfigPropertiesUtil.getBoolean( - "otel.javaagent.experimental.thread-propagation-debugger.enabled") - .orElse(agentDebugEnabled); + "otel.javaagent.experimental.thread-propagation-debugger.enabled", agentDebugEnabled); FAIL_ON_CONTEXT_LEAK = - ConfigPropertiesUtil.getBoolean("otel.javaagent.testing.fail-on-context-leak") - .orElse(false); + ConfigPropertiesUtil.getBoolean("otel.javaagent.testing.fail-on-context-leak", false); } // context to which debug locations were added diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/SemconvStability.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/SemconvStability.java index bc76ae088bab..e54a62530b67 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/SemconvStability.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/SemconvStability.java @@ -31,7 +31,7 @@ public final class SemconvStability { boolean oldCode = true; boolean stableCode = false; - String value = ConfigPropertiesUtil.getString("otel.semconv-stability.opt-in").orElse(null); + String value = ConfigPropertiesUtil.getString("otel.semconv-stability.opt-in"); if (value != null) { Set values = new HashSet<>(asList(value.split(","))); diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/SupportabilityMetrics.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/SupportabilityMetrics.java index 4e4130c4824c..cf91c4274c32 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/SupportabilityMetrics.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/SupportabilityMetrics.java @@ -30,7 +30,7 @@ public final class SupportabilityMetrics { private static final SupportabilityMetrics INSTANCE = new SupportabilityMetrics( - ConfigPropertiesUtil.getBoolean("otel.javaagent.debug").orElse(false), logger::fine) + ConfigPropertiesUtil.getBoolean("otel.javaagent.debug", false), logger::fine) .start(); public static SupportabilityMetrics instance() { diff --git a/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/instrumenter/SpanSuppressionStrategyTest.java b/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/instrumenter/SpanSuppressionStrategyTest.java index d15f564d080f..6091c512dea3 100644 --- a/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/instrumenter/SpanSuppressionStrategyTest.java +++ b/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/instrumenter/SpanSuppressionStrategyTest.java @@ -45,7 +45,8 @@ private static Stream configArgs() { Arguments.of("Span-Kind", SpanSuppressionStrategy.SPAN_KIND), Arguments.of("semconv", SpanSuppressionStrategy.SEMCONV), Arguments.of("SemConv", SpanSuppressionStrategy.SEMCONV), - Arguments.of("asdfasdfasdf", SpanSuppressionStrategy.SEMCONV)); + Arguments.of("asdfasdfasdf", SpanSuppressionStrategy.SEMCONV), + Arguments.of(null, SpanSuppressionStrategy.SEMCONV)); } @ParameterizedTest diff --git a/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java b/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java index a25e8ca1f3d9..1fbd082af88d 100644 --- a/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java +++ b/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java @@ -32,18 +32,18 @@ class ConfigPropertiesUtilTest { @SetSystemProperty(key = "test.property.string", value = "sys") @Test void getString_systemProperty() { - assertThat(ConfigPropertiesUtil.getString("test.property.string")).hasValue("sys"); + assertThat(ConfigPropertiesUtil.getString("test.property.string")).isEqualTo("sys"); } @SetEnvironmentVariable(key = "TEST_PROPERTY_STRING", value = "env") @Test void getString_environmentVariable() { - assertThat(ConfigPropertiesUtil.getString("test.property.string")).hasValue("env"); + assertThat(ConfigPropertiesUtil.getString("test.property.string")).isEqualTo("env"); } @Test void getString_none() { - assertThat(ConfigPropertiesUtil.getString("test.property.string")).isEmpty(); + assertThat(ConfigPropertiesUtil.getString("test.property.string")).isNull(); } @SetEnvironmentVariable(key = "OTEL_INSTRUMENTATION_TEST_PROPERTY_STRING", value = "env_value") @@ -92,24 +92,24 @@ void getString_declarativeConfig(Object property, String expected) { @SetSystemProperty(key = "test.property.int", value = "42") @Test void getInt_systemProperty() { - assertThat(ConfigPropertiesUtil.getInt("test.property.int")).hasValue(42); + assertThat(ConfigPropertiesUtil.getInt("test.property.int", -1)).isEqualTo(42); } @SetEnvironmentVariable(key = "TEST_PROPERTY_INT", value = "12") @Test void getInt_environmentVariable() { - assertThat(ConfigPropertiesUtil.getInt("test.property.int")).hasValue(12); + assertThat(ConfigPropertiesUtil.getInt("test.property.int", -1)).isEqualTo(12); } @Test void getInt_none() { - assertThat(ConfigPropertiesUtil.getInt("test.property.int")).isEmpty(); + assertThat(ConfigPropertiesUtil.getInt("test.property.int", -1)).isEqualTo(-1); } @SetSystemProperty(key = "test.property.int", value = "not a number") @Test void getInt_invalidNumber() { - assertThat(ConfigPropertiesUtil.getInt("test.property.int")).isEmpty(); + assertThat(ConfigPropertiesUtil.getInt("test.property.int", -1)).isEqualTo(-1); } @SetEnvironmentVariable(key = "OTEL_INSTRUMENTATION_TEST_PROPERTY_BOOLEAN", value = "false") @@ -131,9 +131,7 @@ void getBoolean_none() { } private static void assertBoolean(boolean expected) { - assertThat( - ConfigPropertiesUtil.getBoolean("otel.instrumentation.test.property.boolean") - .orElse(false)) + assertThat(ConfigPropertiesUtil.getBoolean("otel.instrumentation.test.property.boolean", false)) .isEqualTo(expected); assertThat( ConfigPropertiesUtil.getBoolean(OpenTelemetry.noop(), "test", "property", "boolean") diff --git a/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2ClientCoreTest.java b/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2ClientCoreTest.java index de9de748436f..e8d61732224b 100644 --- a/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2ClientCoreTest.java +++ b/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2ClientCoreTest.java @@ -98,9 +98,10 @@ public abstract class AbstractAws2ClientCoreTest { protected abstract ClientOverrideConfiguration.Builder createOverrideConfigurationBuilder(); - protected static boolean isSqsAttributeInjectionEnabled() { + protected boolean isSqsAttributeInjectionEnabled() { // See io.opentelemetry.instrumentation.awssdk.v2_2.autoconfigure.TracingExecutionInterceptor return ConfigPropertiesUtil.getBoolean( + getTesting().getOpenTelemetry(), "otel.instrumentation.aws-sdk.experimental-use-propagator-for-messaging") .orElse(false); } diff --git a/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2ClientRecordHttpErrorTest.java b/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2ClientRecordHttpErrorTest.java index 9825935d4b9c..c795afc07cf0 100644 --- a/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2ClientRecordHttpErrorTest.java +++ b/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2ClientRecordHttpErrorTest.java @@ -126,6 +126,7 @@ private static void cleanResponses() { public boolean isRecordIndividualHttpErrorEnabled() { // See io.opentelemetry.instrumentation.awssdk.v2_2.autoconfigure.TracingExecutionInterceptor return ConfigPropertiesUtil.getBoolean( + getTesting().getOpenTelemetry(), "otel.instrumentation.aws-sdk.experimental-record-individual-http-error") .orElse(false); } diff --git a/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2SqsBaseTest.java b/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2SqsBaseTest.java index fd435a84c6b2..b0eb548ec694 100644 --- a/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2SqsBaseTest.java +++ b/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2SqsBaseTest.java @@ -132,6 +132,7 @@ protected void configureSdkClient(SqsAsyncClientBuilder builder) throws URISynta protected boolean isSqsAttributeInjectionEnabled() { // See io.opentelemetry.instrumentation.awssdk.v2_2.autoconfigure.TracingExecutionInterceptor return ConfigPropertiesUtil.getBoolean( + getTesting().getOpenTelemetry(), "otel.instrumentation.aws-sdk.experimental-use-propagator-for-messaging") .orElse(false); } diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.56/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_56/incubator/config/ApplicationDeclarativeConfigProperties156Incubator.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.56/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_56/incubator/config/ApplicationDeclarativeConfigProperties156Incubator.java index 73e84975b85f..731defc77272 100644 --- a/instrumentation/opentelemetry-api/opentelemetry-api-1.56/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_56/incubator/config/ApplicationDeclarativeConfigProperties156Incubator.java +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.56/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_56/incubator/config/ApplicationDeclarativeConfigProperties156Incubator.java @@ -92,9 +92,8 @@ public List getScalarList(String name, Class scalarType, List defau @Nullable @Override public DeclarativeConfigProperties getStructured(String name) { - io.opentelemetry.api.incubator.config.DeclarativeConfigProperties config = - instrumentationConfig.getStructured(name); - return config == null ? null : new ApplicationDeclarativeConfigProperties156Incubator(config); + return new ApplicationDeclarativeConfigProperties156Incubator( + instrumentationConfig.getStructured(name)); } @Nullable diff --git a/instrumentation/servlet/servlet-common/bootstrap/src/main/java/io/opentelemetry/javaagent/bootstrap/servlet/ExperimentalSnippetHolder.java b/instrumentation/servlet/servlet-common/bootstrap/src/main/java/io/opentelemetry/javaagent/bootstrap/servlet/ExperimentalSnippetHolder.java index cc5f10c40e07..df5d4d90d2d4 100644 --- a/instrumentation/servlet/servlet-common/bootstrap/src/main/java/io/opentelemetry/javaagent/bootstrap/servlet/ExperimentalSnippetHolder.java +++ b/instrumentation/servlet/servlet-common/bootstrap/src/main/java/io/opentelemetry/javaagent/bootstrap/servlet/ExperimentalSnippetHolder.java @@ -22,7 +22,8 @@ private static String getSnippetSetting() { ConfigPropertiesUtil.isDeclarativeConfig(openTelemetry) ? ConfigPropertiesUtil.getString( openTelemetry, "servlet", "experimental", "javascript-snippet") - : ConfigPropertiesUtil.getString("otel.experimental.javascript-snippet"); + : Optional.ofNullable( + ConfigPropertiesUtil.getString("otel.experimental.javascript-snippet")); return result.orElse(""); } diff --git a/javaagent-bootstrap/src/main/java/io/opentelemetry/javaagent/bootstrap/AgentInitializer.java b/javaagent-bootstrap/src/main/java/io/opentelemetry/javaagent/bootstrap/AgentInitializer.java index dcd41a32e83e..509d13964d3b 100644 --- a/javaagent-bootstrap/src/main/java/io/opentelemetry/javaagent/bootstrap/AgentInitializer.java +++ b/javaagent-bootstrap/src/main/java/io/opentelemetry/javaagent/bootstrap/AgentInitializer.java @@ -94,7 +94,7 @@ private static boolean getBoolean(String property, boolean defaultValue) { new PrivilegedAction() { @Override public Boolean run() { - return ConfigPropertiesUtil.getBoolean(property).orElse(defaultValue); + return ConfigPropertiesUtil.getBoolean(property, defaultValue); } }); } diff --git a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/SpanLoggingCustomizerProvider.java b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/SpanLoggingCustomizerProvider.java index 14d0fde72e97..00634e858503 100644 --- a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/SpanLoggingCustomizerProvider.java +++ b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/SpanLoggingCustomizerProvider.java @@ -19,6 +19,6 @@ public class SpanLoggingCustomizerProvider extends AbstractSpanLoggingCustomizer protected boolean isEnabled(OpenTelemetryConfigurationModel model) { // read from system properties as it's an early init property and the config bridge is not // available here - return ConfigPropertiesUtil.getBoolean("otel.javaagent.debug").orElse(false); + return ConfigPropertiesUtil.getBoolean("otel.javaagent.debug", false); } } diff --git a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/ConfigurationFile.java b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/ConfigurationFile.java index ddc6e5f740bf..4da9ca45f1fb 100644 --- a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/ConfigurationFile.java +++ b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/ConfigurationFile.java @@ -47,8 +47,7 @@ static void resetForTest() { // visible for tests static Map loadConfigFile() { // Reading from system property first and from env after - String configurationFilePath = - ConfigPropertiesUtil.getString(CONFIGURATION_FILE_PROPERTY).orElse(null); + String configurationFilePath = ConfigPropertiesUtil.getString(CONFIGURATION_FILE_PROPERTY); if (configurationFilePath == null) { return emptyMap(); } diff --git a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/EarlyInitAgentConfig.java b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/EarlyInitAgentConfig.java index e9bb11bfc780..d39f1b9cfd6a 100644 --- a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/EarlyInitAgentConfig.java +++ b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/EarlyInitAgentConfig.java @@ -27,15 +27,18 @@ private EarlyInitAgentConfig(Map configFileContents) { @Nullable public String getString(String propertyName) { - return ConfigPropertiesUtil.getString(propertyName) - .orElseGet(() -> configFileContents.get(propertyName)); + String value = ConfigPropertiesUtil.getString(propertyName); + if (value != null) { + return value; + } + return configFileContents.get(propertyName); } public boolean getBoolean(String propertyName, boolean defaultValue) { String configFileValueStr = configFileContents.get(propertyName); boolean configFileValue = configFileValueStr == null ? defaultValue : Boolean.parseBoolean(configFileValueStr); - return ConfigPropertiesUtil.getBoolean(propertyName).orElse(configFileValue); + return ConfigPropertiesUtil.getBoolean(propertyName, configFileValue); } public int getInt(String propertyName, int defaultValue) { @@ -43,7 +46,7 @@ public int getInt(String propertyName, int defaultValue) { String configFileValueStr = configFileContents.get(propertyName); int configFileValue = configFileValueStr == null ? defaultValue : Integer.parseInt(configFileValueStr); - return ConfigPropertiesUtil.getInt(propertyName).orElse(configFileValue); + return ConfigPropertiesUtil.getInt(propertyName, configFileValue); } catch (NumberFormatException ignored) { return defaultValue; } From 3bc5bbe9709627e021a802caa8574aef48b3890b Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Thu, 27 Nov 2025 16:52:08 +0100 Subject: [PATCH 31/79] fix --- .../instrumentation/awssdk/v2_2/AbstractAws2ClientTest.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2ClientTest.java b/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2ClientTest.java index b8d1892f062a..f02531ee7514 100644 --- a/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2ClientTest.java +++ b/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2ClientTest.java @@ -273,7 +273,7 @@ public abstract class AbstractAws2ClientTest extends AbstractAws2ClientCoreTest + " " + ""; - private static void assumeSupportedConfig(String operation) { + private void assumeSupportedConfig(String operation) { Assumptions.assumeFalse( operation.equals("SendMessage") && isSqsAttributeInjectionEnabled(), "Cannot check Sqs.SendMessage here due to hard-coded MD5."); From 75fefacbfbb4451646aca2ae4ddb7b984cfaa8c0 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Thu, 27 Nov 2025 17:51:42 +0100 Subject: [PATCH 32/79] fix --- .../awssdk/v2_2/AbstractAws2ClientCoreTest.java | 3 +-- .../awssdk/v2_2/AbstractAws2ClientRecordHttpErrorTest.java | 3 +-- .../instrumentation/awssdk/v2_2/AbstractAws2SqsBaseTest.java | 3 +-- 3 files changed, 3 insertions(+), 6 deletions(-) diff --git a/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2ClientCoreTest.java b/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2ClientCoreTest.java index e8d61732224b..bc8794acecb3 100644 --- a/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2ClientCoreTest.java +++ b/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2ClientCoreTest.java @@ -101,8 +101,7 @@ public abstract class AbstractAws2ClientCoreTest { protected boolean isSqsAttributeInjectionEnabled() { // See io.opentelemetry.instrumentation.awssdk.v2_2.autoconfigure.TracingExecutionInterceptor return ConfigPropertiesUtil.getBoolean( - getTesting().getOpenTelemetry(), - "otel.instrumentation.aws-sdk.experimental-use-propagator-for-messaging") + getTesting().getOpenTelemetry(), "aws_sdk", "experimental_use_propagator_for_messaging") .orElse(false); } diff --git a/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2ClientRecordHttpErrorTest.java b/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2ClientRecordHttpErrorTest.java index c795afc07cf0..0de2f015e9fc 100644 --- a/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2ClientRecordHttpErrorTest.java +++ b/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2ClientRecordHttpErrorTest.java @@ -126,8 +126,7 @@ private static void cleanResponses() { public boolean isRecordIndividualHttpErrorEnabled() { // See io.opentelemetry.instrumentation.awssdk.v2_2.autoconfigure.TracingExecutionInterceptor return ConfigPropertiesUtil.getBoolean( - getTesting().getOpenTelemetry(), - "otel.instrumentation.aws-sdk.experimental-record-individual-http-error") + getTesting().getOpenTelemetry(), "aws_sdk", "experimental_record_individual_http_error") .orElse(false); } diff --git a/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2SqsBaseTest.java b/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2SqsBaseTest.java index b0eb548ec694..bb11e984a93e 100644 --- a/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2SqsBaseTest.java +++ b/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2SqsBaseTest.java @@ -132,8 +132,7 @@ protected void configureSdkClient(SqsAsyncClientBuilder builder) throws URISynta protected boolean isSqsAttributeInjectionEnabled() { // See io.opentelemetry.instrumentation.awssdk.v2_2.autoconfigure.TracingExecutionInterceptor return ConfigPropertiesUtil.getBoolean( - getTesting().getOpenTelemetry(), - "otel.instrumentation.aws-sdk.experimental-use-propagator-for-messaging") + getTesting().getOpenTelemetry(), "aws_sdk", "experimental_use_propagator_for_messaging") .orElse(false); } From a1867eb81a82aa63442cbccef434ac4420a7986e Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Wed, 3 Dec 2025 11:22:11 +0100 Subject: [PATCH 33/79] pr review --- docs/advanced-configuration-options.md | 6 +++--- .../servlet/ExperimentalSnippetHolder.java | 15 +++------------ 2 files changed, 6 insertions(+), 15 deletions(-) diff --git a/docs/advanced-configuration-options.md b/docs/advanced-configuration-options.md index 537253406497..67870038f862 100644 --- a/docs/advanced-configuration-options.md +++ b/docs/advanced-configuration-options.md @@ -45,9 +45,9 @@ This feature is designed for integrating client-side monitoring. We plan to integrate OpenTelemetry's own client-side monitoring solution by default once it's available (see the [browser instrumentation proposal](https://github.com/open-telemetry/community/blob/main/projects/browser-phase-1.md)). -| System property | Environment variable | Purpose | -|--------------------------------------|--------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| otel.experimental.javascript-snippet | OTEL_EXPERIMENTAL_JAVASCRIPT_SNIPPET | Experimental setting to inject a JavaScript snippet into HTML responses after the opening `` tag. The value should be a complete JavaScript snippet including `"` | +| System property | Environment variable | Purpose | +|----------------------------------------------------------------|--------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `otel.instrumentation.servlet.experimental.javascript-snippet` | OTEL_EXPERIMENTAL_JAVASCRIPT_SNIPPET | Experimental setting to inject a JavaScript snippet into HTML responses after the opening `` tag. The value should be a complete JavaScript snippet including `"` | **Important notes:** diff --git a/instrumentation/servlet/servlet-common/bootstrap/src/main/java/io/opentelemetry/javaagent/bootstrap/servlet/ExperimentalSnippetHolder.java b/instrumentation/servlet/servlet-common/bootstrap/src/main/java/io/opentelemetry/javaagent/bootstrap/servlet/ExperimentalSnippetHolder.java index df5d4d90d2d4..9368fc04b3d0 100644 --- a/instrumentation/servlet/servlet-common/bootstrap/src/main/java/io/opentelemetry/javaagent/bootstrap/servlet/ExperimentalSnippetHolder.java +++ b/instrumentation/servlet/servlet-common/bootstrap/src/main/java/io/opentelemetry/javaagent/bootstrap/servlet/ExperimentalSnippetHolder.java @@ -6,25 +6,16 @@ package io.opentelemetry.javaagent.bootstrap.servlet; import io.opentelemetry.api.GlobalOpenTelemetry; -import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.instrumentation.api.internal.ConfigPropertiesUtil; -import java.util.Optional; public class ExperimentalSnippetHolder { private static volatile String snippet = getSnippetSetting(); private static String getSnippetSetting() { - OpenTelemetry openTelemetry = GlobalOpenTelemetry.get(); - Optional result = - // otel.experimental.* does not fit the usual pattern of configuration properties for - // instrumentations, so we need to handle both declarative and non-declarative configs here - ConfigPropertiesUtil.isDeclarativeConfig(openTelemetry) - ? ConfigPropertiesUtil.getString( - openTelemetry, "servlet", "experimental", "javascript-snippet") - : Optional.ofNullable( - ConfigPropertiesUtil.getString("otel.experimental.javascript-snippet")); - return result.orElse(""); + return ConfigPropertiesUtil.getString( + GlobalOpenTelemetry.get(), "servlet", "experimental", "javascript-snippet") + .orElse(""); } public static void setSnippet(String newValue) { From 6bba13552e851aaa5cef443a5a05ce979302a23e Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Wed, 3 Dec 2025 11:43:47 +0100 Subject: [PATCH 34/79] revert aws test --- .../awssdk/v2_2/AbstractAws2ClientCoreTest.java | 5 ++--- .../awssdk/v2_2/AbstractAws2ClientRecordHttpErrorTest.java | 3 +-- .../instrumentation/awssdk/v2_2/AbstractAws2ClientTest.java | 2 +- .../instrumentation/awssdk/v2_2/AbstractAws2SqsBaseTest.java | 3 +-- 4 files changed, 5 insertions(+), 8 deletions(-) diff --git a/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2ClientCoreTest.java b/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2ClientCoreTest.java index bc8794acecb3..f34767d4a771 100644 --- a/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2ClientCoreTest.java +++ b/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2ClientCoreTest.java @@ -98,11 +98,10 @@ public abstract class AbstractAws2ClientCoreTest { protected abstract ClientOverrideConfiguration.Builder createOverrideConfigurationBuilder(); - protected boolean isSqsAttributeInjectionEnabled() { + protected static boolean isSqsAttributeInjectionEnabled() { // See io.opentelemetry.instrumentation.awssdk.v2_2.autoconfigure.TracingExecutionInterceptor return ConfigPropertiesUtil.getBoolean( - getTesting().getOpenTelemetry(), "aws_sdk", "experimental_use_propagator_for_messaging") - .orElse(false); + "otel.instrumentation.aws-sdk.experimental-use-propagator-for-messaging", false); } protected void configureSdkClient(SdkClientBuilder builder) { diff --git a/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2ClientRecordHttpErrorTest.java b/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2ClientRecordHttpErrorTest.java index 0de2f015e9fc..582af3e4a941 100644 --- a/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2ClientRecordHttpErrorTest.java +++ b/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2ClientRecordHttpErrorTest.java @@ -126,8 +126,7 @@ private static void cleanResponses() { public boolean isRecordIndividualHttpErrorEnabled() { // See io.opentelemetry.instrumentation.awssdk.v2_2.autoconfigure.TracingExecutionInterceptor return ConfigPropertiesUtil.getBoolean( - getTesting().getOpenTelemetry(), "aws_sdk", "experimental_record_individual_http_error") - .orElse(false); + "otel.instrumentation.aws-sdk.experimental-record-individual-http-error", false); } @SuppressWarnings("deprecation") // using deprecated semconv diff --git a/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2ClientTest.java b/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2ClientTest.java index f02531ee7514..b8d1892f062a 100644 --- a/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2ClientTest.java +++ b/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2ClientTest.java @@ -273,7 +273,7 @@ public abstract class AbstractAws2ClientTest extends AbstractAws2ClientCoreTest + " " + ""; - private void assumeSupportedConfig(String operation) { + private static void assumeSupportedConfig(String operation) { Assumptions.assumeFalse( operation.equals("SendMessage") && isSqsAttributeInjectionEnabled(), "Cannot check Sqs.SendMessage here due to hard-coded MD5."); diff --git a/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2SqsBaseTest.java b/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2SqsBaseTest.java index bb11e984a93e..3fb1636d551a 100644 --- a/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2SqsBaseTest.java +++ b/instrumentation/aws-sdk/aws-sdk-2.2/testing/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/AbstractAws2SqsBaseTest.java @@ -132,8 +132,7 @@ protected void configureSdkClient(SqsAsyncClientBuilder builder) throws URISynta protected boolean isSqsAttributeInjectionEnabled() { // See io.opentelemetry.instrumentation.awssdk.v2_2.autoconfigure.TracingExecutionInterceptor return ConfigPropertiesUtil.getBoolean( - getTesting().getOpenTelemetry(), "aws_sdk", "experimental_use_propagator_for_messaging") - .orElse(false); + "otel.instrumentation.aws-sdk.experimental-use-propagator-for-messaging", false); } @BeforeAll From 4a104d4fa37e2563eb6291a59f91801e28f4d84e Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Wed, 3 Dec 2025 11:59:38 +0100 Subject: [PATCH 35/79] use "/development" instead of "experimental" in declarative config --- .../api/internal/ConfigPropertiesUtil.java | 6 ++++++ .../api/internal/ConfigPropertiesUtilTest.java | 2 ++ .../awssdk/v1_11/autoconfigure/TracingRequestHandler.java | 8 +++----- .../v2_2/internal/AbstractAwsSdkTelemetryFactory.java | 6 +++--- 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java index c35a6e5fbcb7..446bc2cada54 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java @@ -165,6 +165,12 @@ private static DeclarativeConfigProperties getDeclarativeConfigNode( } public static String toSystemProperty(String[] propertyName) { + for (int i = 0; i < propertyName.length; i++) { + if (propertyName[i].endsWith("/development")) { + propertyName[i] = + "experimental-" + propertyName[i].substring(0, propertyName[i].length() - 12); + } + } return "otel.instrumentation." + String.join(".", propertyName).replace('_', '-'); } diff --git a/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java b/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java index 1fbd082af88d..69b57f7ee301 100644 --- a/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java +++ b/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java @@ -175,6 +175,8 @@ private static OpenTelemetryConfigurationModel model(Object value) { void toSystemProperty() { assertThat(ConfigPropertiesUtil.toSystemProperty(new String[] {"a_b", "c", "d"})) .isEqualTo("otel.instrumentation.a-b.c.d"); + assertThat(ConfigPropertiesUtil.toSystemProperty(new String[] {"a_b/development", "c", "d"})) + .isEqualTo("otel.instrumentation.experimental-a-b.c.d"); } @SetEnvironmentVariable(key = "OTEL_INSTRUMENTATION_TEST_PROPERTY_LIST", value = "a,b,c") diff --git a/instrumentation/aws-sdk/aws-sdk-1.11/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v1_11/autoconfigure/TracingRequestHandler.java b/instrumentation/aws-sdk/aws-sdk-1.11/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v1_11/autoconfigure/TracingRequestHandler.java index d7a81f290725..e319b4bb96fb 100644 --- a/instrumentation/aws-sdk/aws-sdk-1.11/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v1_11/autoconfigure/TracingRequestHandler.java +++ b/instrumentation/aws-sdk/aws-sdk-1.11/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v1_11/autoconfigure/TracingRequestHandler.java @@ -24,16 +24,14 @@ public class TracingRequestHandler extends RequestHandler2 { private static RequestHandler2 buildDelegate(OpenTelemetry openTelemetry) { return AwsSdkTelemetry.builder(openTelemetry) .setCaptureExperimentalSpanAttributes( - ConfigPropertiesUtil.getBoolean( - openTelemetry, "aws_sdk", "experimental_span_attributes") + ConfigPropertiesUtil.getBoolean(openTelemetry, "aws_sdk", "span_attributes/development") .orElse(false)) .setMessagingReceiveInstrumentationEnabled( ConfigPropertiesUtil.getBoolean( - openTelemetry, "messaging", "experimental", "receive_telemetry", "enabled") + openTelemetry, "messaging", "receive_telemetry/development", "enabled") .orElse(false)) .setCapturedHeaders( - ConfigPropertiesUtil.getList( - openTelemetry, "messaging", "experimental", "capture_headers")) + ConfigPropertiesUtil.getList(openTelemetry, "messaging", "capture_headers/development")) .build() .newRequestHandler(); } diff --git a/instrumentation/aws-sdk/aws-sdk-2.2/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/internal/AbstractAwsSdkTelemetryFactory.java b/instrumentation/aws-sdk/aws-sdk-2.2/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/internal/AbstractAwsSdkTelemetryFactory.java index 97701d3242c8..33e7280323f3 100644 --- a/instrumentation/aws-sdk/aws-sdk-2.2/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/internal/AbstractAwsSdkTelemetryFactory.java +++ b/instrumentation/aws-sdk/aws-sdk-2.2/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/internal/AbstractAwsSdkTelemetryFactory.java @@ -17,17 +17,17 @@ public abstract class AbstractAwsSdkTelemetryFactory { protected abstract List getCapturedHeaders(); private boolean captureExperimentalSpanAttributes() { - return getBoolean(false, "aws_sdk", "experimental_span_attributes"); + return getBoolean(false, "aws_sdk", "span_attributes/development"); } protected abstract boolean messagingReceiveInstrumentationEnabled(); private boolean useMessagingPropagator() { - return getBoolean(false, "aws_sdk", "experimental_use_propagator_for_messaging"); + return getBoolean(false, "aws_sdk", "use_propagator_for_messaging/development"); } private boolean recordIndividualHttpError() { - return getBoolean(false, "aws_sdk", "experimental_record_individual_http_error"); + return getBoolean(false, "aws_sdk", "record_individual_http_error/development"); } private boolean genaiCaptureMessageContent() { From 265f236dc2c0ace39230f690123aad491a54d465 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Wed, 3 Dec 2025 12:23:25 +0100 Subject: [PATCH 36/79] use "/development" instead of "experimental" in declarative config --- .../api/instrumenter/InstrumenterBuilder.java | 2 +- .../awssdk/v2_2/autoconfigure/AwsSdkSingletons.java | 8 ++------ .../instrumentation/jdbc/OpenTelemetryDriver.java | 4 ++-- .../jdbc/internal/JdbcInstrumenterFactory.java | 5 ++--- .../kafkaclients/v2_6/TracingConsumerInterceptor.java | 4 ++-- .../kafkaclients/v2_6/TracingProducerInterceptor.java | 2 +- .../bootstrap/servlet/ExperimentalSnippetHolder.java | 2 +- 7 files changed, 11 insertions(+), 16 deletions(-) diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/InstrumenterBuilder.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/InstrumenterBuilder.java index 2125804d4514..d8fbbae07973 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/InstrumenterBuilder.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/InstrumenterBuilder.java @@ -373,7 +373,7 @@ SpanSuppressor buildSpanSuppressor() { String value = ConfigPropertiesUtil.isDeclarativeConfig(openTelemetry) ? ConfigPropertiesUtil.getString( - openTelemetry, "common", "experimental", "span_suppression_strategy") + openTelemetry, "common", "span_suppression_strategy/development") .orElse(null) : ConfigPropertiesUtil.getString( "otel.instrumentation.experimental.span-suppression-strategy"); diff --git a/instrumentation/aws-sdk/aws-sdk-2.2/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/autoconfigure/AwsSdkSingletons.java b/instrumentation/aws-sdk/aws-sdk-2.2/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/autoconfigure/AwsSdkSingletons.java index cf5b7b1daada..f6205858923e 100644 --- a/instrumentation/aws-sdk/aws-sdk-2.2/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/autoconfigure/AwsSdkSingletons.java +++ b/instrumentation/aws-sdk/aws-sdk-2.2/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/autoconfigure/AwsSdkSingletons.java @@ -24,17 +24,13 @@ private static class AwsSdkTelemetryFactory extends AbstractAwsSdkTelemetryFacto @Override protected List getCapturedHeaders() { return ConfigPropertiesUtil.getList( - GlobalOpenTelemetry.get(), "messaging", "experimental", "capture_headers"); + GlobalOpenTelemetry.get(), "messaging", "capture_headers/development"); } @Override protected boolean messagingReceiveInstrumentationEnabled() { return ConfigPropertiesUtil.getBoolean( - GlobalOpenTelemetry.get(), - "messaging", - "experimental", - "receive_telemetry", - "enabled") + GlobalOpenTelemetry.get(), "messaging", "receive_telemetry/development", "enabled") .orElse(false); } diff --git a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/OpenTelemetryDriver.java b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/OpenTelemetryDriver.java index 1a4a2803bf66..6717d9fffe07 100644 --- a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/OpenTelemetryDriver.java +++ b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/OpenTelemetryDriver.java @@ -66,12 +66,12 @@ public final class OpenTelemetryDriver implements Driver { private static SqlCommenter getSqlCommenter(OpenTelemetry openTelemetry) { boolean defaultValue = ConfigPropertiesUtil.getBoolean( - openTelemetry, "common", "experimental", "db_sqlcommenter", "enabled") + openTelemetry, "common", "db_sqlcommenter/development", "enabled") .orElse(false); return SqlCommenter.builder() .setEnabled( ConfigPropertiesUtil.getBoolean( - openTelemetry, "jdbc", "experimental", "sqlcommenter", "enabled") + openTelemetry, "jdbc", "sqlcommenter/development", "enabled") .orElse(defaultValue)) .build(); } diff --git a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/JdbcInstrumenterFactory.java b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/JdbcInstrumenterFactory.java index f810a8d345ad..5b2e66e14755 100644 --- a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/JdbcInstrumenterFactory.java +++ b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/JdbcInstrumenterFactory.java @@ -30,7 +30,7 @@ public final class JdbcInstrumenterFactory { public static boolean captureQueryParameters(OpenTelemetry openTelemetry) { return ConfigPropertiesUtil.getBoolean( - openTelemetry, "jdbc", "experimental", "capture_query_parameters") + openTelemetry, "jdbc", "capture_query_parameters/development") .orElse(false); } @@ -96,8 +96,7 @@ public static Instrumenter createTransactionInstrumenter( OpenTelemetry openTelemetry) { return createTransactionInstrumenter( openTelemetry, - ConfigPropertiesUtil.getBoolean( - openTelemetry, "jdbc", "experimental", "transaction", "enabled") + ConfigPropertiesUtil.getBoolean(openTelemetry, "jdbc", "transaction/development", "enabled") .orElse(false)); } diff --git a/instrumentation/kafka/kafka-clients/kafka-clients-2.6/library/src/main/java/io/opentelemetry/instrumentation/kafkaclients/v2_6/TracingConsumerInterceptor.java b/instrumentation/kafka/kafka-clients/kafka-clients-2.6/library/src/main/java/io/opentelemetry/instrumentation/kafkaclients/v2_6/TracingConsumerInterceptor.java index 08b6f0bdd5b9..82a26cceb06e 100644 --- a/instrumentation/kafka/kafka-clients/kafka-clients-2.6/library/src/main/java/io/opentelemetry/instrumentation/kafkaclients/v2_6/TracingConsumerInterceptor.java +++ b/instrumentation/kafka/kafka-clients/kafka-clients-2.6/library/src/main/java/io/opentelemetry/instrumentation/kafkaclients/v2_6/TracingConsumerInterceptor.java @@ -39,11 +39,11 @@ public class TracingConsumerInterceptor implements ConsumerInterceptor implements ProducerInterceptor Date: Wed, 3 Dec 2025 12:23:30 +0100 Subject: [PATCH 37/79] fix --- .../ApplicationDeclarativeConfigProperties156Incubator.java | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/instrumentation/opentelemetry-api/opentelemetry-api-1.56/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_56/incubator/config/ApplicationDeclarativeConfigProperties156Incubator.java b/instrumentation/opentelemetry-api/opentelemetry-api-1.56/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_56/incubator/config/ApplicationDeclarativeConfigProperties156Incubator.java index 731defc77272..73e84975b85f 100644 --- a/instrumentation/opentelemetry-api/opentelemetry-api-1.56/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_56/incubator/config/ApplicationDeclarativeConfigProperties156Incubator.java +++ b/instrumentation/opentelemetry-api/opentelemetry-api-1.56/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/opentelemetryapi/v1_56/incubator/config/ApplicationDeclarativeConfigProperties156Incubator.java @@ -92,8 +92,9 @@ public List getScalarList(String name, Class scalarType, List defau @Nullable @Override public DeclarativeConfigProperties getStructured(String name) { - return new ApplicationDeclarativeConfigProperties156Incubator( - instrumentationConfig.getStructured(name)); + io.opentelemetry.api.incubator.config.DeclarativeConfigProperties config = + instrumentationConfig.getStructured(name); + return config == null ? null : new ApplicationDeclarativeConfigProperties156Incubator(config); } @Nullable From 1a292e2fc7ba4a218d150cfa06dc0ba60285bc45 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Wed, 3 Dec 2025 19:03:34 +0100 Subject: [PATCH 38/79] docs --- .../api/incubator/config/internal/InstrumentationConfig.java | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/config/internal/InstrumentationConfig.java b/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/config/internal/InstrumentationConfig.java index ab1bb761aa22..8b1dd6626c64 100644 --- a/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/config/internal/InstrumentationConfig.java +++ b/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/config/internal/InstrumentationConfig.java @@ -132,7 +132,7 @@ default List getList(String name) { /** * Returns the {@link ConfigProvider} if declarative configuration is used. * - * @return the {@link ConfigProvider} or {@code null} if no provider is available + * @return the {@link ConfigProvider} or {@code null} if declarative configuration is not used */ @Nullable ConfigProvider getConfigProvider(); From 23932b38a3087341eeccbee582e53992dc783818 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Thu, 4 Dec 2025 08:03:10 +0100 Subject: [PATCH 39/79] avoid double bridge --- .../api/internal/ConfigPropertiesUtil.java | 26 ++++++++++++------- .../awssdk/v2_2/AwsSdkSingletons.java | 14 ++++++++-- 2 files changed, 28 insertions(+), 12 deletions(-) diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java index 446bc2cada54..7fa5c266bc34 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java @@ -150,20 +150,26 @@ private static DeclarativeConfigProperties getDeclarativeConfigNode( if (isDeclarativeConfig(openTelemetry)) { ExtendedOpenTelemetry extendedOpenTelemetry = (ExtendedOpenTelemetry) openTelemetry; ConfigProvider configProvider = extendedOpenTelemetry.getConfigProvider(); - DeclarativeConfigProperties instrumentationConfig = configProvider.getInstrumentationConfig(); - if (instrumentationConfig == null) { - return empty(); - } - DeclarativeConfigProperties node = instrumentationConfig.getStructured("java", empty()); - // last part is the leaf property - for (int i = 0; i < propertyName.length - 1; i++) { - node = node.getStructured(propertyName[i], empty()); - } - return node; + return getConfigProperties(configProvider, propertyName); } return null; } + /** Returns the DeclarativeConfigProperties node for the given property name parts. */ + public static DeclarativeConfigProperties getConfigProperties( + ConfigProvider configProvider, String[] propertyName) { + DeclarativeConfigProperties instrumentationConfig = configProvider.getInstrumentationConfig(); + if (instrumentationConfig == null) { + return empty(); + } + DeclarativeConfigProperties node = instrumentationConfig.getStructured("java", empty()); + // last part is the leaf property + for (int i = 0; i < propertyName.length - 1; i++) { + node = node.getStructured(propertyName[i], empty()); + } + return node; + } + public static String toSystemProperty(String[] propertyName) { for (int i = 0; i < propertyName.length; i++) { if (propertyName[i].endsWith("/development")) { diff --git a/instrumentation/aws-sdk/aws-sdk-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v2_2/AwsSdkSingletons.java b/instrumentation/aws-sdk/aws-sdk-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v2_2/AwsSdkSingletons.java index 33ee1679f21a..8061086babaa 100644 --- a/instrumentation/aws-sdk/aws-sdk-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v2_2/AwsSdkSingletons.java +++ b/instrumentation/aws-sdk/aws-sdk-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v2_2/AwsSdkSingletons.java @@ -5,6 +5,8 @@ package io.opentelemetry.javaagent.instrumentation.awssdk.v2_2; +import io.opentelemetry.api.incubator.config.ConfigProvider; +import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; import io.opentelemetry.instrumentation.api.internal.ConfigPropertiesUtil; import io.opentelemetry.instrumentation.awssdk.v2_2.AwsSdkTelemetry; import io.opentelemetry.instrumentation.awssdk.v2_2.internal.AbstractAwsSdkTelemetryFactory; @@ -34,8 +36,16 @@ protected boolean messagingReceiveInstrumentationEnabled() { @Override protected boolean getBoolean(boolean defaultValue, String... name) { - return AgentInstrumentationConfig.get() - .getBoolean(ConfigPropertiesUtil.toSystemProperty(name), defaultValue); + InstrumentationConfig instrumentationConfig = AgentInstrumentationConfig.get(); + ConfigProvider configProvider = instrumentationConfig.getConfigProvider(); + if (configProvider != null) { + // don't use to InstrumentationConfig, which would use a bridge back to declarative config + return ConfigPropertiesUtil.getConfigProperties(configProvider, name) + .getBoolean(name[name.length - 1], defaultValue); + } + + return instrumentationConfig.getBoolean( + ConfigPropertiesUtil.toSystemProperty(name), defaultValue); } } From 5221a186239322bc52de20183b361569b6d0a2f5 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Thu, 4 Dec 2025 17:29:03 +0100 Subject: [PATCH 40/79] normalize system props before lookup to avoid ambiguity of "experimental-foo" and "experimental.foo" that both translate to "foo/development" --- .../api/internal/ConfigPropertiesUtil.java | 36 +++++++++++++------ .../internal/ConfigPropertiesUtilTest.java | 8 ++++- 2 files changed, 32 insertions(+), 12 deletions(-) diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java index 7fa5c266bc34..f7b1056396de 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java @@ -12,9 +12,11 @@ import io.opentelemetry.api.incubator.ExtendedOpenTelemetry; import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; +import io.opentelemetry.api.internal.ConfigUtil; import java.util.Arrays; +import java.util.HashMap; import java.util.List; -import java.util.Locale; +import java.util.Map; import java.util.Optional; import java.util.stream.Collectors; import javax.annotation.Nullable; @@ -27,6 +29,26 @@ public final class ConfigPropertiesUtil { private static final boolean supportsDeclarativeConfig = supportsDeclarativeConfig(); + private static final Map config = load(); + + public static Map load() { + Map config = new HashMap<>(); + System.getenv() + .forEach( + (name, value) -> config.put(ConfigUtil.normalizeEnvironmentVariableKey(name), value)); + ConfigUtil.safeSystemProperties() + .forEach( + (key, value) -> + config.put(ConfigUtil.normalizePropertyKey(key.toString()), value.toString())); + return config; + } + + /** Resets the cached config for testing purposes. */ + public static void resetForTest() { + config.clear(); + config.putAll(load()); + } + private static boolean supportsDeclarativeConfig() { try { Class.forName("io.opentelemetry.api.incubator.ExtendedOpenTelemetry"); @@ -91,11 +113,7 @@ public static int getInt(String propertyName, int defaultValue) { */ @Nullable public static String getString(String propertyName) { - String value = System.getProperty(propertyName); - if (value != null) { - return value; - } - return System.getenv(toEnvVarName(propertyName)); + return config.get(ConfigUtil.normalizePropertyKey(propertyName)); } /** @@ -136,10 +154,6 @@ private static List filterBlanksAndNulls(String[] values) { .collect(Collectors.toList()); } - private static String toEnvVarName(String propertyName) { - return propertyName.toUpperCase(Locale.ROOT).replace('-', '_').replace('.', '_'); - } - private static String leaf(String[] propertyName) { return propertyName[propertyName.length - 1]; } @@ -174,7 +188,7 @@ public static String toSystemProperty(String[] propertyName) { for (int i = 0; i < propertyName.length; i++) { if (propertyName[i].endsWith("/development")) { propertyName[i] = - "experimental-" + propertyName[i].substring(0, propertyName[i].length() - 12); + "experimental." + propertyName[i].substring(0, propertyName[i].length() - 12); } } return "otel.instrumentation." + String.join(".", propertyName).replace('_', '-'); diff --git a/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java b/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java index 69b57f7ee301..54a017e07501 100644 --- a/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java +++ b/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java @@ -19,6 +19,7 @@ import java.util.Collections; import java.util.List; import java.util.stream.Stream; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -28,6 +29,11 @@ class ConfigPropertiesUtilTest { + @BeforeEach + void setUp() { + ConfigPropertiesUtil.resetForTest(); + } + @SetEnvironmentVariable(key = "TEST_PROPERTY_STRING", value = "env") @SetSystemProperty(key = "test.property.string", value = "sys") @Test @@ -176,7 +182,7 @@ void toSystemProperty() { assertThat(ConfigPropertiesUtil.toSystemProperty(new String[] {"a_b", "c", "d"})) .isEqualTo("otel.instrumentation.a-b.c.d"); assertThat(ConfigPropertiesUtil.toSystemProperty(new String[] {"a_b/development", "c", "d"})) - .isEqualTo("otel.instrumentation.experimental-a-b.c.d"); + .isEqualTo("otel.instrumentation.experimental.a-b.c.d"); } @SetEnvironmentVariable(key = "OTEL_INSTRUMENTATION_TEST_PROPERTY_LIST", value = "a,b,c") From aa2ebcbefbf47b6ed023e431f2169bc9d8a38e14 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Thu, 4 Dec 2025 17:47:38 +0100 Subject: [PATCH 41/79] normalize system props before lookup to avoid ambiguity of "experimental-foo" and "experimental.foo" that both translate to "foo/development" --- .../api/internal/ConfigPropertiesUtil.java | 35 ++++++++++++++++--- 1 file changed, 30 insertions(+), 5 deletions(-) diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java index f7b1056396de..8fa11eb53d53 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java @@ -12,12 +12,14 @@ import io.opentelemetry.api.incubator.ExtendedOpenTelemetry; import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; -import io.opentelemetry.api.internal.ConfigUtil; import java.util.Arrays; +import java.util.ConcurrentModificationException; import java.util.HashMap; import java.util.List; +import java.util.Locale; import java.util.Map; import java.util.Optional; +import java.util.Properties; import java.util.stream.Collectors; import javax.annotation.Nullable; @@ -35,11 +37,11 @@ public static Map load() { Map config = new HashMap<>(); System.getenv() .forEach( - (name, value) -> config.put(ConfigUtil.normalizeEnvironmentVariableKey(name), value)); - ConfigUtil.safeSystemProperties() + (name, value) -> config.put(normalizeEnvironmentVariableKey(name), value)); + safeSystemProperties() .forEach( (key, value) -> - config.put(ConfigUtil.normalizePropertyKey(key.toString()), value.toString())); + config.put(normalizePropertyKey(key.toString()), value.toString())); return config; } @@ -113,7 +115,7 @@ public static int getInt(String propertyName, int defaultValue) { */ @Nullable public static String getString(String propertyName) { - return config.get(ConfigUtil.normalizePropertyKey(propertyName)); + return config.get(normalizePropertyKey(propertyName)); } /** @@ -194,5 +196,28 @@ public static String toSystemProperty(String[] propertyName) { return "otel.instrumentation." + String.join(".", propertyName).replace('_', '-'); } + /** + * Normalize an environment variable key by converting to lower case and replacing "_" with ".". + */ + public static String normalizeEnvironmentVariableKey(String key) { + return key.toLowerCase(Locale.ROOT).replace("_", "."); + } + + /** Normalize a property key by converting to lower case and replacing "-" with ".". */ + public static String normalizePropertyKey(String key) { + return key.toLowerCase(Locale.ROOT).replace("-", "."); + } + + /** + * Returns a copy of system properties which is safe to iterate over. + * + *

In java 8 and android environments, iterating through system properties may trigger {@link + * ConcurrentModificationException}. This method ensures callers can iterate safely without risk + * of exception. See https://github.com/open-telemetry/opentelemetry-java/issues/6732 for details. + */ + public static Properties safeSystemProperties() { + return (Properties) System.getProperties().clone(); + } + private ConfigPropertiesUtil() {} } From 6abc03f98a4942437f1e86b719a7059b91431575 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Fri, 5 Dec 2025 07:59:15 +0100 Subject: [PATCH 42/79] normalize system props before lookup to avoid ambiguity of "experimental-foo" and "experimental.foo" that both translate to "foo/development" --- javaagent-tooling/build.gradle.kts | 1 + .../SpanLoggingCustomizerProviderTest.java | 2 ++ .../ConfigurationPropertiesSupplierTest.java | 3 +++ .../tooling/config/ConfigurationFileTest.java | 26 ++++++++----------- 4 files changed, 17 insertions(+), 15 deletions(-) diff --git a/javaagent-tooling/build.gradle.kts b/javaagent-tooling/build.gradle.kts index 5434028a60a0..bc69d6a56f34 100644 --- a/javaagent-tooling/build.gradle.kts +++ b/javaagent-tooling/build.gradle.kts @@ -105,6 +105,7 @@ testing { val testConfigFile by registering(JvmTestSuite::class) { dependencies { + implementation(project(":instrumentation-api")) implementation(project(":javaagent-tooling")) // requires mockito-inline implementation("uk.org.webcompere:system-stubs-jupiter") diff --git a/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/SpanLoggingCustomizerProviderTest.java b/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/SpanLoggingCustomizerProviderTest.java index 93f040a01314..59a09842e452 100644 --- a/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/SpanLoggingCustomizerProviderTest.java +++ b/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/SpanLoggingCustomizerProviderTest.java @@ -7,6 +7,7 @@ import static org.assertj.core.api.Assertions.assertThat; +import io.opentelemetry.instrumentation.api.internal.ConfigPropertiesUtil; import io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfiguration; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel; import java.io.ByteArrayInputStream; @@ -33,6 +34,7 @@ void addSpanLoggingExporter(String propertyValue, boolean alreadyAdded, boolean if (propertyValue != null) { System.setProperty("otel.javaagent.debug", propertyValue); } + ConfigPropertiesUtil.resetForTest(); String yaml = alreadyAdded ? "file_format: \"1.0-rc.1\"\n" diff --git a/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/config/ConfigurationPropertiesSupplierTest.java b/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/config/ConfigurationPropertiesSupplierTest.java index 93c4b7574999..650e2ed259b3 100644 --- a/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/config/ConfigurationPropertiesSupplierTest.java +++ b/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/config/ConfigurationPropertiesSupplierTest.java @@ -10,6 +10,7 @@ import static org.assertj.core.api.Assertions.assertThat; import io.opentelemetry.api.GlobalOpenTelemetry; +import io.opentelemetry.instrumentation.api.internal.ConfigPropertiesUtil; import io.opentelemetry.javaagent.tooling.OpenTelemetryInstaller; import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk; import io.opentelemetry.sdk.autoconfigure.internal.AutoConfigureUtil; @@ -33,6 +34,7 @@ class ConfigurationPropertiesSupplierTest { void setUp() { GlobalOpenTelemetry.resetForTest(); ConfigurationFile.resetForTest(); + ConfigPropertiesUtil.resetForTest(); } // regression for https://github.com/open-telemetry/opentelemetry-java-instrumentation/issues/6696 @@ -43,6 +45,7 @@ void fileConfigOverwritesUserPropertiesSupplier(@TempDir Path tempDir) throws IO Path configFile = tempDir.resolve("test-config.properties"); Files.write(configFile, singleton("custom.key = 42")); System.setProperty(ConfigurationFile.CONFIGURATION_FILE_PROPERTY, configFile.toString()); + ConfigPropertiesUtil.resetForTest(); // when AutoConfiguredOpenTelemetrySdk autoConfiguredSdk = diff --git a/javaagent-tooling/src/testConfigFile/java/io/opentelemetry/javaagent/tooling/config/ConfigurationFileTest.java b/javaagent-tooling/src/testConfigFile/java/io/opentelemetry/javaagent/tooling/config/ConfigurationFileTest.java index 52e6d54261fe..20cbb645bb71 100644 --- a/javaagent-tooling/src/testConfigFile/java/io/opentelemetry/javaagent/tooling/config/ConfigurationFileTest.java +++ b/javaagent-tooling/src/testConfigFile/java/io/opentelemetry/javaagent/tooling/config/ConfigurationFileTest.java @@ -7,6 +7,7 @@ import static org.assertj.core.api.Assertions.assertThat; +import io.opentelemetry.instrumentation.api.internal.ConfigPropertiesUtil; import java.io.File; import java.io.IOException; import java.io.OutputStreamWriter; @@ -36,9 +37,7 @@ void shouldUseEnvVar() throws IOException { String path = createFile("config", "property1=val-env"); environmentVariables.set("OTEL_JAVAAGENT_CONFIGURATION_FILE", path); - Map properties = ConfigurationFile.loadConfigFile(); - - assertThat(properties).containsEntry("property1", "val-env"); + assertThat(load()).containsEntry("property1", "val-env"); } @Test @@ -46,9 +45,7 @@ void shouldUseSystemProperty() throws IOException { String path = createFile("config", "property1=val-sys"); systemProperties.set("otel.javaagent.configuration-file", path); - Map properties = ConfigurationFile.loadConfigFile(); - - assertThat(properties).containsEntry("property1", "val-sys"); + assertThat(load()).containsEntry("property1", "val-sys"); } @Test @@ -58,25 +55,19 @@ void shouldUseSystemPropertyOverEnvVar() throws IOException { systemProperties.set("otel.javaagent.configuration-file", path); environmentVariables.set("OTEL_JAVAAGENT_CONFIGURATION_FILE", pathEnv); - Map properties = ConfigurationFile.loadConfigFile(); - - assertThat(properties).containsEntry("property1", "val-sys"); + assertThat(load()).containsEntry("property1", "val-sys"); } @Test void shouldReturnEmptyPropertiesIfFileDoesNotExist() { systemProperties.set("otel.javaagent.configuration-file", "somePath"); - Map properties = ConfigurationFile.loadConfigFile(); - - assertThat(properties).isEmpty(); + assertThat(load()).isEmpty(); } @Test void shouldReturnEmptyPropertiesIfPropertyIsNotSet() { - Map properties = ConfigurationFile.loadConfigFile(); - - assertThat(properties).isEmpty(); + assertThat(load()).isEmpty(); } private String createFile(String name, String contents) throws IOException { @@ -87,4 +78,9 @@ private String createFile(String name, String contents) throws IOException { } return file.getAbsolutePath(); } + + private static Map load() { + ConfigPropertiesUtil.resetForTest(); + return ConfigurationFile.loadConfigFile(); + } } From 91d25fcfe556966879ee14bb816c8288ba7f0eec Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Fri, 5 Dec 2025 10:12:46 +0100 Subject: [PATCH 43/79] normalize system props before lookup to avoid ambiguity of "experimental-foo" and "experimental.foo" that both translate to "foo/development" --- .../instrumentation/api/internal/ConfigPropertiesUtil.java | 6 ++---- 1 file changed, 2 insertions(+), 4 deletions(-) diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java index 8fa11eb53d53..1987fd065bbb 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java @@ -36,12 +36,10 @@ public final class ConfigPropertiesUtil { public static Map load() { Map config = new HashMap<>(); System.getenv() - .forEach( - (name, value) -> config.put(normalizeEnvironmentVariableKey(name), value)); + .forEach((name, value) -> config.put(normalizeEnvironmentVariableKey(name), value)); safeSystemProperties() .forEach( - (key, value) -> - config.put(normalizePropertyKey(key.toString()), value.toString())); + (key, value) -> config.put(normalizePropertyKey(key.toString()), value.toString())); return config; } From 36494c5aa98c2a577b1951e62054af5c82e58b1e Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Fri, 5 Dec 2025 12:14:42 +0100 Subject: [PATCH 44/79] rename js snippet property --- docs/advanced-configuration-options.md | 6 +++--- .../smoketest/AbstractTestContainerManager.java | 4 +++- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/docs/advanced-configuration-options.md b/docs/advanced-configuration-options.md index 67870038f862..4ae0e075c5d1 100644 --- a/docs/advanced-configuration-options.md +++ b/docs/advanced-configuration-options.md @@ -45,9 +45,9 @@ This feature is designed for integrating client-side monitoring. We plan to integrate OpenTelemetry's own client-side monitoring solution by default once it's available (see the [browser instrumentation proposal](https://github.com/open-telemetry/community/blob/main/projects/browser-phase-1.md)). -| System property | Environment variable | Purpose | -|----------------------------------------------------------------|--------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| -| `otel.instrumentation.servlet.experimental.javascript-snippet` | OTEL_EXPERIMENTAL_JAVASCRIPT_SNIPPET | Experimental setting to inject a JavaScript snippet into HTML responses after the opening `` tag. The value should be a complete JavaScript snippet including `"` | +| System property | Environment variable | Purpose | +|----------------------------------------------------------------|----------------------------------------------------------------|----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| +| `otel.instrumentation.servlet.experimental.javascript-snippet` | `OTEL_INSTRUMENTATION_SERVLET_EXPERIMENTAL_JAVASCRIPT_SNIPPET` | Experimental setting to inject a JavaScript snippet into HTML responses after the opening `` tag. The value should be a complete JavaScript snippet including `"` | **Important notes:** diff --git a/smoke-tests/src/main/java/io/opentelemetry/smoketest/AbstractTestContainerManager.java b/smoke-tests/src/main/java/io/opentelemetry/smoketest/AbstractTestContainerManager.java index 985c4381138a..8342151bb4c5 100644 --- a/smoke-tests/src/main/java/io/opentelemetry/smoketest/AbstractTestContainerManager.java +++ b/smoke-tests/src/main/java/io/opentelemetry/smoketest/AbstractTestContainerManager.java @@ -45,7 +45,9 @@ protected Map getAgentEnvironment( environment.put("OTEL_RESOURCE_ATTRIBUTES", "service.name=smoke-test"); } environment.put("OTEL_JAVAAGENT_DEBUG", "true"); - environment.put("OTEL_EXPERIMENTAL_JAVASCRIPT_SNIPPET", ""); + environment.put( + "OTEL_INSTRUMENTATION_SERVLET_EXPERIMENTAL_JAVASCRIPT_SNIPPET", + ""); environment.put("OTEL_INSTRUMENTATION_RUNTIME_TELEMETRY_PACKAGE_EMITTER_ENABLED", "true"); return environment; } From 8eaf7d6f0ee96859630bed24494b9f4944a351c6 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Fri, 5 Dec 2025 13:12:51 +0100 Subject: [PATCH 45/79] normalize system props before lookup to avoid ambiguity of "experimental-foo" and "experimental.foo" that both translate to "foo/development" --- .../api/internal/ConfigPropertiesUtil.java | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java index 1987fd065bbb..1c43f8914501 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java @@ -35,11 +35,12 @@ public final class ConfigPropertiesUtil { public static Map load() { Map config = new HashMap<>(); - System.getenv() - .forEach((name, value) -> config.put(normalizeEnvironmentVariableKey(name), value)); - safeSystemProperties() - .forEach( - (key, value) -> config.put(normalizePropertyKey(key.toString()), value.toString())); + for (Map.Entry entry : System.getenv().entrySet()) { + config.put(normalizeEnvironmentVariableKey(entry.getKey()), entry.getValue()); + } + for (Map.Entry entry : safeSystemProperties().entrySet()) { + config.put(normalizePropertyKey(entry.getKey().toString()), entry.getValue().toString()); + } return config; } From 031ab24f634af199851eb678f7e40a34ebab2b21 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Sun, 7 Dec 2025 17:34:39 +0100 Subject: [PATCH 46/79] add changelog --- CHANGELOG.md | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/CHANGELOG.md b/CHANGELOG.md index ccb7a7d3abc5..e706949721ca 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,6 +6,12 @@ ### ⚠️ Breaking Changes +- Rename `otel.experimental.javascript-snippet` to + `otel.instrumentation.servlet.experimental.javascript-snippet` to follow naming conventions + ([#15339](https://github.com/open-telemetry/opentelemetry-java-instrumentation/pull/15339)) + +### ⚠️ Breaking Changes + - ActiveMQ Classic JMX metrics: rename attributes and metrics to align with semantic conventions (see PR description for specifics) ([#14996](https://github.com/open-telemetry/opentelemetry-java-instrumentation/pull/14996)) From 86456ca3328cff096c31e3a7887b7e9030af8150 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Sun, 7 Dec 2025 21:48:57 +0100 Subject: [PATCH 47/79] format --- CHANGELOG.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/CHANGELOG.md b/CHANGELOG.md index e706949721ca..87b50ea01989 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -6,7 +6,7 @@ ### ⚠️ Breaking Changes -- Rename `otel.experimental.javascript-snippet` to +- Rename `otel.experimental.javascript-snippet` to `otel.instrumentation.servlet.experimental.javascript-snippet` to follow naming conventions ([#15339](https://github.com/open-telemetry/opentelemetry-java-instrumentation/pull/15339)) From edcda71913499a358811e48736b0cb3bd396d023 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Thu, 11 Dec 2025 12:32:22 +0100 Subject: [PATCH 48/79] remove param that is always false --- .../instrumentation/awssdk/v2_2/AwsSdkSingletons.java | 7 +++---- .../awssdk/v2_2/autoconfigure/AwsSdkSingletons.java | 4 ++-- .../v2_2/internal/AbstractAwsSdkTelemetryFactory.java | 10 +++++----- 3 files changed, 10 insertions(+), 11 deletions(-) diff --git a/instrumentation/aws-sdk/aws-sdk-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v2_2/AwsSdkSingletons.java b/instrumentation/aws-sdk/aws-sdk-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v2_2/AwsSdkSingletons.java index 8061086babaa..da0391246112 100644 --- a/instrumentation/aws-sdk/aws-sdk-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v2_2/AwsSdkSingletons.java +++ b/instrumentation/aws-sdk/aws-sdk-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v2_2/AwsSdkSingletons.java @@ -35,17 +35,16 @@ protected boolean messagingReceiveInstrumentationEnabled() { } @Override - protected boolean getBoolean(boolean defaultValue, String... name) { + protected boolean getBoolean(String... name) { InstrumentationConfig instrumentationConfig = AgentInstrumentationConfig.get(); ConfigProvider configProvider = instrumentationConfig.getConfigProvider(); if (configProvider != null) { // don't use to InstrumentationConfig, which would use a bridge back to declarative config return ConfigPropertiesUtil.getConfigProperties(configProvider, name) - .getBoolean(name[name.length - 1], defaultValue); + .getBoolean(name[name.length - 1], false); } - return instrumentationConfig.getBoolean( - ConfigPropertiesUtil.toSystemProperty(name), defaultValue); + return instrumentationConfig.getBoolean(ConfigPropertiesUtil.toSystemProperty(name), false); } } diff --git a/instrumentation/aws-sdk/aws-sdk-2.2/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/autoconfigure/AwsSdkSingletons.java b/instrumentation/aws-sdk/aws-sdk-2.2/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/autoconfigure/AwsSdkSingletons.java index f6205858923e..e2f4528a23ca 100644 --- a/instrumentation/aws-sdk/aws-sdk-2.2/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/autoconfigure/AwsSdkSingletons.java +++ b/instrumentation/aws-sdk/aws-sdk-2.2/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/autoconfigure/AwsSdkSingletons.java @@ -35,8 +35,8 @@ protected boolean messagingReceiveInstrumentationEnabled() { } @Override - protected boolean getBoolean(boolean defaultValue, String... name) { - return ConfigPropertiesUtil.getBoolean(GlobalOpenTelemetry.get(), name).orElse(defaultValue); + protected boolean getBoolean(String... name) { + return ConfigPropertiesUtil.getBoolean(GlobalOpenTelemetry.get(), name).orElse(false); } } diff --git a/instrumentation/aws-sdk/aws-sdk-2.2/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/internal/AbstractAwsSdkTelemetryFactory.java b/instrumentation/aws-sdk/aws-sdk-2.2/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/internal/AbstractAwsSdkTelemetryFactory.java index 33e7280323f3..134680788b5c 100644 --- a/instrumentation/aws-sdk/aws-sdk-2.2/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/internal/AbstractAwsSdkTelemetryFactory.java +++ b/instrumentation/aws-sdk/aws-sdk-2.2/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/internal/AbstractAwsSdkTelemetryFactory.java @@ -17,24 +17,24 @@ public abstract class AbstractAwsSdkTelemetryFactory { protected abstract List getCapturedHeaders(); private boolean captureExperimentalSpanAttributes() { - return getBoolean(false, "aws_sdk", "span_attributes/development"); + return getBoolean("aws_sdk", "span_attributes/development"); } protected abstract boolean messagingReceiveInstrumentationEnabled(); private boolean useMessagingPropagator() { - return getBoolean(false, "aws_sdk", "use_propagator_for_messaging/development"); + return getBoolean("aws_sdk", "use_propagator_for_messaging/development"); } private boolean recordIndividualHttpError() { - return getBoolean(false, "aws_sdk", "record_individual_http_error/development"); + return getBoolean("aws_sdk", "record_individual_http_error/development"); } private boolean genaiCaptureMessageContent() { - return getBoolean(false, "genai", "capture_message_content"); + return getBoolean("genai", "capture_message_content"); } - protected abstract boolean getBoolean(boolean defaultValue, String... name); + protected abstract boolean getBoolean(String... name); public AwsSdkTelemetry telemetry() { return AwsSdkTelemetry.builder(GlobalOpenTelemetry.get()) From 7ed8b6efdd37137e7f58175c529fb84ff9edbd81 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Thu, 11 Dec 2025 17:17:59 +0100 Subject: [PATCH 49/79] remove performance optimization --- .../api/internal/ConfigPropertiesUtil.java | 23 +----- .../api/internal/ConfigUtil.java | 82 +++++++++++++++++++ .../internal/ConfigPropertiesUtilTest.java | 6 -- .../SpanLoggingCustomizerProviderTest.java | 2 - .../ConfigurationPropertiesSupplierTest.java | 3 - 5 files changed, 83 insertions(+), 33 deletions(-) create mode 100644 instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigUtil.java diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java index 1c43f8914501..b72c4b5472ef 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java @@ -14,10 +14,8 @@ import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import java.util.Arrays; import java.util.ConcurrentModificationException; -import java.util.HashMap; import java.util.List; import java.util.Locale; -import java.util.Map; import java.util.Optional; import java.util.Properties; import java.util.stream.Collectors; @@ -31,25 +29,6 @@ public final class ConfigPropertiesUtil { private static final boolean supportsDeclarativeConfig = supportsDeclarativeConfig(); - private static final Map config = load(); - - public static Map load() { - Map config = new HashMap<>(); - for (Map.Entry entry : System.getenv().entrySet()) { - config.put(normalizeEnvironmentVariableKey(entry.getKey()), entry.getValue()); - } - for (Map.Entry entry : safeSystemProperties().entrySet()) { - config.put(normalizePropertyKey(entry.getKey().toString()), entry.getValue().toString()); - } - return config; - } - - /** Resets the cached config for testing purposes. */ - public static void resetForTest() { - config.clear(); - config.putAll(load()); - } - private static boolean supportsDeclarativeConfig() { try { Class.forName("io.opentelemetry.api.incubator.ExtendedOpenTelemetry"); @@ -114,7 +93,7 @@ public static int getInt(String propertyName, int defaultValue) { */ @Nullable public static String getString(String propertyName) { - return config.get(normalizePropertyKey(propertyName)); + return ConfigUtil.getString(normalizePropertyKey(propertyName)); } /** diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigUtil.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigUtil.java new file mode 100644 index 000000000000..75f431c77a96 --- /dev/null +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigUtil.java @@ -0,0 +1,82 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.api.internal; + +import java.util.ConcurrentModificationException; +import java.util.Locale; +import java.util.Map; +import java.util.Properties; +import javax.annotation.Nullable; + +/** + * Configuration utilities. + * + *

This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + * + *

Copied from SDK + * because some tests target an SDK version where this class does not exist. + */ +final class ConfigUtil { + + private ConfigUtil() {} + + /** + * Returns a copy of system properties which is safe to iterate over. + * + *

In java 8 and android environments, iterating through system properties may trigger {@link + * ConcurrentModificationException}. This method ensures callers can iterate safely without risk + * of exception. See https://github.com/open-telemetry/opentelemetry-java/issues/6732 for details. + */ + public static Properties safeSystemProperties() { + return (Properties) System.getProperties().clone(); + } + + /** + * Return the system property or environment variable for the {@code key}. + * + *

Normalize the {@code key} using {@link #normalizePropertyKey(String)}. Match to system + * property keys also normalized with {@link #normalizePropertyKey(String)}. Match to environment + * variable keys normalized with {@link #normalizeEnvironmentVariableKey(String)}. System + * properties take priority over environment variables. + * + * @param key the property key + * @return the system property if not null, or the environment variable if not null, or {@code + * null} + */ + @Nullable + public static String getString(String key) { + String normalizedKey = normalizePropertyKey(key); + + String systemProperty = + safeSystemProperties().entrySet().stream() + .filter(entry -> normalizedKey.equals(normalizePropertyKey(entry.getKey().toString()))) + .map(entry -> entry.getValue().toString()) + .findFirst() + .orElse(null); + if (systemProperty != null) { + return systemProperty; + } + return System.getenv().entrySet().stream() + .filter(entry -> normalizedKey.equals(normalizeEnvironmentVariableKey(entry.getKey()))) + .map(Map.Entry::getValue) + .findFirst() + .orElse(null); + } + + /** + * Normalize an environment variable key by converting to lower case and replacing "_" with ".". + */ + public static String normalizeEnvironmentVariableKey(String key) { + return key.toLowerCase(Locale.ROOT).replace("_", "."); + } + + /** Normalize a property key by converting to lower case and replacing "-" with ".". */ + public static String normalizePropertyKey(String key) { + return key.toLowerCase(Locale.ROOT).replace("-", "."); + } +} diff --git a/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java b/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java index 54a017e07501..6575d42340ea 100644 --- a/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java +++ b/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java @@ -19,7 +19,6 @@ import java.util.Collections; import java.util.List; import java.util.stream.Stream; -import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; @@ -29,11 +28,6 @@ class ConfigPropertiesUtilTest { - @BeforeEach - void setUp() { - ConfigPropertiesUtil.resetForTest(); - } - @SetEnvironmentVariable(key = "TEST_PROPERTY_STRING", value = "env") @SetSystemProperty(key = "test.property.string", value = "sys") @Test diff --git a/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/SpanLoggingCustomizerProviderTest.java b/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/SpanLoggingCustomizerProviderTest.java index 59a09842e452..93f040a01314 100644 --- a/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/SpanLoggingCustomizerProviderTest.java +++ b/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/SpanLoggingCustomizerProviderTest.java @@ -7,7 +7,6 @@ import static org.assertj.core.api.Assertions.assertThat; -import io.opentelemetry.instrumentation.api.internal.ConfigPropertiesUtil; import io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfiguration; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel; import java.io.ByteArrayInputStream; @@ -34,7 +33,6 @@ void addSpanLoggingExporter(String propertyValue, boolean alreadyAdded, boolean if (propertyValue != null) { System.setProperty("otel.javaagent.debug", propertyValue); } - ConfigPropertiesUtil.resetForTest(); String yaml = alreadyAdded ? "file_format: \"1.0-rc.1\"\n" diff --git a/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/config/ConfigurationPropertiesSupplierTest.java b/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/config/ConfigurationPropertiesSupplierTest.java index 650e2ed259b3..93c4b7574999 100644 --- a/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/config/ConfigurationPropertiesSupplierTest.java +++ b/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/config/ConfigurationPropertiesSupplierTest.java @@ -10,7 +10,6 @@ import static org.assertj.core.api.Assertions.assertThat; import io.opentelemetry.api.GlobalOpenTelemetry; -import io.opentelemetry.instrumentation.api.internal.ConfigPropertiesUtil; import io.opentelemetry.javaagent.tooling.OpenTelemetryInstaller; import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk; import io.opentelemetry.sdk.autoconfigure.internal.AutoConfigureUtil; @@ -34,7 +33,6 @@ class ConfigurationPropertiesSupplierTest { void setUp() { GlobalOpenTelemetry.resetForTest(); ConfigurationFile.resetForTest(); - ConfigPropertiesUtil.resetForTest(); } // regression for https://github.com/open-telemetry/opentelemetry-java-instrumentation/issues/6696 @@ -45,7 +43,6 @@ void fileConfigOverwritesUserPropertiesSupplier(@TempDir Path tempDir) throws IO Path configFile = tempDir.resolve("test-config.properties"); Files.write(configFile, singleton("custom.key = 42")); System.setProperty(ConfigurationFile.CONFIGURATION_FILE_PROPERTY, configFile.toString()); - ConfigPropertiesUtil.resetForTest(); // when AutoConfiguredOpenTelemetrySdk autoConfiguredSdk = From 6e5fbb615e465d9e4d79677a3956a7663fe59b90 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Thu, 11 Dec 2025 18:08:19 +0100 Subject: [PATCH 50/79] remove performance optimization --- .../tooling/config/ConfigurationFileTest.java | 26 +++++++++++-------- 1 file changed, 15 insertions(+), 11 deletions(-) diff --git a/javaagent-tooling/src/testConfigFile/java/io/opentelemetry/javaagent/tooling/config/ConfigurationFileTest.java b/javaagent-tooling/src/testConfigFile/java/io/opentelemetry/javaagent/tooling/config/ConfigurationFileTest.java index 20cbb645bb71..52e6d54261fe 100644 --- a/javaagent-tooling/src/testConfigFile/java/io/opentelemetry/javaagent/tooling/config/ConfigurationFileTest.java +++ b/javaagent-tooling/src/testConfigFile/java/io/opentelemetry/javaagent/tooling/config/ConfigurationFileTest.java @@ -7,7 +7,6 @@ import static org.assertj.core.api.Assertions.assertThat; -import io.opentelemetry.instrumentation.api.internal.ConfigPropertiesUtil; import java.io.File; import java.io.IOException; import java.io.OutputStreamWriter; @@ -37,7 +36,9 @@ void shouldUseEnvVar() throws IOException { String path = createFile("config", "property1=val-env"); environmentVariables.set("OTEL_JAVAAGENT_CONFIGURATION_FILE", path); - assertThat(load()).containsEntry("property1", "val-env"); + Map properties = ConfigurationFile.loadConfigFile(); + + assertThat(properties).containsEntry("property1", "val-env"); } @Test @@ -45,7 +46,9 @@ void shouldUseSystemProperty() throws IOException { String path = createFile("config", "property1=val-sys"); systemProperties.set("otel.javaagent.configuration-file", path); - assertThat(load()).containsEntry("property1", "val-sys"); + Map properties = ConfigurationFile.loadConfigFile(); + + assertThat(properties).containsEntry("property1", "val-sys"); } @Test @@ -55,19 +58,25 @@ void shouldUseSystemPropertyOverEnvVar() throws IOException { systemProperties.set("otel.javaagent.configuration-file", path); environmentVariables.set("OTEL_JAVAAGENT_CONFIGURATION_FILE", pathEnv); - assertThat(load()).containsEntry("property1", "val-sys"); + Map properties = ConfigurationFile.loadConfigFile(); + + assertThat(properties).containsEntry("property1", "val-sys"); } @Test void shouldReturnEmptyPropertiesIfFileDoesNotExist() { systemProperties.set("otel.javaagent.configuration-file", "somePath"); - assertThat(load()).isEmpty(); + Map properties = ConfigurationFile.loadConfigFile(); + + assertThat(properties).isEmpty(); } @Test void shouldReturnEmptyPropertiesIfPropertyIsNotSet() { - assertThat(load()).isEmpty(); + Map properties = ConfigurationFile.loadConfigFile(); + + assertThat(properties).isEmpty(); } private String createFile(String name, String contents) throws IOException { @@ -78,9 +87,4 @@ private String createFile(String name, String contents) throws IOException { } return file.getAbsolutePath(); } - - private static Map load() { - ConfigPropertiesUtil.resetForTest(); - return ConfigurationFile.loadConfigFile(); - } } From 16cc3a77b3660140ee537b0b4c25e7a16159066d Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Thu, 11 Dec 2025 19:52:58 +0100 Subject: [PATCH 51/79] avoid lambda in early phase --- .../api/internal/ConfigUtil.java | 25 +++++++++---------- 1 file changed, 12 insertions(+), 13 deletions(-) diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigUtil.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigUtil.java index 75f431c77a96..701545845fba 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigUtil.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigUtil.java @@ -52,20 +52,19 @@ public static Properties safeSystemProperties() { public static String getString(String key) { String normalizedKey = normalizePropertyKey(key); - String systemProperty = - safeSystemProperties().entrySet().stream() - .filter(entry -> normalizedKey.equals(normalizePropertyKey(entry.getKey().toString()))) - .map(entry -> entry.getValue().toString()) - .findFirst() - .orElse(null); - if (systemProperty != null) { - return systemProperty; + for (Map.Entry entry : safeSystemProperties().entrySet()) { + if (normalizedKey.equals(normalizePropertyKey(entry.getKey().toString()))) { + return entry.getValue().toString(); + } } - return System.getenv().entrySet().stream() - .filter(entry -> normalizedKey.equals(normalizeEnvironmentVariableKey(entry.getKey()))) - .map(Map.Entry::getValue) - .findFirst() - .orElse(null); + + for (Map.Entry entry : System.getenv().entrySet()) { + if (normalizedKey.equals(normalizeEnvironmentVariableKey(entry.getKey()))) { + return entry.getValue(); + } + } + + return null; } /** From 3c4a06907e62fb4bcc8613cc662bb4f0634648f1 Mon Sep 17 00:00:00 2001 From: Trask Stalnaker Date: Thu, 11 Dec 2025 13:06:15 -0800 Subject: [PATCH 52/79] deprecated fallback --- .../servlet/ExperimentalSnippetHolder.java | 29 +++++++++++++++++-- 1 file changed, 26 insertions(+), 3 deletions(-) diff --git a/instrumentation/servlet/servlet-common/bootstrap/src/main/java/io/opentelemetry/javaagent/bootstrap/servlet/ExperimentalSnippetHolder.java b/instrumentation/servlet/servlet-common/bootstrap/src/main/java/io/opentelemetry/javaagent/bootstrap/servlet/ExperimentalSnippetHolder.java index 45e6f21bd782..8f71ad931065 100644 --- a/instrumentation/servlet/servlet-common/bootstrap/src/main/java/io/opentelemetry/javaagent/bootstrap/servlet/ExperimentalSnippetHolder.java +++ b/instrumentation/servlet/servlet-common/bootstrap/src/main/java/io/opentelemetry/javaagent/bootstrap/servlet/ExperimentalSnippetHolder.java @@ -5,17 +5,40 @@ package io.opentelemetry.javaagent.bootstrap.servlet; +import static java.util.logging.Level.WARNING; + import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.instrumentation.api.internal.ConfigPropertiesUtil; +import java.util.Optional; +import java.util.logging.Logger; public class ExperimentalSnippetHolder { + private static final Logger logger = Logger.getLogger(ExperimentalSnippetHolder.class.getName()); + + private static final String DEPRECATED_PROPERTY_NAME = "otel.experimental.javascript-snippet"; + private static final String NEW_PROPERTY_NAME = + "otel.instrumentation.servlet.experimental.javascript-snippet"; + private static volatile String snippet = getSnippetSetting(); private static String getSnippetSetting() { - return ConfigPropertiesUtil.getString( - GlobalOpenTelemetry.get(), "servlet", "javascript-snippet/development") - .orElse(""); + Optional snippet = + ConfigPropertiesUtil.getString( + GlobalOpenTelemetry.get(), "servlet", "javascript-snippet/development"); + // Can remove deprecated fallback in 2.24.0 + return snippet.orElseGet( + () -> { + String deprecatedValue = ConfigPropertiesUtil.getString(DEPRECATED_PROPERTY_NAME); + if (deprecatedValue != null) { + logger.log( + WARNING, + "Deprecated property \"{0}\" was used; use the \"{1}\" property instead", + new Object[] {DEPRECATED_PROPERTY_NAME, NEW_PROPERTY_NAME}); + return deprecatedValue; + } + return ""; + }); } public static void setSnippet(String newValue) { From 3982f888be608017059dd5afe5c2a17feaf2d775 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Fri, 12 Dec 2025 07:31:23 +0100 Subject: [PATCH 53/79] cleanup --- .../api/internal/ConfigPropertiesUtil.java | 28 +------------------ 1 file changed, 1 insertion(+), 27 deletions(-) diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java index b72c4b5472ef..d70597aa467c 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java @@ -13,11 +13,8 @@ import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import java.util.Arrays; -import java.util.ConcurrentModificationException; import java.util.List; -import java.util.Locale; import java.util.Optional; -import java.util.Properties; import java.util.stream.Collectors; import javax.annotation.Nullable; @@ -93,7 +90,7 @@ public static int getInt(String propertyName, int defaultValue) { */ @Nullable public static String getString(String propertyName) { - return ConfigUtil.getString(normalizePropertyKey(propertyName)); + return ConfigUtil.getString(ConfigUtil.normalizePropertyKey(propertyName)); } /** @@ -174,28 +171,5 @@ public static String toSystemProperty(String[] propertyName) { return "otel.instrumentation." + String.join(".", propertyName).replace('_', '-'); } - /** - * Normalize an environment variable key by converting to lower case and replacing "_" with ".". - */ - public static String normalizeEnvironmentVariableKey(String key) { - return key.toLowerCase(Locale.ROOT).replace("_", "."); - } - - /** Normalize a property key by converting to lower case and replacing "-" with ".". */ - public static String normalizePropertyKey(String key) { - return key.toLowerCase(Locale.ROOT).replace("-", "."); - } - - /** - * Returns a copy of system properties which is safe to iterate over. - * - *

In java 8 and android environments, iterating through system properties may trigger {@link - * ConcurrentModificationException}. This method ensures callers can iterate safely without risk - * of exception. See https://github.com/open-telemetry/opentelemetry-java/issues/6732 for details. - */ - public static Properties safeSystemProperties() { - return (Properties) System.getProperties().clone(); - } - private ConfigPropertiesUtil() {} } From 61da982db7943c91ee3807acbb4c65a7838364e8 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Fri, 12 Dec 2025 13:18:03 +0100 Subject: [PATCH 54/79] fix experimental in the middle --- .../instrumentation/api/internal/ConfigPropertiesUtil.java | 7 ++++--- .../api/internal/ConfigPropertiesUtilTest.java | 4 ++++ 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java index d70597aa467c..318be4b24eb8 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java @@ -163,9 +163,10 @@ public static DeclarativeConfigProperties getConfigProperties( public static String toSystemProperty(String[] propertyName) { for (int i = 0; i < propertyName.length; i++) { - if (propertyName[i].endsWith("/development")) { - propertyName[i] = - "experimental." + propertyName[i].substring(0, propertyName[i].length() - 12); + String node = propertyName[i]; + if (node.endsWith("/development")) { + String prefix = node.contains("experimental") ? "" : "experimental."; + propertyName[i] = prefix + node.substring(0, node.length() - 12); } } return "otel.instrumentation." + String.join(".", propertyName).replace('_', '-'); diff --git a/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java b/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java index 6575d42340ea..a206a73fe295 100644 --- a/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java +++ b/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java @@ -177,6 +177,10 @@ void toSystemProperty() { .isEqualTo("otel.instrumentation.a-b.c.d"); assertThat(ConfigPropertiesUtil.toSystemProperty(new String[] {"a_b/development", "c", "d"})) .isEqualTo("otel.instrumentation.experimental.a-b.c.d"); + assertThat( + ConfigPropertiesUtil.toSystemProperty( + new String[] {"a_experimental_b/development", "c", "d"})) + .isEqualTo("otel.instrumentation.a-experimental-b.c.d"); } @SetEnvironmentVariable(key = "OTEL_INSTRUMENTATION_TEST_PROPERTY_LIST", value = "a,b,c") From 3b7e81b86cb07b286c3ceebf4b706539454ed575 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Fri, 12 Dec 2025 13:10:37 +0100 Subject: [PATCH 55/79] add SystemPropertiesDeclarativeConfigProperties --- .../internal/InstrumentationConfig.java | 3 + ...bstractSystemPropertiesConfigProvider.java | 103 +++++++++++++ ...PropertiesDeclarativeConfigProperties.java | 141 ++++++++++++++++++ .../api/internal/ConfigPropertiesUtil.java | 90 +++++------ .../SystemPropertiesConfigProvider.java | 13 ++ ...PropertiesDeclarativeConfigProperties.java | 28 ++++ .../internal/ConfigPropertiesUtilTest.java | 1 + .../awssdk/v2_2/AwsSdkSingletons.java | 8 +- .../OpenTelemetryAutoConfiguration.java | 19 ++- .../properties/ConfigPropertiesBridge.java | 16 +- .../SchedulingInstrumentationAspectTest.java | 3 +- ...gInstrumentationAutoConfigurationTest.java | 3 +- ...xInstrumentationAutoConfigurationTest.java | 3 +- .../WebClientBeanPostProcessorTest.java | 3 +- ...Instrumentation5AutoConfigurationTest.java | 3 +- ...tInstrumentationAutoConfigurationTest.java | 3 +- ...Instrumentation6AutoConfigurationTest.java | 3 +- ...cInstrumentationAutoConfigurationTest.java | 4 +- ...aInstrumentationAutoConfigurationTest.java | 4 +- ...cInstrumentationAutoConfigurationTest.java | 3 +- ...bInstrumentationAutoConfigurationTest.java | 3 +- .../internal/EmptyInstrumentationConfig.java | 6 + .../javaagent/tooling/AgentInstaller.java | 4 +- .../config/ConfigPropertiesBridge.java | 12 +- .../config/ConfigPropertiesBridgeTest.java | 21 ++- 25 files changed, 414 insertions(+), 86 deletions(-) create mode 100644 instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/AbstractSystemPropertiesConfigProvider.java create mode 100644 instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/AbstractSystemPropertiesDeclarativeConfigProperties.java create mode 100644 instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/SystemPropertiesConfigProvider.java create mode 100644 instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/SystemPropertiesDeclarativeConfigProperties.java diff --git a/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/config/internal/InstrumentationConfig.java b/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/config/internal/InstrumentationConfig.java index 8b1dd6626c64..1a25eac44a3f 100644 --- a/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/config/internal/InstrumentationConfig.java +++ b/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/config/internal/InstrumentationConfig.java @@ -7,6 +7,7 @@ import static java.util.Collections.emptyList; +import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import java.time.Duration; @@ -136,4 +137,6 @@ default List getList(String name) { */ @Nullable ConfigProvider getConfigProvider(); + + OpenTelemetry getOpenTelemetry(); } diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/AbstractSystemPropertiesConfigProvider.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/AbstractSystemPropertiesConfigProvider.java new file mode 100644 index 000000000000..3618d3a731f8 --- /dev/null +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/AbstractSystemPropertiesConfigProvider.java @@ -0,0 +1,103 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.api.internal; + +import io.opentelemetry.api.incubator.config.ConfigProvider; +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; +import io.opentelemetry.common.ComponentLoader; +import java.util.List; +import java.util.Set; +import javax.annotation.Nullable; + +/** + * This class is internal and is hence not for public use. Its APIs are unstable and can change at + * any time. + */ +// todo also an implementation of ConfigProvider that reads from ConfigProperties +public abstract class AbstractSystemPropertiesConfigProvider implements ConfigProvider { + @Nullable + @Override + public DeclarativeConfigProperties getInstrumentationConfig() { + return new EmptyDeclarativeConfigProperties() { + @Nullable + @Override + public DeclarativeConfigProperties getStructured(String name) { + if (name.equals("java")) { + return new EmptyDeclarativeConfigProperties() { + @Override + public DeclarativeConfigProperties getStructured(String name) { + return getProperties(name); + } + }; + } + return super.getStructured(name); + } + }; + } + + protected abstract AbstractSystemPropertiesDeclarativeConfigProperties getProperties(String name); + + private abstract static class EmptyDeclarativeConfigProperties + implements DeclarativeConfigProperties { + @Nullable + @Override + public String getString(String name) { + throw new UnsupportedOperationException(); + } + + @Nullable + @Override + public Boolean getBoolean(String name) { + throw new UnsupportedOperationException(); + } + + @Nullable + @Override + public Integer getInt(String name) { + throw new UnsupportedOperationException(); + } + + @Nullable + @Override + public Long getLong(String name) { + throw new UnsupportedOperationException(); + } + + @Nullable + @Override + public Double getDouble(String name) { + throw new UnsupportedOperationException(); + } + + @Nullable + @Override + public List getScalarList(String name, Class scalarType) { + throw new UnsupportedOperationException(); + } + + @Nullable + @Override + public DeclarativeConfigProperties getStructured(String name) { + throw new UnsupportedOperationException(); + } + + @Nullable + @Override + public List getStructuredList(String name) { + throw new UnsupportedOperationException(); + } + + @Override + public Set getPropertyKeys() { + throw new UnsupportedOperationException(); + } + + @Override + public ComponentLoader getComponentLoader() { + throw new UnsupportedOperationException(); + } + } +} diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/AbstractSystemPropertiesDeclarativeConfigProperties.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/AbstractSystemPropertiesDeclarativeConfigProperties.java new file mode 100644 index 000000000000..e37d9e4c17ab --- /dev/null +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/AbstractSystemPropertiesDeclarativeConfigProperties.java @@ -0,0 +1,141 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.api.internal; + +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; +import io.opentelemetry.common.ComponentLoader; +import java.util.ArrayList; +import java.util.Arrays; +import java.util.List; +import java.util.Set; +import java.util.stream.Collectors; +import javax.annotation.Nullable; + +/** + * This class is internal and is hence not for public use. Its APIs are unstable and can change at + * any time. + */ +public abstract class AbstractSystemPropertiesDeclarativeConfigProperties + implements DeclarativeConfigProperties { + protected final String node; + @Nullable protected final AbstractSystemPropertiesDeclarativeConfigProperties parent; + + public AbstractSystemPropertiesDeclarativeConfigProperties( + String node, @Nullable AbstractSystemPropertiesDeclarativeConfigProperties parent) { + this.node = node; + this.parent = parent; + } + + private static List filterBlanksAndNulls(String[] values) { + return Arrays.stream(values) + .map(String::trim) + .filter(s -> !s.isEmpty()) + .collect(Collectors.toList()); + } + + @Nullable + @Override + public Boolean getBoolean(String name) { + String value = getString(name); + return value == null ? null : Boolean.parseBoolean(value); + } + + @Nullable + @Override + public Integer getInt(String name) { + String strValue = getString(name); + if (strValue == null) { + return null; + } + try { + return Integer.parseInt(strValue); + } catch (NumberFormatException ignored) { + return null; + } + } + + @Nullable + @Override + public Long getLong(String name) { + String strValue = getString(name); + if (strValue == null) { + return null; + } + try { + return Long.getLong(strValue); + } catch (NumberFormatException ignored) { + return null; + } + } + + @Nullable + @Override + public Double getDouble(String name) { + String strValue = getString(name); + if (strValue == null) { + return null; + } + try { + return Double.parseDouble(strValue); + } catch (NumberFormatException ignored) { + return null; + } + } + + @SuppressWarnings("unchecked") // only String scalar type is supported + @Nullable + @Override + public List getScalarList(String name, Class scalarType) { + if (scalarType != String.class) { + throw new UnsupportedOperationException("Only String scalar type is supported"); + } + + String value = getString(name); + return value == null + ? null + : (List) + AbstractSystemPropertiesDeclarativeConfigProperties.filterBlanksAndNulls( + value.split(",")); + } + + @Nullable + @Override + public DeclarativeConfigProperties getStructured(String name) { + return newChild(name); + } + + @Nullable + @Override + public List getStructuredList(String name) { + throw new UnsupportedOperationException(); + } + + @Override + public Set getPropertyKeys() { + throw new UnsupportedOperationException(); + } + + @Override + public ComponentLoader getComponentLoader() { + throw new UnsupportedOperationException(); + } + + protected abstract AbstractSystemPropertiesDeclarativeConfigProperties newChild(String node); + + protected String getSystemProperty(String name) { + List nodes = new ArrayList<>(); + addSystemPropertyPathNodes(nodes); + nodes.add(name); + return ConfigPropertiesUtil.toSystemProperty(nodes); + } + + private void addSystemPropertyPathNodes(List parts) { + if (parent != null) { + parent.addSystemPropertyPathNodes(parts); + } + parts.add(node); + } +} diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java index 318be4b24eb8..248199e8b4d5 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java @@ -12,10 +12,11 @@ import io.opentelemetry.api.incubator.ExtendedOpenTelemetry; import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; +import java.util.ArrayList; import java.util.Arrays; import java.util.List; import java.util.Optional; -import java.util.stream.Collectors; +import java.util.function.BiFunction; import javax.annotation.Nullable; /** @@ -57,12 +58,8 @@ public static boolean getBoolean(String propertyName, boolean defaultValue) { * otherwise falls back to system properties and environment variables. */ public static Optional getBoolean(OpenTelemetry openTelemetry, String... propertyName) { - DeclarativeConfigProperties node = getDeclarativeConfigNode(openTelemetry, propertyName); - if (node != null) { - return Optional.ofNullable(node.getBoolean(leaf(propertyName))); - } - String strValue = getString(toSystemProperty(propertyName)); - return strValue == null ? Optional.empty() : Optional.of(Boolean.parseBoolean(strValue)); + return Optional.ofNullable( + getValue(openTelemetry, propertyName, DeclarativeConfigProperties::getBoolean)); } /** @@ -98,11 +95,25 @@ public static String getString(String propertyName) { * otherwise falls back to system properties and environment variables. */ public static Optional getString(OpenTelemetry openTelemetry, String... propertyName) { - DeclarativeConfigProperties node = getDeclarativeConfigNode(openTelemetry, propertyName); - if (node != null) { - return Optional.ofNullable(node.getString(leaf(propertyName))); + return Optional.ofNullable( + getValue(openTelemetry, propertyName, DeclarativeConfigProperties::getString)); + } + + private static T getValue( + OpenTelemetry openTelemetry, + String[] propertyName, + BiFunction getter) { + DeclarativeConfigProperties instrumentationConfig = + getConfigProvider(openTelemetry).getInstrumentationConfig(); + DeclarativeConfigProperties node = + instrumentationConfig == null + ? empty() + : instrumentationConfig.getStructured("java", empty()); + // last part is the leaf property + for (int i = 0; i < propertyName.length - 1; i++) { + node = node.getStructured(propertyName[i], empty()); } - return Optional.ofNullable(getString(toSystemProperty(propertyName))); + return getter.apply(node, propertyName[propertyName.length - 1]); } /** @@ -110,13 +121,11 @@ public static Optional getString(OpenTelemetry openTelemetry, String... * available, otherwise falls back to system properties and environment variables. */ public static List getList(OpenTelemetry openTelemetry, String... propertyName) { - DeclarativeConfigProperties node = getDeclarativeConfigNode(openTelemetry, propertyName); - if (node != null) { - return node.getScalarList(leaf(propertyName), String.class, emptyList()); - } - return Optional.ofNullable(getString(toSystemProperty(propertyName))) - .map(value -> filterBlanksAndNulls(value.split(","))) - .orElse(emptyList()); + return getValue( + openTelemetry, + propertyName, + (declarativeConfigProperties, name) -> + declarativeConfigProperties.getScalarList(name, String.class, emptyList())); } /** Returns true if the given OpenTelemetry instance supports Declarative Config. */ @@ -124,52 +133,27 @@ public static boolean isDeclarativeConfig(OpenTelemetry openTelemetry) { return supportsDeclarativeConfig && openTelemetry instanceof ExtendedOpenTelemetry; } - private static List filterBlanksAndNulls(String[] values) { - return Arrays.stream(values) - .map(String::trim) - .filter(s -> !s.isEmpty()) - .collect(Collectors.toList()); - } - - private static String leaf(String[] propertyName) { - return propertyName[propertyName.length - 1]; - } - - @Nullable - private static DeclarativeConfigProperties getDeclarativeConfigNode( - OpenTelemetry openTelemetry, String... propertyName) { + private static ConfigProvider getConfigProvider(OpenTelemetry openTelemetry) { if (isDeclarativeConfig(openTelemetry)) { ExtendedOpenTelemetry extendedOpenTelemetry = (ExtendedOpenTelemetry) openTelemetry; - ConfigProvider configProvider = extendedOpenTelemetry.getConfigProvider(); - return getConfigProperties(configProvider, propertyName); + return extendedOpenTelemetry.getConfigProvider(); } - return null; + return new SystemPropertiesConfigProvider(); } - /** Returns the DeclarativeConfigProperties node for the given property name parts. */ - public static DeclarativeConfigProperties getConfigProperties( - ConfigProvider configProvider, String[] propertyName) { - DeclarativeConfigProperties instrumentationConfig = configProvider.getInstrumentationConfig(); - if (instrumentationConfig == null) { - return empty(); - } - DeclarativeConfigProperties node = instrumentationConfig.getStructured("java", empty()); - // last part is the leaf property - for (int i = 0; i < propertyName.length - 1; i++) { - node = node.getStructured(propertyName[i], empty()); - } - return node; + public static String toSystemProperty(String[] nodes) { + return toSystemProperty(new ArrayList<>(Arrays.asList(nodes))); } - public static String toSystemProperty(String[] propertyName) { - for (int i = 0; i < propertyName.length; i++) { - String node = propertyName[i]; + public static String toSystemProperty(List nodes) { + for (int i = 0; i < nodes.size(); i++) { + String node = nodes.get(i); if (node.endsWith("/development")) { String prefix = node.contains("experimental") ? "" : "experimental."; - propertyName[i] = prefix + node.substring(0, node.length() - 12); + nodes.set(i, prefix + node.substring(0, node.length() - 12)); } } - return "otel.instrumentation." + String.join(".", propertyName).replace('_', '-'); + return "otel.instrumentation." + String.join(".", nodes).replace('_', '-'); } private ConfigPropertiesUtil() {} diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/SystemPropertiesConfigProvider.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/SystemPropertiesConfigProvider.java new file mode 100644 index 000000000000..9ac7a2dd7ffb --- /dev/null +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/SystemPropertiesConfigProvider.java @@ -0,0 +1,13 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.api.internal; + +class SystemPropertiesConfigProvider extends AbstractSystemPropertiesConfigProvider { + @Override + protected AbstractSystemPropertiesDeclarativeConfigProperties getProperties(String name) { + return new SystemPropertiesDeclarativeConfigProperties(name, null); + } +} diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/SystemPropertiesDeclarativeConfigProperties.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/SystemPropertiesDeclarativeConfigProperties.java new file mode 100644 index 000000000000..7ec1f7f1c2f3 --- /dev/null +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/SystemPropertiesDeclarativeConfigProperties.java @@ -0,0 +1,28 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.api.internal; + +import javax.annotation.Nullable; + +class SystemPropertiesDeclarativeConfigProperties + extends AbstractSystemPropertiesDeclarativeConfigProperties { + + SystemPropertiesDeclarativeConfigProperties( + String node, @Nullable SystemPropertiesDeclarativeConfigProperties parent) { + super(node, parent); + } + + @Nullable + @Override + public String getString(String name) { + return ConfigPropertiesUtil.getString(getSystemProperty(name)); + } + + @Override + protected AbstractSystemPropertiesDeclarativeConfigProperties newChild(String node) { + return new SystemPropertiesDeclarativeConfigProperties(node, this); + } +} diff --git a/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java b/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java index a206a73fe295..6df20c1647da 100644 --- a/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java +++ b/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java @@ -173,6 +173,7 @@ private static OpenTelemetryConfigurationModel model(Object value) { @Test void toSystemProperty() { + // todo test for prop that has both experimental and /development assertThat(ConfigPropertiesUtil.toSystemProperty(new String[] {"a_b", "c", "d"})) .isEqualTo("otel.instrumentation.a-b.c.d"); assertThat(ConfigPropertiesUtil.toSystemProperty(new String[] {"a_b/development", "c", "d"})) diff --git a/instrumentation/aws-sdk/aws-sdk-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v2_2/AwsSdkSingletons.java b/instrumentation/aws-sdk/aws-sdk-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v2_2/AwsSdkSingletons.java index da0391246112..8ec8139ab309 100644 --- a/instrumentation/aws-sdk/aws-sdk-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v2_2/AwsSdkSingletons.java +++ b/instrumentation/aws-sdk/aws-sdk-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v2_2/AwsSdkSingletons.java @@ -5,7 +5,6 @@ package io.opentelemetry.javaagent.instrumentation.awssdk.v2_2; -import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; import io.opentelemetry.instrumentation.api.internal.ConfigPropertiesUtil; import io.opentelemetry.instrumentation.awssdk.v2_2.AwsSdkTelemetry; @@ -37,11 +36,10 @@ protected boolean messagingReceiveInstrumentationEnabled() { @Override protected boolean getBoolean(String... name) { InstrumentationConfig instrumentationConfig = AgentInstrumentationConfig.get(); - ConfigProvider configProvider = instrumentationConfig.getConfigProvider(); - if (configProvider != null) { + if (instrumentationConfig.isDeclarative()) { // don't use to InstrumentationConfig, which would use a bridge back to declarative config - return ConfigPropertiesUtil.getConfigProperties(configProvider, name) - .getBoolean(name[name.length - 1], false); + return ConfigPropertiesUtil.getBoolean(instrumentationConfig.getOpenTelemetry(), name) + .orElse(false); } return instrumentationConfig.getBoolean(ConfigPropertiesUtil.toSystemProperty(name), false); diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/OpenTelemetryAutoConfiguration.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/OpenTelemetryAutoConfiguration.java index bbb40a59a2cb..7741017c9cc0 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/OpenTelemetryAutoConfiguration.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/OpenTelemetryAutoConfiguration.java @@ -131,8 +131,9 @@ public OpenTelemetry openTelemetry( } @Bean - public InstrumentationConfig instrumentationConfig(ConfigProperties properties) { - return new ConfigPropertiesBridge(properties); + public InstrumentationConfig instrumentationConfig( + ConfigProperties properties, OpenTelemetry openTelemetry) { + return new ConfigPropertiesBridge(properties, openTelemetry); } /** @@ -190,8 +191,8 @@ public ConfigProperties otelProperties(ConfigProvider configProvider) { @Bean public InstrumentationConfig instrumentationConfig( - ConfigProperties properties, ConfigProvider configProvider) { - return new ConfigPropertiesBridge(properties, configProvider); + ConfigProperties properties, OpenTelemetry openTelemetry, ConfigProvider configProvider) { + return new ConfigPropertiesBridge(properties, openTelemetry, configProvider); } @Bean @@ -231,8 +232,9 @@ public ConfigProperties otelProperties() { } @Bean - public InstrumentationConfig instrumentationConfig(ConfigProperties properties) { - return new ConfigPropertiesBridge(properties, null); + public InstrumentationConfig instrumentationConfig( + ConfigProperties properties, OpenTelemetry openTelemetry) { + return new ConfigPropertiesBridge(properties, openTelemetry); } @Configuration @@ -267,8 +269,9 @@ public ConfigProperties otelProperties(ApplicationContext applicationContext) { @ConditionalOnMissingBean({InstrumentationConfig.class}) static class FallbackInstrumentationConfig { @Bean - public InstrumentationConfig instrumentationConfig(ConfigProperties properties) { - return new ConfigPropertiesBridge(properties, null); + public InstrumentationConfig instrumentationConfig( + ConfigProperties properties, OpenTelemetry openTelemetry) { + return new ConfigPropertiesBridge(properties, openTelemetry); } } diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/properties/ConfigPropertiesBridge.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/properties/ConfigPropertiesBridge.java index dbabca731486..d28f7439a396 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/properties/ConfigPropertiesBridge.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/properties/ConfigPropertiesBridge.java @@ -8,6 +8,7 @@ import static io.opentelemetry.api.incubator.config.DeclarativeConfigProperties.empty; import static java.util.Objects.requireNonNull; +import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.api.incubator.config.InstrumentationConfigUtil; @@ -28,15 +29,19 @@ public final class ConfigPropertiesBridge implements InstrumentationConfig { private final ConfigProperties configProperties; + private final OpenTelemetry openTelemetry; @Nullable private final ConfigProvider configProvider; - public ConfigPropertiesBridge(ConfigProperties configProperties) { - this(configProperties, null); + public ConfigPropertiesBridge(ConfigProperties configProperties, OpenTelemetry openTelemetry) { + this(configProperties, openTelemetry, null); } public ConfigPropertiesBridge( - ConfigProperties configProperties, @Nullable ConfigProvider configProvider) { + ConfigProperties configProperties, + OpenTelemetry openTelemetry, + @Nullable ConfigProvider configProvider) { this.configProperties = configProperties; + this.openTelemetry = openTelemetry; this.configProvider = configProvider; } @@ -143,4 +148,9 @@ public DeclarativeConfigProperties getDeclarativeConfig(String node) { public ConfigProvider getConfigProvider() { return configProvider; } + + @Override + public OpenTelemetry getOpenTelemetry() { + return openTelemetry; + } } diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/scheduling/SchedulingInstrumentationAspectTest.java b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/scheduling/SchedulingInstrumentationAspectTest.java index 3306b280869c..2db00c0f582a 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/scheduling/SchedulingInstrumentationAspectTest.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/scheduling/SchedulingInstrumentationAspectTest.java @@ -58,7 +58,8 @@ void setup() { newAspect( testing.getOpenTelemetry(), new ConfigPropertiesBridge( - DefaultConfigProperties.createFromMap(Collections.emptyMap()))); + DefaultConfigProperties.createFromMap(Collections.emptyMap()), + OpenTelemetry.noop())); factory.addAspect(aspect); schedulingTester = factory.getProxy(); diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/scheduling/SchedulingInstrumentationAutoConfigurationTest.java b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/scheduling/SchedulingInstrumentationAutoConfigurationTest.java index 5b631daf1434..114fd3a91a64 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/scheduling/SchedulingInstrumentationAutoConfigurationTest.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/scheduling/SchedulingInstrumentationAutoConfigurationTest.java @@ -24,7 +24,8 @@ class SchedulingInstrumentationAutoConfigurationTest { InstrumentationConfig.class, () -> new ConfigPropertiesBridge( - DefaultConfigProperties.createFromMap(Collections.emptyMap()))) + DefaultConfigProperties.createFromMap(Collections.emptyMap()), + OpenTelemetry.noop())) .withConfiguration( AutoConfigurations.of(SpringSchedulingInstrumentationAutoConfiguration.class)); diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webflux/SpringWebfluxInstrumentationAutoConfigurationTest.java b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webflux/SpringWebfluxInstrumentationAutoConfigurationTest.java index df6273d4686c..edf362d06b5c 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webflux/SpringWebfluxInstrumentationAutoConfigurationTest.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webflux/SpringWebfluxInstrumentationAutoConfigurationTest.java @@ -25,7 +25,8 @@ class SpringWebfluxInstrumentationAutoConfigurationTest { InstrumentationConfig.class, () -> new ConfigPropertiesBridge( - DefaultConfigProperties.createFromMap(Collections.emptyMap()))) + DefaultConfigProperties.createFromMap(Collections.emptyMap()), + OpenTelemetry.noop())) .withConfiguration( AutoConfigurations.of(SpringWebfluxInstrumentationAutoConfiguration.class)); diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webflux/WebClientBeanPostProcessorTest.java b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webflux/WebClientBeanPostProcessorTest.java index 4c25da12a112..2ae53eb57eda 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webflux/WebClientBeanPostProcessorTest.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webflux/WebClientBeanPostProcessorTest.java @@ -26,7 +26,8 @@ class WebClientBeanPostProcessorTest { beanFactory.registerSingleton("openTelemetry", OpenTelemetry.noop()); beanFactory.registerSingleton( "configProperties", - new ConfigPropertiesBridge(DefaultConfigProperties.createFromMap(Collections.emptyMap()))); + new ConfigPropertiesBridge( + DefaultConfigProperties.createFromMap(Collections.emptyMap()), OpenTelemetry.noop())); } @Test diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webmvc/SpringWebMvcInstrumentation5AutoConfigurationTest.java b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webmvc/SpringWebMvcInstrumentation5AutoConfigurationTest.java index 3c90a46fdfdc..bbc09d27b283 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webmvc/SpringWebMvcInstrumentation5AutoConfigurationTest.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webmvc/SpringWebMvcInstrumentation5AutoConfigurationTest.java @@ -28,7 +28,8 @@ class SpringWebMvcInstrumentation5AutoConfigurationTest { InstrumentationConfig.class, () -> new ConfigPropertiesBridge( - DefaultConfigProperties.createFromMap(Collections.emptyMap()))) + DefaultConfigProperties.createFromMap(Collections.emptyMap()), + OpenTelemetry.noop())) .withConfiguration( AutoConfigurations.of(SpringWebMvc5InstrumentationAutoConfiguration.class)); diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/testSpring3/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/web/RestClientInstrumentationAutoConfigurationTest.java b/instrumentation/spring/spring-boot-autoconfigure/src/testSpring3/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/web/RestClientInstrumentationAutoConfigurationTest.java index 3e16f15b23ef..7e9def12c344 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/testSpring3/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/web/RestClientInstrumentationAutoConfigurationTest.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/testSpring3/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/web/RestClientInstrumentationAutoConfigurationTest.java @@ -26,7 +26,8 @@ class RestClientInstrumentationAutoConfigurationTest { InstrumentationConfig.class, () -> new ConfigPropertiesBridge( - DefaultConfigProperties.createFromMap(Collections.emptyMap()))) + DefaultConfigProperties.createFromMap(Collections.emptyMap()), + OpenTelemetry.noop())) .withBean(RestClient.class, RestClient::create) .withConfiguration( AutoConfigurations.of(RestClientInstrumentationAutoConfiguration.class)); diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/testSpring3/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webmvc/SpringWebMvcInstrumentation6AutoConfigurationTest.java b/instrumentation/spring/spring-boot-autoconfigure/src/testSpring3/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webmvc/SpringWebMvcInstrumentation6AutoConfigurationTest.java index a96d6abc2f4e..dc17ba1fd7ef 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/testSpring3/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webmvc/SpringWebMvcInstrumentation6AutoConfigurationTest.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/testSpring3/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webmvc/SpringWebMvcInstrumentation6AutoConfigurationTest.java @@ -28,7 +28,8 @@ class SpringWebMvcInstrumentation6AutoConfigurationTest { InstrumentationConfig.class, () -> new ConfigPropertiesBridge( - DefaultConfigProperties.createFromMap(Collections.emptyMap()))) + DefaultConfigProperties.createFromMap(Collections.emptyMap()), + OpenTelemetry.noop())) .withConfiguration( AutoConfigurations.of(SpringWebMvc6InstrumentationAutoConfiguration.class)); diff --git a/instrumentation/spring/spring-boot-autoconfigure/testing/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/AbstractJdbcInstrumentationAutoConfigurationTest.java b/instrumentation/spring/spring-boot-autoconfigure/testing/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/AbstractJdbcInstrumentationAutoConfigurationTest.java index 8c7b05f14e96..b0a84b75b0cc 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/testing/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/AbstractJdbcInstrumentationAutoConfigurationTest.java +++ b/instrumentation/spring/spring-boot-autoconfigure/testing/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/AbstractJdbcInstrumentationAutoConfigurationTest.java @@ -34,7 +34,9 @@ public abstract class AbstractJdbcInstrumentationAutoConfigurationTest { new ApplicationContextRunner() .withBean( InstrumentationConfig.class, - () -> new ConfigPropertiesBridge(DefaultConfigProperties.createFromMap(emptyMap()))) + () -> + new ConfigPropertiesBridge( + DefaultConfigProperties.createFromMap(emptyMap()), OpenTelemetry.noop())) .withConfiguration(autoConfigurations()) .withBean("openTelemetry", OpenTelemetry.class, testing()::getOpenTelemetry); diff --git a/instrumentation/spring/spring-boot-autoconfigure/testing/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/AbstractKafkaInstrumentationAutoConfigurationTest.java b/instrumentation/spring/spring-boot-autoconfigure/testing/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/AbstractKafkaInstrumentationAutoConfigurationTest.java index c4e0b40a127c..4cd81572c034 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/testing/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/AbstractKafkaInstrumentationAutoConfigurationTest.java +++ b/instrumentation/spring/spring-boot-autoconfigure/testing/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/AbstractKafkaInstrumentationAutoConfigurationTest.java @@ -27,7 +27,9 @@ public abstract class AbstractKafkaInstrumentationAutoConfigurationTest { new ApplicationContextRunner() .withBean( InstrumentationConfig.class, - () -> new ConfigPropertiesBridge(DefaultConfigProperties.createFromMap(emptyMap()))) + () -> + new ConfigPropertiesBridge( + DefaultConfigProperties.createFromMap(emptyMap()), OpenTelemetry.noop())) .withConfiguration(autoConfigurations()) .withBean("openTelemetry", OpenTelemetry.class, OpenTelemetry::noop); diff --git a/instrumentation/spring/spring-boot-autoconfigure/testing/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/AbstractR2DbcInstrumentationAutoConfigurationTest.java b/instrumentation/spring/spring-boot-autoconfigure/testing/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/AbstractR2DbcInstrumentationAutoConfigurationTest.java index a556d7e1f68c..089e625cb9aa 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/testing/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/AbstractR2DbcInstrumentationAutoConfigurationTest.java +++ b/instrumentation/spring/spring-boot-autoconfigure/testing/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/AbstractR2DbcInstrumentationAutoConfigurationTest.java @@ -31,7 +31,8 @@ public abstract class AbstractR2DbcInstrumentationAutoConfigurationTest { InstrumentationConfig.class, () -> new ConfigPropertiesBridge( - DefaultConfigProperties.createFromMap(Collections.emptyMap()))) + DefaultConfigProperties.createFromMap(Collections.emptyMap()), + OpenTelemetry.noop())) .withConfiguration(autoConfigurations()) .withBean("openTelemetry", OpenTelemetry.class, testing()::getOpenTelemetry); diff --git a/instrumentation/spring/spring-boot-autoconfigure/testing/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/AbstractSpringWebInstrumentationAutoConfigurationTest.java b/instrumentation/spring/spring-boot-autoconfigure/testing/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/AbstractSpringWebInstrumentationAutoConfigurationTest.java index 4b9a339d38b7..a719f2e16fc7 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/testing/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/AbstractSpringWebInstrumentationAutoConfigurationTest.java +++ b/instrumentation/spring/spring-boot-autoconfigure/testing/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/AbstractSpringWebInstrumentationAutoConfigurationTest.java @@ -29,7 +29,8 @@ public abstract class AbstractSpringWebInstrumentationAutoConfigurationTest { InstrumentationConfig.class, () -> new ConfigPropertiesBridge( - DefaultConfigProperties.createFromMap(Collections.emptyMap()))) + DefaultConfigProperties.createFromMap(Collections.emptyMap()), + OpenTelemetry.noop())) .withBean(RestTemplate.class, RestTemplate::new) .withConfiguration(autoConfigurations()); diff --git a/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/bootstrap/internal/EmptyInstrumentationConfig.java b/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/bootstrap/internal/EmptyInstrumentationConfig.java index 56cd43580c17..0ead2701b162 100644 --- a/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/bootstrap/internal/EmptyInstrumentationConfig.java +++ b/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/bootstrap/internal/EmptyInstrumentationConfig.java @@ -5,6 +5,7 @@ package io.opentelemetry.javaagent.bootstrap.internal; +import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; @@ -77,4 +78,9 @@ public DeclarativeConfigProperties getDeclarativeConfig(String node) { public ConfigProvider getConfigProvider() { return null; } + + @Override + public OpenTelemetry getOpenTelemetry() { + return OpenTelemetry.noop(); + } } diff --git a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/AgentInstaller.java b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/AgentInstaller.java index 769908d7f2a8..3dc4068632d4 100644 --- a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/AgentInstaller.java +++ b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/AgentInstaller.java @@ -169,7 +169,9 @@ private static void installBytebuddyAgent( ConfigProperties sdkConfig = AutoConfigureUtil.getConfig(autoConfiguredSdk); AgentInstrumentationConfig.internalInitializeConfig( new ConfigPropertiesBridge( - sdkConfig, AutoConfigureUtil.getConfigProvider(autoConfiguredSdk))); + sdkConfig, + AutoConfigureUtil.getConfigProvider(autoConfiguredSdk), + autoConfiguredSdk.getOpenTelemetrySdk())); copyNecessaryConfigToSystemProperties(sdkConfig); setBootstrapPackages(sdkConfig, extensionClassLoader); diff --git a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/ConfigPropertiesBridge.java b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/ConfigPropertiesBridge.java index 5c7fe70d9f1d..32492bd11be9 100644 --- a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/ConfigPropertiesBridge.java +++ b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/ConfigPropertiesBridge.java @@ -8,6 +8,7 @@ import static io.opentelemetry.api.incubator.config.DeclarativeConfigProperties.empty; import static java.util.Objects.requireNonNull; +import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.api.incubator.config.InstrumentationConfigUtil; @@ -23,11 +24,15 @@ public final class ConfigPropertiesBridge implements InstrumentationConfig { private final ConfigProperties configProperties; @Nullable private final ConfigProvider configProvider; + private final OpenTelemetry openTelemetry; public ConfigPropertiesBridge( - ConfigProperties configProperties, @Nullable ConfigProvider configProvider) { + ConfigProperties configProperties, + @Nullable ConfigProvider configProvider, + OpenTelemetry openTelemetry) { this.configProperties = configProperties; this.configProvider = configProvider; + this.openTelemetry = openTelemetry; } @Nullable @@ -133,4 +138,9 @@ public DeclarativeConfigProperties getDeclarativeConfig(String node) { public ConfigProvider getConfigProvider() { return configProvider; } + + @Override + public OpenTelemetry getOpenTelemetry() { + return openTelemetry; + } } diff --git a/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/config/ConfigPropertiesBridgeTest.java b/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/config/ConfigPropertiesBridgeTest.java index 6adba8deacfd..363fcad0f813 100644 --- a/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/config/ConfigPropertiesBridgeTest.java +++ b/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/config/ConfigPropertiesBridgeTest.java @@ -9,6 +9,7 @@ import static java.util.Collections.emptyMap; import static org.assertj.core.api.Assertions.assertThat; +import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.instrumentation.api.incubator.config.internal.CommonConfig; import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; @@ -45,10 +46,16 @@ public static Stream emptyGeneralConfig() { DefaultConfigProperties configProperties = DefaultConfigProperties.createFromMap(emptyMap()); return Stream.of( - Arguments.of("config properties", new ConfigPropertiesBridge(configProperties, null)), + Arguments.of( + "config properties", + new ConfigPropertiesBridge( + configProperties, null, OpenTelemetry.noop())), Arguments.of( "declarative config", - new ConfigPropertiesBridge(configProperties, SdkConfigProvider.create(emptyModel)))); + new ConfigPropertiesBridge( + configProperties, + SdkConfigProvider.create(emptyModel), + OpenTelemetry.noop()))); } @ParameterizedTest(name = "{0}") @@ -95,10 +102,16 @@ public static Stream fullGeneralConfig() { DefaultConfigProperties.createFromMap(getProperties()); return Stream.of( - Arguments.of("config properties", new ConfigPropertiesBridge(configProperties, null)), + Arguments.of( + "config properties", + new ConfigPropertiesBridge( + configProperties, null, OpenTelemetry.noop())), Arguments.of( "declarative config", - new ConfigPropertiesBridge(configProperties, SdkConfigProvider.create(emptyModel)))); + new ConfigPropertiesBridge( + configProperties, + SdkConfigProvider.create(emptyModel), + OpenTelemetry.noop()))); } private static Map getProperties() { From 42ab6c0809813b2bab3d3df179ccc67f9b9be25e Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Fri, 12 Dec 2025 13:22:39 +0100 Subject: [PATCH 56/79] add SystemPropertiesDeclarativeConfigProperties --- .../instrumentation/api/internal/ConfigPropertiesUtilTest.java | 1 - 1 file changed, 1 deletion(-) diff --git a/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java b/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java index 6df20c1647da..a206a73fe295 100644 --- a/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java +++ b/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java @@ -173,7 +173,6 @@ private static OpenTelemetryConfigurationModel model(Object value) { @Test void toSystemProperty() { - // todo test for prop that has both experimental and /development assertThat(ConfigPropertiesUtil.toSystemProperty(new String[] {"a_b", "c", "d"})) .isEqualTo("otel.instrumentation.a-b.c.d"); assertThat(ConfigPropertiesUtil.toSystemProperty(new String[] {"a_b/development", "c", "d"})) From 0e1343f51f6ee816dc0c9a0867771d1cea2da540 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Fri, 12 Dec 2025 14:01:58 +0100 Subject: [PATCH 57/79] add SystemPropertiesDeclarativeConfigProperties --- ...bstractSystemPropertiesConfigProvider.java | 1 - .../api/internal/ConfigPropertiesUtil.java | 7 +++- .../SystemPropertiesConfigProvider.java | 13 ------- ...PropertiesDeclarativeConfigProperties.java | 36 +++++++++++++++++++ 4 files changed, 42 insertions(+), 15 deletions(-) delete mode 100644 instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/SystemPropertiesConfigProvider.java create mode 100644 javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/ConfigPropertiesDeclarativeConfigProperties.java diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/AbstractSystemPropertiesConfigProvider.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/AbstractSystemPropertiesConfigProvider.java index 3618d3a731f8..a420b9dd40da 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/AbstractSystemPropertiesConfigProvider.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/AbstractSystemPropertiesConfigProvider.java @@ -16,7 +16,6 @@ * This class is internal and is hence not for public use. Its APIs are unstable and can change at * any time. */ -// todo also an implementation of ConfigProvider that reads from ConfigProperties public abstract class AbstractSystemPropertiesConfigProvider implements ConfigProvider { @Nullable @Override diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java index 248199e8b4d5..1eb962e4d29f 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java @@ -138,7 +138,12 @@ private static ConfigProvider getConfigProvider(OpenTelemetry openTelemetry) { ExtendedOpenTelemetry extendedOpenTelemetry = (ExtendedOpenTelemetry) openTelemetry; return extendedOpenTelemetry.getConfigProvider(); } - return new SystemPropertiesConfigProvider(); + return new AbstractSystemPropertiesConfigProvider() { + @Override + protected AbstractSystemPropertiesDeclarativeConfigProperties getProperties(String name) { + return new SystemPropertiesDeclarativeConfigProperties(name, null); + } + }; } public static String toSystemProperty(String[] nodes) { diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/SystemPropertiesConfigProvider.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/SystemPropertiesConfigProvider.java deleted file mode 100644 index 9ac7a2dd7ffb..000000000000 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/SystemPropertiesConfigProvider.java +++ /dev/null @@ -1,13 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.instrumentation.api.internal; - -class SystemPropertiesConfigProvider extends AbstractSystemPropertiesConfigProvider { - @Override - protected AbstractSystemPropertiesDeclarativeConfigProperties getProperties(String name) { - return new SystemPropertiesDeclarativeConfigProperties(name, null); - } -} diff --git a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/ConfigPropertiesDeclarativeConfigProperties.java b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/ConfigPropertiesDeclarativeConfigProperties.java new file mode 100644 index 000000000000..df67db577494 --- /dev/null +++ b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/ConfigPropertiesDeclarativeConfigProperties.java @@ -0,0 +1,36 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.tooling.config; + +import io.opentelemetry.instrumentation.api.internal.AbstractSystemPropertiesDeclarativeConfigProperties; +import io.opentelemetry.instrumentation.api.internal.ConfigPropertiesUtil; +import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; +import javax.annotation.Nullable; + +public class ConfigPropertiesDeclarativeConfigProperties + extends AbstractSystemPropertiesDeclarativeConfigProperties { + + private final ConfigProperties configProperties; + + public ConfigPropertiesDeclarativeConfigProperties( + ConfigProperties configProperties, + String node, + @Nullable ConfigPropertiesDeclarativeConfigProperties parent) { + super(node, parent); + this.configProperties = configProperties; + } + + @Nullable + @Override + public String getString(String name) { + return configProperties.getString(name); + } + + @Override + protected AbstractSystemPropertiesDeclarativeConfigProperties newChild(String node) { + return new ConfigPropertiesDeclarativeConfigProperties(configProperties, node, this); + } +} From 4ec69808b83e4c6335c5510dc732b25716a37970 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Fri, 12 Dec 2025 15:05:21 +0100 Subject: [PATCH 58/79] add to InstrumentationConfig --- ...PropertiesDeclarativeConfigProperties.java | 17 +++++-- .../internal/InstrumentationConfig.java | 9 +--- .../api/internal/ConfigPropertiesUtil.java | 2 +- .../awssdk/v2_2/AwsSdkSingletons.java | 15 ++----- .../v2_2/autoconfigure/AwsSdkSingletons.java | 5 ++- .../AbstractAwsSdkTelemetryFactory.java | 33 +++++++++++--- .../OpenTelemetryAutoConfiguration.java | 45 ++++++++++++++----- .../properties/ConfigPropertiesBridge.java | 19 +------- .../SchedulingInstrumentationAspectTest.java | 3 +- ...gInstrumentationAutoConfigurationTest.java | 3 +- ...xInstrumentationAutoConfigurationTest.java | 3 +- .../WebClientBeanPostProcessorTest.java | 3 +- ...Instrumentation5AutoConfigurationTest.java | 3 +- ...tInstrumentationAutoConfigurationTest.java | 3 +- ...Instrumentation6AutoConfigurationTest.java | 3 +- ...cInstrumentationAutoConfigurationTest.java | 3 +- ...aInstrumentationAutoConfigurationTest.java | 3 +- ...cInstrumentationAutoConfigurationTest.java | 3 +- ...bInstrumentationAutoConfigurationTest.java | 3 +- .../javaagent/tooling/AgentInstaller.java | 22 +++++++-- .../config/ConfigPropertiesBridge.java | 21 +++------ .../config/ConfigPropertiesBridgeTest.java | 14 ++---- 22 files changed, 137 insertions(+), 98 deletions(-) rename {javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config => declarative-config-bridge/src/main/java/io/opentelemetry/instrumentation/config/bridge}/ConfigPropertiesDeclarativeConfigProperties.java (61%) diff --git a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/ConfigPropertiesDeclarativeConfigProperties.java b/declarative-config-bridge/src/main/java/io/opentelemetry/instrumentation/config/bridge/ConfigPropertiesDeclarativeConfigProperties.java similarity index 61% rename from javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/ConfigPropertiesDeclarativeConfigProperties.java rename to declarative-config-bridge/src/main/java/io/opentelemetry/instrumentation/config/bridge/ConfigPropertiesDeclarativeConfigProperties.java index df67db577494..65c4bbbed02d 100644 --- a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/ConfigPropertiesDeclarativeConfigProperties.java +++ b/declarative-config-bridge/src/main/java/io/opentelemetry/instrumentation/config/bridge/ConfigPropertiesDeclarativeConfigProperties.java @@ -3,10 +3,12 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.tooling.config; +package io.opentelemetry.instrumentation.config.bridge; +import io.opentelemetry.api.incubator.config.ConfigProvider; + +import io.opentelemetry.instrumentation.api.internal.AbstractSystemPropertiesConfigProvider; import io.opentelemetry.instrumentation.api.internal.AbstractSystemPropertiesDeclarativeConfigProperties; -import io.opentelemetry.instrumentation.api.internal.ConfigPropertiesUtil; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import javax.annotation.Nullable; @@ -15,7 +17,7 @@ public class ConfigPropertiesDeclarativeConfigProperties private final ConfigProperties configProperties; - public ConfigPropertiesDeclarativeConfigProperties( + private ConfigPropertiesDeclarativeConfigProperties( ConfigProperties configProperties, String node, @Nullable ConfigPropertiesDeclarativeConfigProperties parent) { @@ -23,6 +25,15 @@ public ConfigPropertiesDeclarativeConfigProperties( this.configProperties = configProperties; } + public static ConfigProvider create(ConfigProperties configProperties) { + return new AbstractSystemPropertiesConfigProvider() { + @Override + protected AbstractSystemPropertiesDeclarativeConfigProperties getProperties(String name) { + return new ConfigPropertiesDeclarativeConfigProperties(configProperties, name, null); + } + }; + } + @Nullable @Override public String getString(String name) { diff --git a/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/config/internal/InstrumentationConfig.java b/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/config/internal/InstrumentationConfig.java index 1a25eac44a3f..13d5f4e543bf 100644 --- a/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/config/internal/InstrumentationConfig.java +++ b/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/config/internal/InstrumentationConfig.java @@ -7,7 +7,6 @@ import static java.util.Collections.emptyList; -import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import java.time.Duration; @@ -131,12 +130,8 @@ default List getList(String name) { DeclarativeConfigProperties getDeclarativeConfig(String node); /** - * Returns the {@link ConfigProvider} if declarative configuration is used. - * - * @return the {@link ConfigProvider} or {@code null} if declarative configuration is not used + * @return the {@link ConfigProvider}, which is a bridge to ConfigProperties if declarative + * configuration is not used */ - @Nullable ConfigProvider getConfigProvider(); - - OpenTelemetry getOpenTelemetry(); } diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java index 1eb962e4d29f..1e8333f63f6a 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java @@ -133,7 +133,7 @@ public static boolean isDeclarativeConfig(OpenTelemetry openTelemetry) { return supportsDeclarativeConfig && openTelemetry instanceof ExtendedOpenTelemetry; } - private static ConfigProvider getConfigProvider(OpenTelemetry openTelemetry) { + public static ConfigProvider getConfigProvider(OpenTelemetry openTelemetry) { if (isDeclarativeConfig(openTelemetry)) { ExtendedOpenTelemetry extendedOpenTelemetry = (ExtendedOpenTelemetry) openTelemetry; return extendedOpenTelemetry.getConfigProvider(); diff --git a/instrumentation/aws-sdk/aws-sdk-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v2_2/AwsSdkSingletons.java b/instrumentation/aws-sdk/aws-sdk-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v2_2/AwsSdkSingletons.java index 8ec8139ab309..71515697275e 100644 --- a/instrumentation/aws-sdk/aws-sdk-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v2_2/AwsSdkSingletons.java +++ b/instrumentation/aws-sdk/aws-sdk-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v2_2/AwsSdkSingletons.java @@ -5,8 +5,7 @@ package io.opentelemetry.javaagent.instrumentation.awssdk.v2_2; -import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; -import io.opentelemetry.instrumentation.api.internal.ConfigPropertiesUtil; +import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.instrumentation.awssdk.v2_2.AwsSdkTelemetry; import io.opentelemetry.instrumentation.awssdk.v2_2.internal.AbstractAwsSdkTelemetryFactory; import io.opentelemetry.javaagent.bootstrap.internal.AgentInstrumentationConfig; @@ -22,7 +21,6 @@ public static AwsSdkTelemetry telemetry() { } private static class AwsSdkTelemetryFactory extends AbstractAwsSdkTelemetryFactory { - @Override protected List getCapturedHeaders() { return ExperimentalConfig.get().getMessagingHeaders(); @@ -34,15 +32,8 @@ protected boolean messagingReceiveInstrumentationEnabled() { } @Override - protected boolean getBoolean(String... name) { - InstrumentationConfig instrumentationConfig = AgentInstrumentationConfig.get(); - if (instrumentationConfig.isDeclarative()) { - // don't use to InstrumentationConfig, which would use a bridge back to declarative config - return ConfigPropertiesUtil.getBoolean(instrumentationConfig.getOpenTelemetry(), name) - .orElse(false); - } - - return instrumentationConfig.getBoolean(ConfigPropertiesUtil.toSystemProperty(name), false); + protected ConfigProvider getConfigProvider() { + return AgentInstrumentationConfig.get().getConfigProvider(); } } diff --git a/instrumentation/aws-sdk/aws-sdk-2.2/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/autoconfigure/AwsSdkSingletons.java b/instrumentation/aws-sdk/aws-sdk-2.2/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/autoconfigure/AwsSdkSingletons.java index e2f4528a23ca..3c7632e16f6b 100644 --- a/instrumentation/aws-sdk/aws-sdk-2.2/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/autoconfigure/AwsSdkSingletons.java +++ b/instrumentation/aws-sdk/aws-sdk-2.2/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/autoconfigure/AwsSdkSingletons.java @@ -6,6 +6,7 @@ package io.opentelemetry.instrumentation.awssdk.v2_2.autoconfigure; import io.opentelemetry.api.GlobalOpenTelemetry; +import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.instrumentation.api.internal.ConfigPropertiesUtil; import io.opentelemetry.instrumentation.awssdk.v2_2.AwsSdkTelemetry; import io.opentelemetry.instrumentation.awssdk.v2_2.internal.AbstractAwsSdkTelemetryFactory; @@ -35,8 +36,8 @@ protected boolean messagingReceiveInstrumentationEnabled() { } @Override - protected boolean getBoolean(String... name) { - return ConfigPropertiesUtil.getBoolean(GlobalOpenTelemetry.get(), name).orElse(false); + protected ConfigProvider getConfigProvider() { + return ConfigPropertiesUtil.getConfigProvider(GlobalOpenTelemetry.get()); } } diff --git a/instrumentation/aws-sdk/aws-sdk-2.2/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/internal/AbstractAwsSdkTelemetryFactory.java b/instrumentation/aws-sdk/aws-sdk-2.2/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/internal/AbstractAwsSdkTelemetryFactory.java index 134680788b5c..2f5643661c2f 100644 --- a/instrumentation/aws-sdk/aws-sdk-2.2/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/internal/AbstractAwsSdkTelemetryFactory.java +++ b/instrumentation/aws-sdk/aws-sdk-2.2/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/internal/AbstractAwsSdkTelemetryFactory.java @@ -6,8 +6,11 @@ package io.opentelemetry.instrumentation.awssdk.v2_2.internal; import io.opentelemetry.api.GlobalOpenTelemetry; +import io.opentelemetry.api.incubator.config.ConfigProvider; +import io.opentelemetry.api.incubator.config.InstrumentationConfigUtil; import io.opentelemetry.instrumentation.awssdk.v2_2.AwsSdkTelemetry; import java.util.List; +import java.util.Optional; /** * This class is internal and is hence not for public use. Its APIs are unstable and can change at @@ -17,24 +20,44 @@ public abstract class AbstractAwsSdkTelemetryFactory { protected abstract List getCapturedHeaders(); private boolean captureExperimentalSpanAttributes() { - return getBoolean("aws_sdk", "span_attributes/development"); + return Optional.ofNullable( + InstrumentationConfigUtil.getOrNull( + getConfigProvider(), + config -> config.getBoolean("span_attributes/development"), + "aws_sdk")) + .orElse(false); } protected abstract boolean messagingReceiveInstrumentationEnabled(); private boolean useMessagingPropagator() { - return getBoolean("aws_sdk", "use_propagator_for_messaging/development"); + return Optional.ofNullable( + InstrumentationConfigUtil.getOrNull( + getConfigProvider(), + config -> config.getBoolean("use_propagator_for_messaging/development"), + "aws_sdk")) + .orElse(false); } private boolean recordIndividualHttpError() { - return getBoolean("aws_sdk", "record_individual_http_error/development"); + return Optional.ofNullable( + InstrumentationConfigUtil.getOrNull( + getConfigProvider(), + config -> config.getBoolean("record_individual_http_error/development"), + "aws_sdk")) + .orElse(false); } private boolean genaiCaptureMessageContent() { - return getBoolean("genai", "capture_message_content"); + return Optional.ofNullable( + InstrumentationConfigUtil.getOrNull( + getConfigProvider(), + config -> config.getBoolean("capture_message_content"), + "genai")) + .orElse(false); } - protected abstract boolean getBoolean(String... name); + protected abstract ConfigProvider getConfigProvider(); public AwsSdkTelemetry telemetry() { return AwsSdkTelemetry.builder(GlobalOpenTelemetry.get()) diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/OpenTelemetryAutoConfiguration.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/OpenTelemetryAutoConfiguration.java index 7741017c9cc0..7e6af32fdb9c 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/OpenTelemetryAutoConfiguration.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/OpenTelemetryAutoConfiguration.java @@ -13,6 +13,7 @@ import io.opentelemetry.common.ComponentLoader; import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; import io.opentelemetry.instrumentation.api.internal.EmbeddedInstrumentationProperties; +import io.opentelemetry.instrumentation.config.bridge.ConfigPropertiesDeclarativeConfigProperties; import io.opentelemetry.instrumentation.config.bridge.DeclarativeConfigPropertiesBridgeBuilder; import io.opentelemetry.instrumentation.spring.autoconfigure.internal.DeclarativeConfigDisabled; import io.opentelemetry.instrumentation.spring.autoconfigure.internal.DeclarativeConfigEnabled; @@ -130,12 +131,6 @@ public OpenTelemetry openTelemetry( return autoConfiguredOpenTelemetrySdk.getOpenTelemetrySdk(); } - @Bean - public InstrumentationConfig instrumentationConfig( - ConfigProperties properties, OpenTelemetry openTelemetry) { - return new ConfigPropertiesBridge(properties, openTelemetry); - } - /** * Expose the {@link ConfigProperties} bean for use in other auto-configurations. * @@ -149,6 +144,17 @@ public ConfigProperties otelProperties( AutoConfiguredOpenTelemetrySdk autoConfiguredOpenTelemetrySdk) { return requireNonNull(AutoConfigureUtil.getConfig(autoConfiguredOpenTelemetrySdk)); } + + @Bean + public ConfigProvider configProvider(ConfigProperties properties) { + return ConfigPropertiesDeclarativeConfigProperties.create(properties); + } + + @Bean + public InstrumentationConfig instrumentationConfig( + ConfigProperties properties, ConfigProvider configProvider) { + return new ConfigPropertiesBridge(properties, configProvider); + } } @Configuration @@ -191,8 +197,8 @@ public ConfigProperties otelProperties(ConfigProvider configProvider) { @Bean public InstrumentationConfig instrumentationConfig( - ConfigProperties properties, OpenTelemetry openTelemetry, ConfigProvider configProvider) { - return new ConfigPropertiesBridge(properties, openTelemetry, configProvider); + ConfigProperties properties, ConfigProvider configProvider) { + return new ConfigPropertiesBridge(properties, configProvider); } @Bean @@ -231,10 +237,15 @@ public ConfigProperties otelProperties() { return DefaultConfigProperties.createFromMap(Collections.emptyMap()); } + @Bean + public ConfigProvider configProvider() { + return ConfigProvider.noop(); + } + @Bean public InstrumentationConfig instrumentationConfig( - ConfigProperties properties, OpenTelemetry openTelemetry) { - return new ConfigPropertiesBridge(properties, openTelemetry); + ConfigProperties properties, ConfigProvider configProvider) { + return new ConfigPropertiesBridge(properties, configProvider); } @Configuration @@ -264,14 +275,24 @@ public ConfigProperties otelProperties(ApplicationContext applicationContext) { } } + @Configuration + @ConditionalOnBean(OpenTelemetry.class) + @ConditionalOnMissingBean({ConfigProvider.class}) + static class FallbackConfigProvider { + @Bean + public ConfigProvider configProvider() { + return ConfigProvider.noop(); + } + } + @Configuration @ConditionalOnBean(OpenTelemetry.class) @ConditionalOnMissingBean({InstrumentationConfig.class}) static class FallbackInstrumentationConfig { @Bean public InstrumentationConfig instrumentationConfig( - ConfigProperties properties, OpenTelemetry openTelemetry) { - return new ConfigPropertiesBridge(properties, openTelemetry); + ConfigProperties properties, ConfigProvider configProvider) { + return new ConfigPropertiesBridge(properties, configProvider); } } diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/properties/ConfigPropertiesBridge.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/properties/ConfigPropertiesBridge.java index d28f7439a396..25cb2da45b1b 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/properties/ConfigPropertiesBridge.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/properties/ConfigPropertiesBridge.java @@ -8,7 +8,6 @@ import static io.opentelemetry.api.incubator.config.DeclarativeConfigProperties.empty; import static java.util.Objects.requireNonNull; -import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.api.incubator.config.InstrumentationConfigUtil; @@ -29,19 +28,10 @@ public final class ConfigPropertiesBridge implements InstrumentationConfig { private final ConfigProperties configProperties; - private final OpenTelemetry openTelemetry; - @Nullable private final ConfigProvider configProvider; + private final ConfigProvider configProvider; - public ConfigPropertiesBridge(ConfigProperties configProperties, OpenTelemetry openTelemetry) { - this(configProperties, openTelemetry, null); - } - - public ConfigPropertiesBridge( - ConfigProperties configProperties, - OpenTelemetry openTelemetry, - @Nullable ConfigProvider configProvider) { + public ConfigPropertiesBridge(ConfigProperties configProperties, ConfigProvider configProvider) { this.configProperties = configProperties; - this.openTelemetry = openTelemetry; this.configProvider = configProvider; } @@ -148,9 +138,4 @@ public DeclarativeConfigProperties getDeclarativeConfig(String node) { public ConfigProvider getConfigProvider() { return configProvider; } - - @Override - public OpenTelemetry getOpenTelemetry() { - return openTelemetry; - } } diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/scheduling/SchedulingInstrumentationAspectTest.java b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/scheduling/SchedulingInstrumentationAspectTest.java index 2db00c0f582a..28151745ebf4 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/scheduling/SchedulingInstrumentationAspectTest.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/scheduling/SchedulingInstrumentationAspectTest.java @@ -9,6 +9,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy; import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.Tracer; import io.opentelemetry.context.Context; @@ -59,7 +60,7 @@ void setup() { testing.getOpenTelemetry(), new ConfigPropertiesBridge( DefaultConfigProperties.createFromMap(Collections.emptyMap()), - OpenTelemetry.noop())); + ConfigProvider.noop())); factory.addAspect(aspect); schedulingTester = factory.getProxy(); diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/scheduling/SchedulingInstrumentationAutoConfigurationTest.java b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/scheduling/SchedulingInstrumentationAutoConfigurationTest.java index 114fd3a91a64..caa10eeadcc0 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/scheduling/SchedulingInstrumentationAutoConfigurationTest.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/scheduling/SchedulingInstrumentationAutoConfigurationTest.java @@ -8,6 +8,7 @@ import static org.assertj.core.api.Assertions.assertThat; import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; import io.opentelemetry.instrumentation.spring.autoconfigure.internal.properties.ConfigPropertiesBridge; import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; @@ -25,7 +26,7 @@ class SchedulingInstrumentationAutoConfigurationTest { () -> new ConfigPropertiesBridge( DefaultConfigProperties.createFromMap(Collections.emptyMap()), - OpenTelemetry.noop())) + ConfigProvider.noop())) .withConfiguration( AutoConfigurations.of(SpringSchedulingInstrumentationAutoConfiguration.class)); diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webflux/SpringWebfluxInstrumentationAutoConfigurationTest.java b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webflux/SpringWebfluxInstrumentationAutoConfigurationTest.java index edf362d06b5c..7e5585fdf151 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webflux/SpringWebfluxInstrumentationAutoConfigurationTest.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webflux/SpringWebfluxInstrumentationAutoConfigurationTest.java @@ -8,6 +8,7 @@ import static org.assertj.core.api.Assertions.assertThat; import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; import io.opentelemetry.instrumentation.spring.autoconfigure.internal.properties.ConfigPropertiesBridge; import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; @@ -26,7 +27,7 @@ class SpringWebfluxInstrumentationAutoConfigurationTest { () -> new ConfigPropertiesBridge( DefaultConfigProperties.createFromMap(Collections.emptyMap()), - OpenTelemetry.noop())) + ConfigProvider.noop())) .withConfiguration( AutoConfigurations.of(SpringWebfluxInstrumentationAutoConfiguration.class)); diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webflux/WebClientBeanPostProcessorTest.java b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webflux/WebClientBeanPostProcessorTest.java index 2ae53eb57eda..35956bbb2a19 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webflux/WebClientBeanPostProcessorTest.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webflux/WebClientBeanPostProcessorTest.java @@ -8,6 +8,7 @@ import static org.assertj.core.api.Assertions.assertThat; import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; import io.opentelemetry.instrumentation.spring.autoconfigure.internal.properties.ConfigPropertiesBridge; import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; @@ -27,7 +28,7 @@ class WebClientBeanPostProcessorTest { beanFactory.registerSingleton( "configProperties", new ConfigPropertiesBridge( - DefaultConfigProperties.createFromMap(Collections.emptyMap()), OpenTelemetry.noop())); + DefaultConfigProperties.createFromMap(Collections.emptyMap()), ConfigProvider.noop())); } @Test diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webmvc/SpringWebMvcInstrumentation5AutoConfigurationTest.java b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webmvc/SpringWebMvcInstrumentation5AutoConfigurationTest.java index bbc09d27b283..e331a17172b2 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webmvc/SpringWebMvcInstrumentation5AutoConfigurationTest.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webmvc/SpringWebMvcInstrumentation5AutoConfigurationTest.java @@ -9,6 +9,7 @@ import static org.junit.jupiter.api.Assumptions.assumeFalse; import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; import io.opentelemetry.instrumentation.spring.autoconfigure.internal.properties.ConfigPropertiesBridge; import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; @@ -29,7 +30,7 @@ class SpringWebMvcInstrumentation5AutoConfigurationTest { () -> new ConfigPropertiesBridge( DefaultConfigProperties.createFromMap(Collections.emptyMap()), - OpenTelemetry.noop())) + ConfigProvider.noop())) .withConfiguration( AutoConfigurations.of(SpringWebMvc5InstrumentationAutoConfiguration.class)); diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/testSpring3/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/web/RestClientInstrumentationAutoConfigurationTest.java b/instrumentation/spring/spring-boot-autoconfigure/src/testSpring3/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/web/RestClientInstrumentationAutoConfigurationTest.java index 7e9def12c344..8745c0830bc0 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/testSpring3/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/web/RestClientInstrumentationAutoConfigurationTest.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/testSpring3/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/web/RestClientInstrumentationAutoConfigurationTest.java @@ -8,6 +8,7 @@ import static org.assertj.core.api.Assertions.assertThat; import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; import io.opentelemetry.instrumentation.spring.autoconfigure.internal.properties.ConfigPropertiesBridge; import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; @@ -27,7 +28,7 @@ class RestClientInstrumentationAutoConfigurationTest { () -> new ConfigPropertiesBridge( DefaultConfigProperties.createFromMap(Collections.emptyMap()), - OpenTelemetry.noop())) + ConfigProvider.noop())) .withBean(RestClient.class, RestClient::create) .withConfiguration( AutoConfigurations.of(RestClientInstrumentationAutoConfiguration.class)); diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/testSpring3/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webmvc/SpringWebMvcInstrumentation6AutoConfigurationTest.java b/instrumentation/spring/spring-boot-autoconfigure/src/testSpring3/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webmvc/SpringWebMvcInstrumentation6AutoConfigurationTest.java index dc17ba1fd7ef..13adaebb0eda 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/testSpring3/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webmvc/SpringWebMvcInstrumentation6AutoConfigurationTest.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/testSpring3/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webmvc/SpringWebMvcInstrumentation6AutoConfigurationTest.java @@ -9,6 +9,7 @@ import static org.junit.jupiter.api.Assumptions.assumeTrue; import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; import io.opentelemetry.instrumentation.spring.autoconfigure.internal.properties.ConfigPropertiesBridge; import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; @@ -29,7 +30,7 @@ class SpringWebMvcInstrumentation6AutoConfigurationTest { () -> new ConfigPropertiesBridge( DefaultConfigProperties.createFromMap(Collections.emptyMap()), - OpenTelemetry.noop())) + ConfigProvider.noop())) .withConfiguration( AutoConfigurations.of(SpringWebMvc6InstrumentationAutoConfiguration.class)); diff --git a/instrumentation/spring/spring-boot-autoconfigure/testing/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/AbstractJdbcInstrumentationAutoConfigurationTest.java b/instrumentation/spring/spring-boot-autoconfigure/testing/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/AbstractJdbcInstrumentationAutoConfigurationTest.java index b0a84b75b0cc..81264fb218b4 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/testing/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/AbstractJdbcInstrumentationAutoConfigurationTest.java +++ b/instrumentation/spring/spring-boot-autoconfigure/testing/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/AbstractJdbcInstrumentationAutoConfigurationTest.java @@ -11,6 +11,7 @@ import static org.assertj.core.api.Assertions.assertThat; import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; import io.opentelemetry.instrumentation.spring.autoconfigure.internal.properties.ConfigPropertiesBridge; import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension; @@ -36,7 +37,7 @@ public abstract class AbstractJdbcInstrumentationAutoConfigurationTest { InstrumentationConfig.class, () -> new ConfigPropertiesBridge( - DefaultConfigProperties.createFromMap(emptyMap()), OpenTelemetry.noop())) + DefaultConfigProperties.createFromMap(emptyMap()), ConfigProvider.noop())) .withConfiguration(autoConfigurations()) .withBean("openTelemetry", OpenTelemetry.class, testing()::getOpenTelemetry); diff --git a/instrumentation/spring/spring-boot-autoconfigure/testing/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/AbstractKafkaInstrumentationAutoConfigurationTest.java b/instrumentation/spring/spring-boot-autoconfigure/testing/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/AbstractKafkaInstrumentationAutoConfigurationTest.java index 4cd81572c034..ba7faa2f58f7 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/testing/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/AbstractKafkaInstrumentationAutoConfigurationTest.java +++ b/instrumentation/spring/spring-boot-autoconfigure/testing/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/AbstractKafkaInstrumentationAutoConfigurationTest.java @@ -9,6 +9,7 @@ import static org.assertj.core.api.Assertions.assertThat; import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; import io.opentelemetry.instrumentation.spring.autoconfigure.internal.properties.ConfigPropertiesBridge; import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; @@ -29,7 +30,7 @@ public abstract class AbstractKafkaInstrumentationAutoConfigurationTest { InstrumentationConfig.class, () -> new ConfigPropertiesBridge( - DefaultConfigProperties.createFromMap(emptyMap()), OpenTelemetry.noop())) + DefaultConfigProperties.createFromMap(emptyMap()), ConfigProvider.noop())) .withConfiguration(autoConfigurations()) .withBean("openTelemetry", OpenTelemetry.class, OpenTelemetry::noop); diff --git a/instrumentation/spring/spring-boot-autoconfigure/testing/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/AbstractR2DbcInstrumentationAutoConfigurationTest.java b/instrumentation/spring/spring-boot-autoconfigure/testing/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/AbstractR2DbcInstrumentationAutoConfigurationTest.java index 089e625cb9aa..c9bb1c9ef8ca 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/testing/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/AbstractR2DbcInstrumentationAutoConfigurationTest.java +++ b/instrumentation/spring/spring-boot-autoconfigure/testing/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/AbstractR2DbcInstrumentationAutoConfigurationTest.java @@ -9,6 +9,7 @@ import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_STATEMENT; import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; import io.opentelemetry.instrumentation.spring.autoconfigure.internal.properties.ConfigPropertiesBridge; import io.opentelemetry.instrumentation.testing.junit.LibraryInstrumentationExtension; @@ -32,7 +33,7 @@ public abstract class AbstractR2DbcInstrumentationAutoConfigurationTest { () -> new ConfigPropertiesBridge( DefaultConfigProperties.createFromMap(Collections.emptyMap()), - OpenTelemetry.noop())) + ConfigProvider.noop())) .withConfiguration(autoConfigurations()) .withBean("openTelemetry", OpenTelemetry.class, testing()::getOpenTelemetry); diff --git a/instrumentation/spring/spring-boot-autoconfigure/testing/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/AbstractSpringWebInstrumentationAutoConfigurationTest.java b/instrumentation/spring/spring-boot-autoconfigure/testing/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/AbstractSpringWebInstrumentationAutoConfigurationTest.java index a719f2e16fc7..3d9e914f46ef 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/testing/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/AbstractSpringWebInstrumentationAutoConfigurationTest.java +++ b/instrumentation/spring/spring-boot-autoconfigure/testing/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/AbstractSpringWebInstrumentationAutoConfigurationTest.java @@ -8,6 +8,7 @@ import static org.assertj.core.api.Assertions.assertThat; import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; import io.opentelemetry.instrumentation.spring.autoconfigure.internal.instrumentation.web.RestTemplateBeanPostProcessor; import io.opentelemetry.instrumentation.spring.autoconfigure.internal.properties.ConfigPropertiesBridge; @@ -30,7 +31,7 @@ public abstract class AbstractSpringWebInstrumentationAutoConfigurationTest { () -> new ConfigPropertiesBridge( DefaultConfigProperties.createFromMap(Collections.emptyMap()), - OpenTelemetry.noop())) + ConfigProvider.noop())) .withBean(RestTemplate.class, RestTemplate::new) .withConfiguration(autoConfigurations()); diff --git a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/AgentInstaller.java b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/AgentInstaller.java index 3dc4068632d4..a7743566fe22 100644 --- a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/AgentInstaller.java +++ b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/AgentInstaller.java @@ -15,10 +15,12 @@ import static net.bytebuddy.matcher.ElementMatchers.any; import static net.bytebuddy.matcher.ElementMatchers.none; +import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.context.Context; import io.opentelemetry.context.ContextStorage; import io.opentelemetry.context.Scope; import io.opentelemetry.instrumentation.api.internal.EmbeddedInstrumentationProperties; +import io.opentelemetry.instrumentation.config.bridge.ConfigPropertiesDeclarativeConfigProperties; import io.opentelemetry.javaagent.bootstrap.AgentClassLoader; import io.opentelemetry.javaagent.bootstrap.BootstrapPackagePrefixesHolder; import io.opentelemetry.javaagent.bootstrap.DefineClassHelper; @@ -76,6 +78,7 @@ import net.bytebuddy.dynamic.scaffold.InstrumentedType; import net.bytebuddy.dynamic.scaffold.MethodGraph; import net.bytebuddy.utility.JavaModule; +import org.jetbrains.annotations.NotNull; public class AgentInstaller { @@ -168,10 +171,7 @@ private static void installBytebuddyAgent( ConfigProperties sdkConfig = AutoConfigureUtil.getConfig(autoConfiguredSdk); AgentInstrumentationConfig.internalInitializeConfig( - new ConfigPropertiesBridge( - sdkConfig, - AutoConfigureUtil.getConfigProvider(autoConfiguredSdk), - autoConfiguredSdk.getOpenTelemetrySdk())); + getConfigPropertiesBridge(autoConfiguredSdk, sdkConfig)); copyNecessaryConfigToSystemProperties(sdkConfig); setBootstrapPackages(sdkConfig, extensionClassLoader); @@ -230,6 +230,20 @@ private static void installBytebuddyAgent( runAfterAgentListeners(agentListeners, autoConfiguredSdk, sdkConfig); } + @NotNull + private static ConfigPropertiesBridge getConfigPropertiesBridge( + AutoConfiguredOpenTelemetrySdk autoConfiguredSdk, ConfigProperties sdkConfig) { + ConfigProvider configProvider = AutoConfigureUtil.getConfigProvider(autoConfiguredSdk); + + return new ConfigPropertiesBridge( + sdkConfig, + configProvider != null + ? configProvider + : ConfigPropertiesDeclarativeConfigProperties.create( + AutoConfigureUtil.getConfig(autoConfiguredSdk)), + configProvider != null); + } + private static AgentBuilder newAgentBuilder(ByteBuddy byteBuddy) { // AgentBuilder.Default constructor triggers sun.misc.Unsafe::objectFieldOffset called warning // AgentBuilder$Default. diff --git a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/ConfigPropertiesBridge.java b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/ConfigPropertiesBridge.java index 32492bd11be9..dd22d6e2b37c 100644 --- a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/ConfigPropertiesBridge.java +++ b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/ConfigPropertiesBridge.java @@ -6,9 +6,7 @@ package io.opentelemetry.javaagent.tooling.config; import static io.opentelemetry.api.incubator.config.DeclarativeConfigProperties.empty; -import static java.util.Objects.requireNonNull; -import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.api.incubator.config.InstrumentationConfigUtil; @@ -23,16 +21,16 @@ public final class ConfigPropertiesBridge implements InstrumentationConfig { private final ConfigProperties configProperties; - @Nullable private final ConfigProvider configProvider; - private final OpenTelemetry openTelemetry; + private final ConfigProvider configProvider; + private final boolean useDeclarativeConfig; public ConfigPropertiesBridge( ConfigProperties configProperties, - @Nullable ConfigProvider configProvider, - OpenTelemetry openTelemetry) { + ConfigProvider configProvider, + boolean useDeclarativeConfig) { this.configProperties = configProperties; this.configProvider = configProvider; - this.openTelemetry = openTelemetry; + this.useDeclarativeConfig = useDeclarativeConfig; } @Nullable @@ -119,13 +117,13 @@ public Map getMap(String name, Map defaultValue) @Override public boolean isDeclarative() { - return configProvider != null; + return useDeclarativeConfig; } @Override public DeclarativeConfigProperties getDeclarativeConfig(String node) { DeclarativeConfigProperties config = - InstrumentationConfigUtil.javaInstrumentationConfig(requireNonNull(configProvider), node); + InstrumentationConfigUtil.javaInstrumentationConfig(configProvider, node); if (config == null) { // there is no declarative config for this node return empty(); @@ -138,9 +136,4 @@ public DeclarativeConfigProperties getDeclarativeConfig(String node) { public ConfigProvider getConfigProvider() { return configProvider; } - - @Override - public OpenTelemetry getOpenTelemetry() { - return openTelemetry; - } } diff --git a/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/config/ConfigPropertiesBridgeTest.java b/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/config/ConfigPropertiesBridgeTest.java index 363fcad0f813..796d7a90a9a3 100644 --- a/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/config/ConfigPropertiesBridgeTest.java +++ b/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/config/ConfigPropertiesBridgeTest.java @@ -48,14 +48,11 @@ public static Stream emptyGeneralConfig() { return Stream.of( Arguments.of( "config properties", - new ConfigPropertiesBridge( - configProperties, null, OpenTelemetry.noop())), + new ConfigPropertiesBridge(configProperties, null, OpenTelemetry.noop())), Arguments.of( "declarative config", new ConfigPropertiesBridge( - configProperties, - SdkConfigProvider.create(emptyModel), - OpenTelemetry.noop()))); + configProperties, SdkConfigProvider.create(emptyModel), OpenTelemetry.noop()))); } @ParameterizedTest(name = "{0}") @@ -104,14 +101,11 @@ public static Stream fullGeneralConfig() { return Stream.of( Arguments.of( "config properties", - new ConfigPropertiesBridge( - configProperties, null, OpenTelemetry.noop())), + new ConfigPropertiesBridge(configProperties, null, OpenTelemetry.noop())), Arguments.of( "declarative config", new ConfigPropertiesBridge( - configProperties, - SdkConfigProvider.create(emptyModel), - OpenTelemetry.noop()))); + configProperties, SdkConfigProvider.create(emptyModel), OpenTelemetry.noop()))); } private static Map getProperties() { From 157507ade3eb6e5ade747f7811ecc11a3e9d3ee8 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Fri, 12 Dec 2025 15:18:24 +0100 Subject: [PATCH 59/79] add to InstrumentationConfig --- declarative-config-bridge/build.gradle.kts | 1 + .../ConfigPropertiesDeclarativeConfigProperties.java | 4 ++-- .../api/incubator/config/internal/CommonConfig.java | 2 +- .../incubator/config/internal/InstrumentationConfig.java | 4 ++-- ...gProvider.java => AbstractBridgedConfigProvider.java} | 2 +- .../api/internal/ConfigPropertiesUtil.java | 2 +- .../internal/properties/ConfigPropertiesBridge.java | 3 +-- .../bootstrap/internal/EmptyInstrumentationConfig.java | 9 +-------- 8 files changed, 10 insertions(+), 17 deletions(-) rename instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/{AbstractSystemPropertiesConfigProvider.java => AbstractBridgedConfigProvider.java} (96%) diff --git a/declarative-config-bridge/build.gradle.kts b/declarative-config-bridge/build.gradle.kts index b5ac9ec9c1c3..e02d15f1c081 100644 --- a/declarative-config-bridge/build.gradle.kts +++ b/declarative-config-bridge/build.gradle.kts @@ -8,6 +8,7 @@ group = "io.opentelemetry.instrumentation" dependencies { compileOnly("io.opentelemetry:opentelemetry-sdk-extension-autoconfigure") + implementation(project(":instrumentation-api")) implementation("io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi") implementation("io.opentelemetry:opentelemetry-api-incubator") diff --git a/declarative-config-bridge/src/main/java/io/opentelemetry/instrumentation/config/bridge/ConfigPropertiesDeclarativeConfigProperties.java b/declarative-config-bridge/src/main/java/io/opentelemetry/instrumentation/config/bridge/ConfigPropertiesDeclarativeConfigProperties.java index 65c4bbbed02d..fedc1a27a048 100644 --- a/declarative-config-bridge/src/main/java/io/opentelemetry/instrumentation/config/bridge/ConfigPropertiesDeclarativeConfigProperties.java +++ b/declarative-config-bridge/src/main/java/io/opentelemetry/instrumentation/config/bridge/ConfigPropertiesDeclarativeConfigProperties.java @@ -7,7 +7,7 @@ import io.opentelemetry.api.incubator.config.ConfigProvider; -import io.opentelemetry.instrumentation.api.internal.AbstractSystemPropertiesConfigProvider; +import io.opentelemetry.instrumentation.api.internal.AbstractBridgedConfigProvider; import io.opentelemetry.instrumentation.api.internal.AbstractSystemPropertiesDeclarativeConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import javax.annotation.Nullable; @@ -26,7 +26,7 @@ private ConfigPropertiesDeclarativeConfigProperties( } public static ConfigProvider create(ConfigProperties configProperties) { - return new AbstractSystemPropertiesConfigProvider() { + return new AbstractBridgedConfigProvider() { @Override protected AbstractSystemPropertiesDeclarativeConfigProperties getProperties(String name) { return new ConfigPropertiesDeclarativeConfigProperties(configProperties, name, null); diff --git a/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/config/internal/CommonConfig.java b/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/config/internal/CommonConfig.java index abf1485fd3c4..d273706143ce 100644 --- a/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/config/internal/CommonConfig.java +++ b/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/config/internal/CommonConfig.java @@ -176,7 +176,7 @@ private static T getFromConfigProviderOrFallback( T defaultValue, Supplier fallback) { ConfigProvider configProvider = config.getConfigProvider(); - if (configProvider != null) { + if (config.isDeclarative() && configProvider != null) { T value = getFromConfigProvider.get(configProvider); return value != null ? value : defaultValue; } diff --git a/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/config/internal/InstrumentationConfig.java b/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/config/internal/InstrumentationConfig.java index 13d5f4e543bf..a17195f50658 100644 --- a/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/config/internal/InstrumentationConfig.java +++ b/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/config/internal/InstrumentationConfig.java @@ -130,8 +130,8 @@ default List getList(String name) { DeclarativeConfigProperties getDeclarativeConfig(String node); /** - * @return the {@link ConfigProvider}, which is a bridge to ConfigProperties if declarative - * configuration is not used + * Returns the {@link ConfigProvider}, which is a bridge to ConfigProperties if declarative + * configuration is not used */ ConfigProvider getConfigProvider(); } diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/AbstractSystemPropertiesConfigProvider.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/AbstractBridgedConfigProvider.java similarity index 96% rename from instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/AbstractSystemPropertiesConfigProvider.java rename to instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/AbstractBridgedConfigProvider.java index a420b9dd40da..099e7b3b002b 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/AbstractSystemPropertiesConfigProvider.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/AbstractBridgedConfigProvider.java @@ -16,7 +16,7 @@ * This class is internal and is hence not for public use. Its APIs are unstable and can change at * any time. */ -public abstract class AbstractSystemPropertiesConfigProvider implements ConfigProvider { +public abstract class AbstractBridgedConfigProvider implements ConfigProvider { @Nullable @Override public DeclarativeConfigProperties getInstrumentationConfig() { diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java index 1e8333f63f6a..314052dbbac8 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java @@ -138,7 +138,7 @@ public static ConfigProvider getConfigProvider(OpenTelemetry openTelemetry) { ExtendedOpenTelemetry extendedOpenTelemetry = (ExtendedOpenTelemetry) openTelemetry; return extendedOpenTelemetry.getConfigProvider(); } - return new AbstractSystemPropertiesConfigProvider() { + return new AbstractBridgedConfigProvider() { @Override protected AbstractSystemPropertiesDeclarativeConfigProperties getProperties(String name) { return new SystemPropertiesDeclarativeConfigProperties(name, null); diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/properties/ConfigPropertiesBridge.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/properties/ConfigPropertiesBridge.java index 25cb2da45b1b..28eaae5cc5c4 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/properties/ConfigPropertiesBridge.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/properties/ConfigPropertiesBridge.java @@ -125,7 +125,7 @@ public boolean isDeclarative() { @Override public DeclarativeConfigProperties getDeclarativeConfig(String node) { DeclarativeConfigProperties config = - InstrumentationConfigUtil.javaInstrumentationConfig(requireNonNull(configProvider), node); + InstrumentationConfigUtil.javaInstrumentationConfig(configProvider, node); if (config == null) { // there is no declarative config for this node return empty(); @@ -133,7 +133,6 @@ public DeclarativeConfigProperties getDeclarativeConfig(String node) { return config; } - @Nullable @Override public ConfigProvider getConfigProvider() { return configProvider; diff --git a/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/bootstrap/internal/EmptyInstrumentationConfig.java b/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/bootstrap/internal/EmptyInstrumentationConfig.java index 0ead2701b162..083ebf67fbdd 100644 --- a/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/bootstrap/internal/EmptyInstrumentationConfig.java +++ b/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/bootstrap/internal/EmptyInstrumentationConfig.java @@ -5,7 +5,6 @@ package io.opentelemetry.javaagent.bootstrap.internal; -import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; @@ -73,14 +72,8 @@ public DeclarativeConfigProperties getDeclarativeConfig(String node) { "Declarative configuration is not supported in the empty instrumentation config"); } - @Nullable @Override public ConfigProvider getConfigProvider() { - return null; - } - - @Override - public OpenTelemetry getOpenTelemetry() { - return OpenTelemetry.noop(); + return ConfigProvider.noop(); } } From 1138e4310f0b0a19ddbf2fb87d9447d66582edac Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Fri, 12 Dec 2025 16:15:42 +0100 Subject: [PATCH 60/79] add to InstrumentationConfig --- ...PropertiesDeclarativeConfigProperties.java | 1 - .../api/internal/ConfigPropertiesUtil.java | 29 +++++++------------ .../internal/ConfigPropertiesUtilTest.java | 28 +++++++++++++----- .../autoconfigure/TracingRequestHandler.java | 19 ++++++++++-- .../v2_2/autoconfigure/AwsSdkSingletons.java | 10 +++++-- .../AbstractAwsSdkTelemetryFactory.java | 4 +++ .../jdbc/OpenTelemetryDriver.java | 22 +++++++++++--- .../internal/JdbcInstrumenterFactory.java | 27 +++++++++++++---- .../v2_6/TracingConsumerInterceptor.java | 11 +++++-- .../OpenTelemetryContextDataProvider.java | 10 +++++-- .../properties/ConfigPropertiesBridge.java | 1 - 11 files changed, 116 insertions(+), 46 deletions(-) diff --git a/declarative-config-bridge/src/main/java/io/opentelemetry/instrumentation/config/bridge/ConfigPropertiesDeclarativeConfigProperties.java b/declarative-config-bridge/src/main/java/io/opentelemetry/instrumentation/config/bridge/ConfigPropertiesDeclarativeConfigProperties.java index fedc1a27a048..424277e8494e 100644 --- a/declarative-config-bridge/src/main/java/io/opentelemetry/instrumentation/config/bridge/ConfigPropertiesDeclarativeConfigProperties.java +++ b/declarative-config-bridge/src/main/java/io/opentelemetry/instrumentation/config/bridge/ConfigPropertiesDeclarativeConfigProperties.java @@ -6,7 +6,6 @@ package io.opentelemetry.instrumentation.config.bridge; import io.opentelemetry.api.incubator.config.ConfigProvider; - import io.opentelemetry.instrumentation.api.internal.AbstractBridgedConfigProvider; import io.opentelemetry.instrumentation.api.internal.AbstractSystemPropertiesDeclarativeConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java index 314052dbbac8..d870e61b9d5a 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java @@ -27,6 +27,14 @@ public final class ConfigPropertiesUtil { private static final boolean supportsDeclarativeConfig = supportsDeclarativeConfig(); + static final AbstractBridgedConfigProvider BRIDGED_CONFIG_PROVIDER = + new AbstractBridgedConfigProvider() { + @Override + protected AbstractSystemPropertiesDeclarativeConfigProperties getProperties(String name) { + return new SystemPropertiesDeclarativeConfigProperties(name, null); + } + }; + private static boolean supportsDeclarativeConfig() { try { Class.forName("io.opentelemetry.api.incubator.ExtendedOpenTelemetry"); @@ -45,7 +53,7 @@ private static boolean supportsDeclarativeConfig() { * Returns the boolean value of the given property name from system properties and environment * variables. * - *

It's recommended to use {@link #getBoolean(OpenTelemetry, String...)} instead to support + *

It's recommended to use {@link #getConfigProvider(OpenTelemetry)} instead to support * Declarative Config. */ public static boolean getBoolean(String propertyName, boolean defaultValue) { @@ -53,15 +61,6 @@ public static boolean getBoolean(String propertyName, boolean defaultValue) { return strValue == null ? defaultValue : Boolean.parseBoolean(strValue); } - /** - * Returns the boolean value of the given property name from Declarative Config if available, - * otherwise falls back to system properties and environment variables. - */ - public static Optional getBoolean(OpenTelemetry openTelemetry, String... propertyName) { - return Optional.ofNullable( - getValue(openTelemetry, propertyName, DeclarativeConfigProperties::getBoolean)); - } - /** * Returns the int value of the given property name from system properties and environment * variables. @@ -135,15 +134,9 @@ public static boolean isDeclarativeConfig(OpenTelemetry openTelemetry) { public static ConfigProvider getConfigProvider(OpenTelemetry openTelemetry) { if (isDeclarativeConfig(openTelemetry)) { - ExtendedOpenTelemetry extendedOpenTelemetry = (ExtendedOpenTelemetry) openTelemetry; - return extendedOpenTelemetry.getConfigProvider(); + return ((ExtendedOpenTelemetry) openTelemetry).getConfigProvider(); } - return new AbstractBridgedConfigProvider() { - @Override - protected AbstractSystemPropertiesDeclarativeConfigProperties getProperties(String name) { - return new SystemPropertiesDeclarativeConfigProperties(name, null); - } - }; + return BRIDGED_CONFIG_PROVIDER; } public static String toSystemProperty(String[] nodes) { diff --git a/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java b/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java index a206a73fe295..e9c1232eadff 100644 --- a/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java +++ b/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java @@ -10,7 +10,9 @@ import static java.util.Collections.singletonList; import static org.assertj.core.api.Assertions.assertThat; +import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.api.incubator.config.InstrumentationConfigUtil; import io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfiguration; import io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfigurationBuilder; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalLanguageSpecificInstrumentationModel; @@ -18,6 +20,7 @@ import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel; import java.util.Collections; import java.util.List; +import java.util.Optional; import java.util.stream.Stream; import org.junit.jupiter.api.Test; import org.junit.jupiter.params.ParameterizedTest; @@ -134,7 +137,13 @@ private static void assertBoolean(boolean expected) { assertThat(ConfigPropertiesUtil.getBoolean("otel.instrumentation.test.property.boolean", false)) .isEqualTo(expected); assertThat( - ConfigPropertiesUtil.getBoolean(OpenTelemetry.noop(), "test", "property", "boolean") + Optional.ofNullable( + InstrumentationConfigUtil.getOrNull( + ConfigPropertiesUtil.getConfigProvider(GlobalOpenTelemetry.get()), + config -> config.getBoolean("boolean"), + "java", + "test", + "property")) .orElse(false)) .isEqualTo(expected); } @@ -143,18 +152,21 @@ public static Stream booleanValuesProvider() { return Stream.of( Arguments.of(true, true), Arguments.of(false, false), - Arguments.of("invalid", false), - Arguments.of("true", false), // no type coercion in declarative config - Arguments.of(null, false)); + Arguments.of("invalid", null), + Arguments.of("true", null), // no type coercion in declarative config + Arguments.of(null, null)); } @ParameterizedTest @MethodSource("booleanValuesProvider") - void getBoolean_declarativeConfig(Object property, boolean expected) { + void getBoolean_declarativeConfig(Object property, Boolean expected) { assertThat( - ConfigPropertiesUtil.getBoolean( - DeclarativeConfiguration.create(model(property)), "foo", "bar") - .orElse(false)) + InstrumentationConfigUtil.getOrNull( + ConfigPropertiesUtil.getConfigProvider( + DeclarativeConfiguration.create(model(property))), + config -> config.getBoolean("bar"), + "java", + "foo")) .isEqualTo(expected); } diff --git a/instrumentation/aws-sdk/aws-sdk-1.11/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v1_11/autoconfigure/TracingRequestHandler.java b/instrumentation/aws-sdk/aws-sdk-1.11/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v1_11/autoconfigure/TracingRequestHandler.java index e319b4bb96fb..fa710e45ab94 100644 --- a/instrumentation/aws-sdk/aws-sdk-1.11/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v1_11/autoconfigure/TracingRequestHandler.java +++ b/instrumentation/aws-sdk/aws-sdk-1.11/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v1_11/autoconfigure/TracingRequestHandler.java @@ -11,8 +11,11 @@ import com.amazonaws.handlers.RequestHandler2; import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.api.incubator.config.ConfigProvider; +import io.opentelemetry.api.incubator.config.InstrumentationConfigUtil; import io.opentelemetry.instrumentation.api.internal.ConfigPropertiesUtil; import io.opentelemetry.instrumentation.awssdk.v1_11.AwsSdkTelemetry; +import java.util.Optional; /** * A {@link RequestHandler2} for use as an SPI by the AWS SDK to automatically trace all requests. @@ -22,13 +25,23 @@ public class TracingRequestHandler extends RequestHandler2 { private static final RequestHandler2 DELEGATE = buildDelegate(GlobalOpenTelemetry.get()); private static RequestHandler2 buildDelegate(OpenTelemetry openTelemetry) { + ConfigProvider configProvider = ConfigPropertiesUtil.getConfigProvider(openTelemetry); return AwsSdkTelemetry.builder(openTelemetry) .setCaptureExperimentalSpanAttributes( - ConfigPropertiesUtil.getBoolean(openTelemetry, "aws_sdk", "span_attributes/development") + Optional.ofNullable( + InstrumentationConfigUtil.getOrNull( + configProvider, + config -> config.getBoolean("span_attributes/development"), + "java", + "aws_sdk")) .orElse(false)) .setMessagingReceiveInstrumentationEnabled( - ConfigPropertiesUtil.getBoolean( - openTelemetry, "messaging", "receive_telemetry/development", "enabled") + Optional.ofNullable( + InstrumentationConfigUtil.getOrNull( + configProvider, + config -> config.getBoolean("messaging.receive_telemetry/development"), + "java", + "aws_sdk")) .orElse(false)) .setCapturedHeaders( ConfigPropertiesUtil.getList(openTelemetry, "messaging", "capture_headers/development")) diff --git a/instrumentation/aws-sdk/aws-sdk-2.2/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/autoconfigure/AwsSdkSingletons.java b/instrumentation/aws-sdk/aws-sdk-2.2/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/autoconfigure/AwsSdkSingletons.java index 3c7632e16f6b..bb5082dc8161 100644 --- a/instrumentation/aws-sdk/aws-sdk-2.2/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/autoconfigure/AwsSdkSingletons.java +++ b/instrumentation/aws-sdk/aws-sdk-2.2/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/autoconfigure/AwsSdkSingletons.java @@ -7,10 +7,12 @@ import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.incubator.config.ConfigProvider; +import io.opentelemetry.api.incubator.config.InstrumentationConfigUtil; import io.opentelemetry.instrumentation.api.internal.ConfigPropertiesUtil; import io.opentelemetry.instrumentation.awssdk.v2_2.AwsSdkTelemetry; import io.opentelemetry.instrumentation.awssdk.v2_2.internal.AbstractAwsSdkTelemetryFactory; import java.util.List; +import java.util.Optional; public final class AwsSdkSingletons { @@ -30,8 +32,12 @@ protected List getCapturedHeaders() { @Override protected boolean messagingReceiveInstrumentationEnabled() { - return ConfigPropertiesUtil.getBoolean( - GlobalOpenTelemetry.get(), "messaging", "receive_telemetry/development", "enabled") + return Optional.ofNullable( + InstrumentationConfigUtil.getOrNull( + getConfigProvider(), + config -> config.getBoolean("messaging.receive_telemetry/development"), + "java", + "aws_sdk")) .orElse(false); } diff --git a/instrumentation/aws-sdk/aws-sdk-2.2/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/internal/AbstractAwsSdkTelemetryFactory.java b/instrumentation/aws-sdk/aws-sdk-2.2/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/internal/AbstractAwsSdkTelemetryFactory.java index 2f5643661c2f..bbb388640dc5 100644 --- a/instrumentation/aws-sdk/aws-sdk-2.2/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/internal/AbstractAwsSdkTelemetryFactory.java +++ b/instrumentation/aws-sdk/aws-sdk-2.2/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/internal/AbstractAwsSdkTelemetryFactory.java @@ -24,6 +24,7 @@ private boolean captureExperimentalSpanAttributes() { InstrumentationConfigUtil.getOrNull( getConfigProvider(), config -> config.getBoolean("span_attributes/development"), + "java", "aws_sdk")) .orElse(false); } @@ -35,6 +36,7 @@ private boolean useMessagingPropagator() { InstrumentationConfigUtil.getOrNull( getConfigProvider(), config -> config.getBoolean("use_propagator_for_messaging/development"), + "java", "aws_sdk")) .orElse(false); } @@ -44,6 +46,7 @@ private boolean recordIndividualHttpError() { InstrumentationConfigUtil.getOrNull( getConfigProvider(), config -> config.getBoolean("record_individual_http_error/development"), + "java", "aws_sdk")) .orElse(false); } @@ -53,6 +56,7 @@ private boolean genaiCaptureMessageContent() { InstrumentationConfigUtil.getOrNull( getConfigProvider(), config -> config.getBoolean("capture_message_content"), + "java", "genai")) .orElse(false); } diff --git a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/OpenTelemetryDriver.java b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/OpenTelemetryDriver.java index 6717d9fffe07..7a666f8b80fd 100644 --- a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/OpenTelemetryDriver.java +++ b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/OpenTelemetryDriver.java @@ -23,6 +23,8 @@ import static io.opentelemetry.instrumentation.jdbc.internal.JdbcInstrumenterFactory.INSTRUMENTATION_NAME; import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.api.incubator.config.ConfigProvider; +import io.opentelemetry.api.incubator.config.InstrumentationConfigUtil; import io.opentelemetry.instrumentation.api.incubator.semconv.db.internal.SqlCommenter; import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; import io.opentelemetry.instrumentation.api.internal.ConfigPropertiesUtil; @@ -42,6 +44,7 @@ import java.util.Collections; import java.util.Enumeration; import java.util.List; +import java.util.Optional; import java.util.Properties; import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.atomic.AtomicBoolean; @@ -64,14 +67,25 @@ public final class OpenTelemetryDriver implements Driver { private static final List DRIVER_CANDIDATES = new CopyOnWriteArrayList<>(); private static SqlCommenter getSqlCommenter(OpenTelemetry openTelemetry) { + ConfigProvider configProvider = ConfigPropertiesUtil.getConfigProvider(openTelemetry); boolean defaultValue = - ConfigPropertiesUtil.getBoolean( - openTelemetry, "common", "db_sqlcommenter/development", "enabled") + Optional.ofNullable( + InstrumentationConfigUtil.getOrNull( + configProvider, + config -> config.getBoolean("enabled"), + "java", + "common", + "db_sqlcommenter/development")) .orElse(false); return SqlCommenter.builder() .setEnabled( - ConfigPropertiesUtil.getBoolean( - openTelemetry, "jdbc", "sqlcommenter/development", "enabled") + Optional.ofNullable( + InstrumentationConfigUtil.getOrNull( + configProvider, + config -> config.getBoolean("enabled"), + "java", + "jdbc", + "sqlcommenter/development")) .orElse(defaultValue)) .build(); } diff --git a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/JdbcInstrumenterFactory.java b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/JdbcInstrumenterFactory.java index 5b2e66e14755..19ea5adfeb17 100644 --- a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/JdbcInstrumenterFactory.java +++ b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/JdbcInstrumenterFactory.java @@ -8,6 +8,7 @@ import static java.util.Collections.emptyList; import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.api.incubator.config.InstrumentationConfigUtil; import io.opentelemetry.instrumentation.api.incubator.semconv.code.CodeAttributesExtractor; import io.opentelemetry.instrumentation.api.incubator.semconv.code.CodeSpanNameExtractor; import io.opentelemetry.instrumentation.api.incubator.semconv.db.DbClientMetrics; @@ -19,6 +20,7 @@ import io.opentelemetry.instrumentation.api.internal.ConfigPropertiesUtil; import io.opentelemetry.instrumentation.jdbc.internal.dbinfo.DbInfo; import java.util.List; +import java.util.Optional; import javax.sql.DataSource; /** @@ -29,8 +31,12 @@ public final class JdbcInstrumenterFactory { public static final String INSTRUMENTATION_NAME = "io.opentelemetry.jdbc"; public static boolean captureQueryParameters(OpenTelemetry openTelemetry) { - return ConfigPropertiesUtil.getBoolean( - openTelemetry, "jdbc", "capture_query_parameters/development") + return Optional.ofNullable( + InstrumentationConfigUtil.getOrNull( + ConfigPropertiesUtil.getConfigProvider(openTelemetry), + config -> config.getBoolean("capture_query_parameters/development"), + "java", + "jdbc")) .orElse(false); } @@ -45,8 +51,13 @@ static Instrumenter createStatementInstrumenter( openTelemetry, emptyList(), true, - ConfigPropertiesUtil.getBoolean( - openTelemetry, "common", "db_statement_sanitizer", "enabled") + Optional.ofNullable( + InstrumentationConfigUtil.getOrNull( + ConfigPropertiesUtil.getConfigProvider(openTelemetry), + config -> config.getBoolean("enabled"), + "java", + "common", + "db_statement_sanitizer")) .orElse(true), captureQueryParameters); } @@ -96,7 +107,13 @@ public static Instrumenter createTransactionInstrumenter( OpenTelemetry openTelemetry) { return createTransactionInstrumenter( openTelemetry, - ConfigPropertiesUtil.getBoolean(openTelemetry, "jdbc", "transaction/development", "enabled") + Optional.ofNullable( + InstrumentationConfigUtil.getOrNull( + ConfigPropertiesUtil.getConfigProvider(openTelemetry), + config -> config.getBoolean("enabled"), + "java", + "jdbc", + "transaction/development")) .orElse(false)); } diff --git a/instrumentation/kafka/kafka-clients/kafka-clients-2.6/library/src/main/java/io/opentelemetry/instrumentation/kafkaclients/v2_6/TracingConsumerInterceptor.java b/instrumentation/kafka/kafka-clients/kafka-clients-2.6/library/src/main/java/io/opentelemetry/instrumentation/kafkaclients/v2_6/TracingConsumerInterceptor.java index 82a26cceb06e..66d6e416ea21 100644 --- a/instrumentation/kafka/kafka-clients/kafka-clients-2.6/library/src/main/java/io/opentelemetry/instrumentation/kafkaclients/v2_6/TracingConsumerInterceptor.java +++ b/instrumentation/kafka/kafka-clients/kafka-clients-2.6/library/src/main/java/io/opentelemetry/instrumentation/kafkaclients/v2_6/TracingConsumerInterceptor.java @@ -8,6 +8,7 @@ import com.google.errorprone.annotations.CanIgnoreReturnValue; import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.api.incubator.config.InstrumentationConfigUtil; import io.opentelemetry.context.Context; import io.opentelemetry.instrumentation.api.internal.ConfigPropertiesUtil; import io.opentelemetry.instrumentation.api.internal.Timer; @@ -15,6 +16,7 @@ import io.opentelemetry.instrumentation.kafkaclients.common.v0_11.internal.KafkaConsumerContextUtil; import java.util.Map; import java.util.Objects; +import java.util.Optional; import org.apache.kafka.clients.consumer.ConsumerConfig; import org.apache.kafka.clients.consumer.ConsumerInterceptor; import org.apache.kafka.clients.consumer.ConsumerRecords; @@ -38,8 +40,13 @@ public class TracingConsumerInterceptor implements ConsumerInterceptor config.getBoolean("enabled"), + "java", + "messaging", + "receive_telemetry/development")) .orElse(false)) .setCapturedHeaders( ConfigPropertiesUtil.getList( diff --git a/instrumentation/log4j/log4j-context-data/log4j-context-data-2.17/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/log4j/contextdata/v2_17/OpenTelemetryContextDataProvider.java b/instrumentation/log4j/log4j-context-data/log4j-context-data-2.17/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/log4j/contextdata/v2_17/OpenTelemetryContextDataProvider.java index 050d31337c4c..752eea199e46 100644 --- a/instrumentation/log4j/log4j-context-data/log4j-context-data-2.17/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/log4j/contextdata/v2_17/OpenTelemetryContextDataProvider.java +++ b/instrumentation/log4j/log4j-context-data/log4j-context-data-2.17/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/log4j/contextdata/v2_17/OpenTelemetryContextDataProvider.java @@ -8,6 +8,7 @@ import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.baggage.Baggage; import io.opentelemetry.api.baggage.BaggageEntry; +import io.opentelemetry.api.incubator.config.InstrumentationConfigUtil; import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.SpanContext; import io.opentelemetry.context.Context; @@ -17,6 +18,7 @@ import java.util.Collections; import java.util.HashMap; import java.util.Map; +import java.util.Optional; import org.apache.logging.log4j.ThreadContext; import org.apache.logging.log4j.core.util.ContextDataProvider; @@ -26,8 +28,12 @@ */ public class OpenTelemetryContextDataProvider implements ContextDataProvider { private static final boolean BAGGAGE_ENABLED = - ConfigPropertiesUtil.getBoolean( - GlobalOpenTelemetry.get(), "log4j_context_data", "add_baggage") + Optional.ofNullable( + InstrumentationConfigUtil.getOrNull( + ConfigPropertiesUtil.getConfigProvider(GlobalOpenTelemetry.get()), + config -> config.getBoolean("add_baggage"), + "java", + "log4j_context_data")) .orElse(false); private static final boolean configuredResourceAttributeAccessible = diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/properties/ConfigPropertiesBridge.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/properties/ConfigPropertiesBridge.java index 28eaae5cc5c4..44f8cbac8487 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/properties/ConfigPropertiesBridge.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/properties/ConfigPropertiesBridge.java @@ -6,7 +6,6 @@ package io.opentelemetry.instrumentation.spring.autoconfigure.internal.properties; import static io.opentelemetry.api.incubator.config.DeclarativeConfigProperties.empty; -import static java.util.Objects.requireNonNull; import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; From 3f65273d50a3784cb4e56331e0bd9390c6ceefa3 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Fri, 12 Dec 2025 16:46:54 +0100 Subject: [PATCH 61/79] use InstrumentationConfigUtil --- .../api/internal/ConfigPropertiesUtil.java | 13 ----------- .../internal/ConfigPropertiesUtilTest.java | 22 ++++++++++++++----- .../autoconfigure/TracingRequestHandler.java | 10 ++++++++- .../v2_2/autoconfigure/AwsSdkSingletons.java | 11 ++++++++-- .../v2_6/TracingConsumerInterceptor.java | 16 +++++++++++--- .../v2_6/TracingProducerInterceptor.java | 15 +++++++++++-- 6 files changed, 60 insertions(+), 27 deletions(-) diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java index d870e61b9d5a..b349dcbbd7dc 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java @@ -6,7 +6,6 @@ package io.opentelemetry.instrumentation.api.internal; import static io.opentelemetry.api.incubator.config.DeclarativeConfigProperties.empty; -import static java.util.Collections.emptyList; import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.api.incubator.ExtendedOpenTelemetry; @@ -115,18 +114,6 @@ private static T getValue( return getter.apply(node, propertyName[propertyName.length - 1]); } - /** - * Returns the list of strings value of the given property name from Declarative Config if - * available, otherwise falls back to system properties and environment variables. - */ - public static List getList(OpenTelemetry openTelemetry, String... propertyName) { - return getValue( - openTelemetry, - propertyName, - (declarativeConfigProperties, name) -> - declarativeConfigProperties.getScalarList(name, String.class, emptyList())); - } - /** Returns true if the given OpenTelemetry instance supports Declarative Config. */ public static boolean isDeclarativeConfig(OpenTelemetry openTelemetry) { return supportsDeclarativeConfig && openTelemetry instanceof ExtendedOpenTelemetry; diff --git a/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java b/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java index e9c1232eadff..c79a8b16d6e9 100644 --- a/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java +++ b/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java @@ -210,11 +210,17 @@ void getList_environmentVariable() { @Test void getList_none() { - assertList(emptyList()); + assertList(null); } private static void assertList(List expected) { - assertThat(ConfigPropertiesUtil.getList(OpenTelemetry.noop(), "test", "property", "list")) + assertThat( + InstrumentationConfigUtil.>getOrNull( + ConfigPropertiesUtil.getConfigProvider(OpenTelemetry.noop()), + config -> config.getScalarList("list", String.class), + "java", + "test", + "property")) .isEqualTo(expected); } @@ -223,16 +229,20 @@ public static Stream listValuesProvider() { Arguments.of(asList("a", "b", "c"), asList("a", "b", "c")), Arguments.of(singletonList("single"), singletonList("single")), Arguments.of(emptyList(), emptyList()), - Arguments.of("invalid", emptyList()), - Arguments.of(null, emptyList())); + Arguments.of("invalid", null), + Arguments.of(null, null)); } @ParameterizedTest @MethodSource("listValuesProvider") void getList_declarativeConfig(Object property, List expected) { assertThat( - ConfigPropertiesUtil.getList( - DeclarativeConfiguration.create(model(property)), "foo", "bar")) + InstrumentationConfigUtil.>getOrNull( + ConfigPropertiesUtil.getConfigProvider( + DeclarativeConfiguration.create(model(property))), + config -> config.getScalarList("bar", String.class), + "java", + "foo")) .isEqualTo(expected); } } diff --git a/instrumentation/aws-sdk/aws-sdk-1.11/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v1_11/autoconfigure/TracingRequestHandler.java b/instrumentation/aws-sdk/aws-sdk-1.11/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v1_11/autoconfigure/TracingRequestHandler.java index fa710e45ab94..06db0aefca91 100644 --- a/instrumentation/aws-sdk/aws-sdk-1.11/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v1_11/autoconfigure/TracingRequestHandler.java +++ b/instrumentation/aws-sdk/aws-sdk-1.11/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v1_11/autoconfigure/TracingRequestHandler.java @@ -5,6 +5,8 @@ package io.opentelemetry.instrumentation.awssdk.v1_11.autoconfigure; +import static java.util.Collections.emptyList; + import com.amazonaws.AmazonWebServiceRequest; import com.amazonaws.Request; import com.amazonaws.Response; @@ -44,7 +46,13 @@ private static RequestHandler2 buildDelegate(OpenTelemetry openTelemetry) { "aws_sdk")) .orElse(false)) .setCapturedHeaders( - ConfigPropertiesUtil.getList(openTelemetry, "messaging", "capture_headers/development")) + Optional.ofNullable( + InstrumentationConfigUtil.getOrNull( + configProvider, + config -> config.getScalarList("capture_headers/development", String.class), + "java", + "messaging")) + .orElse(emptyList())) .build() .newRequestHandler(); } diff --git a/instrumentation/aws-sdk/aws-sdk-2.2/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/autoconfigure/AwsSdkSingletons.java b/instrumentation/aws-sdk/aws-sdk-2.2/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/autoconfigure/AwsSdkSingletons.java index bb5082dc8161..667c9da2c3a2 100644 --- a/instrumentation/aws-sdk/aws-sdk-2.2/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/autoconfigure/AwsSdkSingletons.java +++ b/instrumentation/aws-sdk/aws-sdk-2.2/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/autoconfigure/AwsSdkSingletons.java @@ -5,6 +5,8 @@ package io.opentelemetry.instrumentation.awssdk.v2_2.autoconfigure; +import static java.util.Collections.emptyList; + import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.api.incubator.config.InstrumentationConfigUtil; @@ -26,8 +28,13 @@ private static class AwsSdkTelemetryFactory extends AbstractAwsSdkTelemetryFacto @Override protected List getCapturedHeaders() { - return ConfigPropertiesUtil.getList( - GlobalOpenTelemetry.get(), "messaging", "capture_headers/development"); + return Optional.ofNullable( + InstrumentationConfigUtil.getOrNull( + ConfigPropertiesUtil.getConfigProvider(GlobalOpenTelemetry.get()), + config -> config.getScalarList("capture_headers/development", String.class), + "java", + "messaging")) + .orElse(emptyList()); } @Override diff --git a/instrumentation/kafka/kafka-clients/kafka-clients-2.6/library/src/main/java/io/opentelemetry/instrumentation/kafkaclients/v2_6/TracingConsumerInterceptor.java b/instrumentation/kafka/kafka-clients/kafka-clients-2.6/library/src/main/java/io/opentelemetry/instrumentation/kafkaclients/v2_6/TracingConsumerInterceptor.java index 66d6e416ea21..5de47fce39b5 100644 --- a/instrumentation/kafka/kafka-clients/kafka-clients-2.6/library/src/main/java/io/opentelemetry/instrumentation/kafkaclients/v2_6/TracingConsumerInterceptor.java +++ b/instrumentation/kafka/kafka-clients/kafka-clients-2.6/library/src/main/java/io/opentelemetry/instrumentation/kafkaclients/v2_6/TracingConsumerInterceptor.java @@ -5,9 +5,12 @@ package io.opentelemetry.instrumentation.kafkaclients.v2_6; +import static java.util.Collections.emptyList; + import com.google.errorprone.annotations.CanIgnoreReturnValue; import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.api.incubator.config.InstrumentationConfigUtil; import io.opentelemetry.context.Context; import io.opentelemetry.instrumentation.api.internal.ConfigPropertiesUtil; @@ -37,20 +40,27 @@ public class TracingConsumerInterceptor implements ConsumerInterceptor config.getBoolean("enabled"), "java", "messaging", "receive_telemetry/development")) .orElse(false)) .setCapturedHeaders( - ConfigPropertiesUtil.getList( - openTelemetry, "messaging", "capture_headers/development")) + Optional.ofNullable( + InstrumentationConfigUtil.getOrNull( + configProvider, + config -> + config.getScalarList("capture_headers/development", String.class), + "java", + "messaging")) + .orElse(emptyList())) .build(); } diff --git a/instrumentation/kafka/kafka-clients/kafka-clients-2.6/library/src/main/java/io/opentelemetry/instrumentation/kafkaclients/v2_6/TracingProducerInterceptor.java b/instrumentation/kafka/kafka-clients/kafka-clients-2.6/library/src/main/java/io/opentelemetry/instrumentation/kafkaclients/v2_6/TracingProducerInterceptor.java index 6d8a6af196f8..e075fe1bb36d 100644 --- a/instrumentation/kafka/kafka-clients/kafka-clients-2.6/library/src/main/java/io/opentelemetry/instrumentation/kafkaclients/v2_6/TracingProducerInterceptor.java +++ b/instrumentation/kafka/kafka-clients/kafka-clients-2.6/library/src/main/java/io/opentelemetry/instrumentation/kafkaclients/v2_6/TracingProducerInterceptor.java @@ -5,12 +5,16 @@ package io.opentelemetry.instrumentation.kafkaclients.v2_6; +import static java.util.Collections.emptyList; + import com.google.errorprone.annotations.CanIgnoreReturnValue; import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.api.incubator.config.InstrumentationConfigUtil; import io.opentelemetry.instrumentation.api.internal.ConfigPropertiesUtil; import java.util.Map; import java.util.Objects; +import java.util.Optional; import javax.annotation.Nullable; import org.apache.kafka.clients.producer.ProducerConfig; import org.apache.kafka.clients.producer.ProducerInterceptor; @@ -34,9 +38,16 @@ public class TracingProducerInterceptor implements ProducerInterceptor + config.getScalarList("capture_headers/development", String.class), + "java", + "messaging")) + .orElse(emptyList())) .build(); + ; } @Nullable private String clientId; From b8b562ab6aaab063bf46b230bdf1534aea4d89be Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Fri, 12 Dec 2025 19:39:58 +0100 Subject: [PATCH 62/79] cleanup --- ...PropertiesDeclarativeConfigProperties.java | 12 +- .../api/instrumenter/InstrumenterBuilder.java | 13 +- .../AbstractBridgedConfigProvider.java | 2 +- ...ctBridgedDeclarativeConfigProperties.java} | 37 +++- .../api/internal/ConfigPropertiesUtil.java | 98 +-------- .../api/internal/ConfigProviderUtil.java | 52 +++++ ...PropertiesDeclarativeConfigProperties.java | 8 +- ...ridgedDeclarativeConfigPropertiesTest.java | 29 +++ .../internal/ConfigPropertiesUtilTest.java | 168 --------------- .../api/internal/ConfigProviderUtilTest.java | 201 ++++++++++++++++++ .../autoconfigure/TracingRequestHandler.java | 4 +- .../v2_2/autoconfigure/AwsSdkSingletons.java | 6 +- .../jdbc/OpenTelemetryDriver.java | 4 +- .../internal/JdbcInstrumenterFactory.java | 8 +- .../v2_6/TracingConsumerInterceptor.java | 4 +- .../v2_6/TracingProducerInterceptor.java | 4 +- .../OpenTelemetryContextDataProvider.java | 4 +- .../v2_17/internal/ContextDataKeys.java | 26 ++- .../servlet-common/bootstrap/build.gradle.kts | 4 + .../servlet/ExperimentalSnippetHolder.java | 10 +- 20 files changed, 383 insertions(+), 311 deletions(-) rename instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/{AbstractSystemPropertiesDeclarativeConfigProperties.java => AbstractBridgedDeclarativeConfigProperties.java} (72%) create mode 100644 instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigProviderUtil.java create mode 100644 instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/AbstractBridgedDeclarativeConfigPropertiesTest.java create mode 100644 instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigProviderUtilTest.java diff --git a/declarative-config-bridge/src/main/java/io/opentelemetry/instrumentation/config/bridge/ConfigPropertiesDeclarativeConfigProperties.java b/declarative-config-bridge/src/main/java/io/opentelemetry/instrumentation/config/bridge/ConfigPropertiesDeclarativeConfigProperties.java index 424277e8494e..d111a93e9ee4 100644 --- a/declarative-config-bridge/src/main/java/io/opentelemetry/instrumentation/config/bridge/ConfigPropertiesDeclarativeConfigProperties.java +++ b/declarative-config-bridge/src/main/java/io/opentelemetry/instrumentation/config/bridge/ConfigPropertiesDeclarativeConfigProperties.java @@ -7,12 +7,12 @@ import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.instrumentation.api.internal.AbstractBridgedConfigProvider; -import io.opentelemetry.instrumentation.api.internal.AbstractSystemPropertiesDeclarativeConfigProperties; +import io.opentelemetry.instrumentation.api.internal.AbstractBridgedDeclarativeConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import javax.annotation.Nullable; public class ConfigPropertiesDeclarativeConfigProperties - extends AbstractSystemPropertiesDeclarativeConfigProperties { + extends AbstractBridgedDeclarativeConfigProperties { private final ConfigProperties configProperties; @@ -27,7 +27,7 @@ private ConfigPropertiesDeclarativeConfigProperties( public static ConfigProvider create(ConfigProperties configProperties) { return new AbstractBridgedConfigProvider() { @Override - protected AbstractSystemPropertiesDeclarativeConfigProperties getProperties(String name) { + protected AbstractBridgedDeclarativeConfigProperties getProperties(String name) { return new ConfigPropertiesDeclarativeConfigProperties(configProperties, name, null); } }; @@ -35,12 +35,12 @@ protected AbstractSystemPropertiesDeclarativeConfigProperties getProperties(Stri @Nullable @Override - public String getString(String name) { - return configProperties.getString(name); + public String getStringValue(String systemPropertyKey) { + return configProperties.getString(systemPropertyKey); } @Override - protected AbstractSystemPropertiesDeclarativeConfigProperties newChild(String node) { + protected AbstractBridgedDeclarativeConfigProperties newChild(String node) { return new ConfigPropertiesDeclarativeConfigProperties(configProperties, node, this); } } diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/InstrumenterBuilder.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/InstrumenterBuilder.java index d8fbbae07973..4e9e65ad85b4 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/InstrumenterBuilder.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/InstrumenterBuilder.java @@ -9,7 +9,9 @@ import static java.util.logging.Level.WARNING; import com.google.errorprone.annotations.CanIgnoreReturnValue; +import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.api.incubator.config.InstrumentationConfigUtil; import io.opentelemetry.api.metrics.Meter; import io.opentelemetry.api.metrics.MeterBuilder; import io.opentelemetry.api.trace.SpanKind; @@ -20,6 +22,7 @@ import io.opentelemetry.context.propagation.TextMapGetter; import io.opentelemetry.context.propagation.TextMapSetter; import io.opentelemetry.instrumentation.api.internal.ConfigPropertiesUtil; +import io.opentelemetry.instrumentation.api.internal.ConfigProviderUtil; import io.opentelemetry.instrumentation.api.internal.EmbeddedInstrumentationProperties; import io.opentelemetry.instrumentation.api.internal.Experimental; import io.opentelemetry.instrumentation.api.internal.InstrumenterBuilderAccess; @@ -371,10 +374,12 @@ SpanSuppressor buildSpanSuppressor() { // otel.instrumentation.experimental.* doesn't fit the usual pattern of configuration properties // for instrumentations, so we need to handle both declarative and non-declarative configs here String value = - ConfigPropertiesUtil.isDeclarativeConfig(openTelemetry) - ? ConfigPropertiesUtil.getString( - openTelemetry, "common", "span_suppression_strategy/development") - .orElse(null) + ConfigProviderUtil.isDeclarativeConfig(openTelemetry) + ? InstrumentationConfigUtil.getOrNull( + ConfigProviderUtil.getConfigProvider(GlobalOpenTelemetry.get()), + config -> config.getString("span_suppression_strategy/development"), + "java", + "common") : ConfigPropertiesUtil.getString( "otel.instrumentation.experimental.span-suppression-strategy"); return new SpanSuppressors.ByContextKey( diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/AbstractBridgedConfigProvider.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/AbstractBridgedConfigProvider.java index 099e7b3b002b..5dbaebb6ed45 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/AbstractBridgedConfigProvider.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/AbstractBridgedConfigProvider.java @@ -37,7 +37,7 @@ public DeclarativeConfigProperties getStructured(String name) { }; } - protected abstract AbstractSystemPropertiesDeclarativeConfigProperties getProperties(String name); + protected abstract AbstractBridgedDeclarativeConfigProperties getProperties(String name); private abstract static class EmptyDeclarativeConfigProperties implements DeclarativeConfigProperties { diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/AbstractSystemPropertiesDeclarativeConfigProperties.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/AbstractBridgedDeclarativeConfigProperties.java similarity index 72% rename from instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/AbstractSystemPropertiesDeclarativeConfigProperties.java rename to instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/AbstractBridgedDeclarativeConfigProperties.java index e37d9e4c17ab..ab9b58e67ea3 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/AbstractSystemPropertiesDeclarativeConfigProperties.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/AbstractBridgedDeclarativeConfigProperties.java @@ -18,13 +18,13 @@ * This class is internal and is hence not for public use. Its APIs are unstable and can change at * any time. */ -public abstract class AbstractSystemPropertiesDeclarativeConfigProperties +public abstract class AbstractBridgedDeclarativeConfigProperties implements DeclarativeConfigProperties { protected final String node; - @Nullable protected final AbstractSystemPropertiesDeclarativeConfigProperties parent; + @Nullable protected final AbstractBridgedDeclarativeConfigProperties parent; - public AbstractSystemPropertiesDeclarativeConfigProperties( - String node, @Nullable AbstractSystemPropertiesDeclarativeConfigProperties parent) { + public AbstractBridgedDeclarativeConfigProperties( + String node, @Nullable AbstractBridgedDeclarativeConfigProperties parent) { this.node = node; this.parent = parent; } @@ -36,6 +36,12 @@ private static List filterBlanksAndNulls(String[] values) { .collect(Collectors.toList()); } + @Nullable + @Override + public String getString(String name) { + return getStringValue(getSystemProperty(name)); + } + @Nullable @Override public Boolean getBoolean(String name) { @@ -97,8 +103,7 @@ public List getScalarList(String name, Class scalarType) { return value == null ? null : (List) - AbstractSystemPropertiesDeclarativeConfigProperties.filterBlanksAndNulls( - value.split(",")); + AbstractBridgedDeclarativeConfigProperties.filterBlanksAndNulls(value.split(",")); } @Nullable @@ -123,13 +128,16 @@ public ComponentLoader getComponentLoader() { throw new UnsupportedOperationException(); } - protected abstract AbstractSystemPropertiesDeclarativeConfigProperties newChild(String node); + protected abstract AbstractBridgedDeclarativeConfigProperties newChild(String node); - protected String getSystemProperty(String name) { + @Nullable + protected abstract String getStringValue(String systemPropertyKey); + + private String getSystemProperty(String name) { List nodes = new ArrayList<>(); addSystemPropertyPathNodes(nodes); nodes.add(name); - return ConfigPropertiesUtil.toSystemProperty(nodes); + return toSystemProperty(nodes); } private void addSystemPropertyPathNodes(List parts) { @@ -138,4 +146,15 @@ private void addSystemPropertyPathNodes(List parts) { } parts.add(node); } + + static String toSystemProperty(List nodes) { + for (int i = 0; i < nodes.size(); i++) { + String node = nodes.get(i); + if (node.endsWith("/development")) { + String prefix = node.contains("experimental") ? "" : "experimental."; + nodes.set(i, prefix + node.substring(0, node.length() - 12)); + } + } + return "otel.instrumentation." + String.join(".", nodes).replace('_', '-'); + } } diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java index b349dcbbd7dc..1a7f3b383031 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java @@ -5,17 +5,7 @@ package io.opentelemetry.instrumentation.api.internal; -import static io.opentelemetry.api.incubator.config.DeclarativeConfigProperties.empty; - import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.api.incubator.ExtendedOpenTelemetry; -import io.opentelemetry.api.incubator.config.ConfigProvider; -import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; -import java.util.ArrayList; -import java.util.Arrays; -import java.util.List; -import java.util.Optional; -import java.util.function.BiFunction; import javax.annotation.Nullable; /** @@ -24,36 +14,12 @@ */ public final class ConfigPropertiesUtil { - private static final boolean supportsDeclarativeConfig = supportsDeclarativeConfig(); - - static final AbstractBridgedConfigProvider BRIDGED_CONFIG_PROVIDER = - new AbstractBridgedConfigProvider() { - @Override - protected AbstractSystemPropertiesDeclarativeConfigProperties getProperties(String name) { - return new SystemPropertiesDeclarativeConfigProperties(name, null); - } - }; - - private static boolean supportsDeclarativeConfig() { - try { - Class.forName("io.opentelemetry.api.incubator.ExtendedOpenTelemetry"); - return true; - } catch (ClassNotFoundException e) { - // The incubator module is not available. - // This only happens in OpenTelemetry API instrumentation tests, where an older version of - // OpenTelemetry API is used that does not have ExtendedOpenTelemetry. - // Having the incubator module without ExtendedOpenTelemetry class should still return false - // for those tests to avoid a ClassNotFoundException. - return false; - } - } - /** * Returns the boolean value of the given property name from system properties and environment * variables. * - *

It's recommended to use {@link #getConfigProvider(OpenTelemetry)} instead to support - * Declarative Config. + *

It's recommended to use {@link ConfigProviderUtil#getConfigProvider(OpenTelemetry)} instead + * to support Declarative Config. */ public static boolean getBoolean(String propertyName, boolean defaultValue) { String strValue = getString(propertyName); @@ -63,6 +29,9 @@ public static boolean getBoolean(String propertyName, boolean defaultValue) { /** * Returns the int value of the given property name from system properties and environment * variables. + * + *

It's recommended to use {@link ConfigProviderUtil#getConfigProvider(OpenTelemetry)} instead + * to support Declarative Config. */ public static int getInt(String propertyName, int defaultValue) { String strValue = getString(propertyName); @@ -80,66 +49,13 @@ public static int getInt(String propertyName, int defaultValue) { * Returns the string value of the given property name from system properties and environment * variables. * - *

It's recommended to use {@link #getString(OpenTelemetry, String...)} instead to support - * Declarative Config. + *

It's recommended to use {@link ConfigProviderUtil#getConfigProvider(OpenTelemetry)} instead + * to support Declarative Config. */ @Nullable public static String getString(String propertyName) { return ConfigUtil.getString(ConfigUtil.normalizePropertyKey(propertyName)); } - /** - * Returns the string value of the given property name from Declarative Config if available, - * otherwise falls back to system properties and environment variables. - */ - public static Optional getString(OpenTelemetry openTelemetry, String... propertyName) { - return Optional.ofNullable( - getValue(openTelemetry, propertyName, DeclarativeConfigProperties::getString)); - } - - private static T getValue( - OpenTelemetry openTelemetry, - String[] propertyName, - BiFunction getter) { - DeclarativeConfigProperties instrumentationConfig = - getConfigProvider(openTelemetry).getInstrumentationConfig(); - DeclarativeConfigProperties node = - instrumentationConfig == null - ? empty() - : instrumentationConfig.getStructured("java", empty()); - // last part is the leaf property - for (int i = 0; i < propertyName.length - 1; i++) { - node = node.getStructured(propertyName[i], empty()); - } - return getter.apply(node, propertyName[propertyName.length - 1]); - } - - /** Returns true if the given OpenTelemetry instance supports Declarative Config. */ - public static boolean isDeclarativeConfig(OpenTelemetry openTelemetry) { - return supportsDeclarativeConfig && openTelemetry instanceof ExtendedOpenTelemetry; - } - - public static ConfigProvider getConfigProvider(OpenTelemetry openTelemetry) { - if (isDeclarativeConfig(openTelemetry)) { - return ((ExtendedOpenTelemetry) openTelemetry).getConfigProvider(); - } - return BRIDGED_CONFIG_PROVIDER; - } - - public static String toSystemProperty(String[] nodes) { - return toSystemProperty(new ArrayList<>(Arrays.asList(nodes))); - } - - public static String toSystemProperty(List nodes) { - for (int i = 0; i < nodes.size(); i++) { - String node = nodes.get(i); - if (node.endsWith("/development")) { - String prefix = node.contains("experimental") ? "" : "experimental."; - nodes.set(i, prefix + node.substring(0, node.length() - 12)); - } - } - return "otel.instrumentation." + String.join(".", nodes).replace('_', '-'); - } - private ConfigPropertiesUtil() {} } diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigProviderUtil.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigProviderUtil.java new file mode 100644 index 000000000000..532e7898614e --- /dev/null +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigProviderUtil.java @@ -0,0 +1,52 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.api.internal; + +import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.api.incubator.ExtendedOpenTelemetry; +import io.opentelemetry.api.incubator.config.ConfigProvider; + +/** + * This class is internal and is hence not for public use. Its APIs are unstable and can change at + * any time. + */ +public class ConfigProviderUtil { + + static final AbstractBridgedConfigProvider BRIDGED_CONFIG_PROVIDER = + new AbstractBridgedConfigProvider() { + @Override + protected AbstractBridgedDeclarativeConfigProperties getProperties(String name) { + return new SystemPropertiesDeclarativeConfigProperties(name, null); + } + }; + private static final boolean supportsDeclarativeConfig = supportsDeclarativeConfig(); + + private static boolean supportsDeclarativeConfig() { + try { + Class.forName("io.opentelemetry.api.incubator.ExtendedOpenTelemetry"); + return true; + } catch (ClassNotFoundException e) { + // The incubator module is not available. + // This only happens in OpenTelemetry API instrumentation tests, where an older version of + // OpenTelemetry API is used that does not have ExtendedOpenTelemetry. + // Having the incubator module without ExtendedOpenTelemetry class should still return false + // for those tests to avoid a ClassNotFoundException. + return false; + } + } + + /** Returns true if the given OpenTelemetry instance supports Declarative Config. */ + public static boolean isDeclarativeConfig(OpenTelemetry openTelemetry) { + return supportsDeclarativeConfig && openTelemetry instanceof ExtendedOpenTelemetry; + } + + public static ConfigProvider getConfigProvider(OpenTelemetry openTelemetry) { + if (isDeclarativeConfig(openTelemetry)) { + return ((ExtendedOpenTelemetry) openTelemetry).getConfigProvider(); + } + return BRIDGED_CONFIG_PROVIDER; + } +} diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/SystemPropertiesDeclarativeConfigProperties.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/SystemPropertiesDeclarativeConfigProperties.java index 7ec1f7f1c2f3..d6bdc387a479 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/SystemPropertiesDeclarativeConfigProperties.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/SystemPropertiesDeclarativeConfigProperties.java @@ -8,7 +8,7 @@ import javax.annotation.Nullable; class SystemPropertiesDeclarativeConfigProperties - extends AbstractSystemPropertiesDeclarativeConfigProperties { + extends AbstractBridgedDeclarativeConfigProperties { SystemPropertiesDeclarativeConfigProperties( String node, @Nullable SystemPropertiesDeclarativeConfigProperties parent) { @@ -17,12 +17,12 @@ class SystemPropertiesDeclarativeConfigProperties @Nullable @Override - public String getString(String name) { - return ConfigPropertiesUtil.getString(getSystemProperty(name)); + public String getStringValue(String systemPropertyKey) { + return ConfigPropertiesUtil.getString(systemPropertyKey); } @Override - protected AbstractSystemPropertiesDeclarativeConfigProperties newChild(String node) { + protected AbstractBridgedDeclarativeConfigProperties newChild(String node) { return new SystemPropertiesDeclarativeConfigProperties(node, this); } } diff --git a/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/AbstractBridgedDeclarativeConfigPropertiesTest.java b/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/AbstractBridgedDeclarativeConfigPropertiesTest.java new file mode 100644 index 000000000000..288d76196792 --- /dev/null +++ b/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/AbstractBridgedDeclarativeConfigPropertiesTest.java @@ -0,0 +1,29 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.api.internal; + +import static org.assertj.core.api.Assertions.assertThat; + +import java.util.Arrays; +import org.junit.jupiter.api.Test; + +class AbstractBridgedDeclarativeConfigPropertiesTest { + @Test + void toSystemProperty() { + assertThat( + AbstractBridgedDeclarativeConfigProperties.toSystemProperty( + Arrays.asList("a_b", "c", "d"))) + .isEqualTo("otel.instrumentation.a-b.c.d"); + assertThat( + AbstractBridgedDeclarativeConfigProperties.toSystemProperty( + Arrays.asList("a_b/development", "c", "d"))) + .isEqualTo("otel.instrumentation.experimental.a-b.c.d"); + assertThat( + AbstractBridgedDeclarativeConfigProperties.toSystemProperty( + Arrays.asList("a_experimental_b/development", "c", "d"))) + .isEqualTo("otel.instrumentation.a-experimental-b.c.d"); + } +} diff --git a/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java b/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java index c79a8b16d6e9..29e5082fd009 100644 --- a/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java +++ b/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtilTest.java @@ -5,27 +5,9 @@ package io.opentelemetry.instrumentation.api.internal; -import static java.util.Arrays.asList; -import static java.util.Collections.emptyList; -import static java.util.Collections.singletonList; import static org.assertj.core.api.Assertions.assertThat; -import io.opentelemetry.api.GlobalOpenTelemetry; -import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.api.incubator.config.InstrumentationConfigUtil; -import io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfiguration; -import io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfigurationBuilder; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalLanguageSpecificInstrumentationModel; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.InstrumentationModel; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel; -import java.util.Collections; -import java.util.List; -import java.util.Optional; -import java.util.stream.Stream; import org.junit.jupiter.api.Test; -import org.junit.jupiter.params.ParameterizedTest; -import org.junit.jupiter.params.provider.Arguments; -import org.junit.jupiter.params.provider.MethodSource; import org.junitpioneer.jupiter.SetEnvironmentVariable; import org.junitpioneer.jupiter.SetSystemProperty; @@ -49,48 +31,6 @@ void getString_none() { assertThat(ConfigPropertiesUtil.getString("test.property.string")).isNull(); } - @SetEnvironmentVariable(key = "OTEL_INSTRUMENTATION_TEST_PROPERTY_STRING", value = "env_value") - @SetSystemProperty(key = "otel.instrumentation.test.property.string", value = "sys_value") - @Test - void getString_withOpenTelemetry_systemProperty() { - assertString("sys_value"); - } - - @SetEnvironmentVariable(key = "OTEL_INSTRUMENTATION_TEST_PROPERTY_STRING", value = "env_value") - @Test - void getString_withOpenTelemetry_environmentVariable() { - assertString("env_value"); - } - - @Test - void getString_withOpenTelemetry_none() { - assertString("default_value"); - } - - private static void assertString(String expected) { - assertThat( - ConfigPropertiesUtil.getString(OpenTelemetry.noop(), "test", "property", "string") - .orElse("default_value")) - .isEqualTo(expected); - } - - public static Stream stringValuesProvider() { - return Stream.of( - Arguments.of("value1", "value1"), - Arguments.of("", ""), - Arguments.of(null, "default_value"), - Arguments.of(123, "default_value"), // no type coercion in declarative config - Arguments.of(true, "default_value")); // no type coercion in declarative config - } - - @ParameterizedTest - @MethodSource("stringValuesProvider") - void getString_declarativeConfig(Object property, String expected) { - OpenTelemetry openTelemetry = DeclarativeConfiguration.create(model(property)); - assertThat(ConfigPropertiesUtil.getString(openTelemetry, "foo", "bar").orElse("default_value")) - .isEqualTo(expected); - } - @SetEnvironmentVariable(key = "TEST_PROPERTY_INT", value = "12") @SetSystemProperty(key = "test.property.int", value = "42") @Test @@ -136,113 +76,5 @@ void getBoolean_none() { private static void assertBoolean(boolean expected) { assertThat(ConfigPropertiesUtil.getBoolean("otel.instrumentation.test.property.boolean", false)) .isEqualTo(expected); - assertThat( - Optional.ofNullable( - InstrumentationConfigUtil.getOrNull( - ConfigPropertiesUtil.getConfigProvider(GlobalOpenTelemetry.get()), - config -> config.getBoolean("boolean"), - "java", - "test", - "property")) - .orElse(false)) - .isEqualTo(expected); - } - - public static Stream booleanValuesProvider() { - return Stream.of( - Arguments.of(true, true), - Arguments.of(false, false), - Arguments.of("invalid", null), - Arguments.of("true", null), // no type coercion in declarative config - Arguments.of(null, null)); - } - - @ParameterizedTest - @MethodSource("booleanValuesProvider") - void getBoolean_declarativeConfig(Object property, Boolean expected) { - assertThat( - InstrumentationConfigUtil.getOrNull( - ConfigPropertiesUtil.getConfigProvider( - DeclarativeConfiguration.create(model(property))), - config -> config.getBoolean("bar"), - "java", - "foo")) - .isEqualTo(expected); - } - - private static OpenTelemetryConfigurationModel model(Object value) { - return new DeclarativeConfigurationBuilder() - .customizeModel( - new OpenTelemetryConfigurationModel() - .withFileFormat("1.0-rc.1") - .withInstrumentationDevelopment( - new InstrumentationModel() - .withJava( - new ExperimentalLanguageSpecificInstrumentationModel() - .withAdditionalProperty( - "foo", Collections.singletonMap("bar", value))))); - } - - @Test - void toSystemProperty() { - assertThat(ConfigPropertiesUtil.toSystemProperty(new String[] {"a_b", "c", "d"})) - .isEqualTo("otel.instrumentation.a-b.c.d"); - assertThat(ConfigPropertiesUtil.toSystemProperty(new String[] {"a_b/development", "c", "d"})) - .isEqualTo("otel.instrumentation.experimental.a-b.c.d"); - assertThat( - ConfigPropertiesUtil.toSystemProperty( - new String[] {"a_experimental_b/development", "c", "d"})) - .isEqualTo("otel.instrumentation.a-experimental-b.c.d"); - } - - @SetEnvironmentVariable(key = "OTEL_INSTRUMENTATION_TEST_PROPERTY_LIST", value = "a,b,c") - @SetSystemProperty(key = "otel.instrumentation.test.property.list", value = "x,y,z") - @Test - void getList_systemProperty() { - assertList(asList("x", "y", "z")); - } - - @SetEnvironmentVariable(key = "OTEL_INSTRUMENTATION_TEST_PROPERTY_LIST", value = "a,b,c") - @Test - void getList_environmentVariable() { - assertList(asList("a", "b", "c")); - } - - @Test - void getList_none() { - assertList(null); - } - - private static void assertList(List expected) { - assertThat( - InstrumentationConfigUtil.>getOrNull( - ConfigPropertiesUtil.getConfigProvider(OpenTelemetry.noop()), - config -> config.getScalarList("list", String.class), - "java", - "test", - "property")) - .isEqualTo(expected); - } - - public static Stream listValuesProvider() { - return Stream.of( - Arguments.of(asList("a", "b", "c"), asList("a", "b", "c")), - Arguments.of(singletonList("single"), singletonList("single")), - Arguments.of(emptyList(), emptyList()), - Arguments.of("invalid", null), - Arguments.of(null, null)); - } - - @ParameterizedTest - @MethodSource("listValuesProvider") - void getList_declarativeConfig(Object property, List expected) { - assertThat( - InstrumentationConfigUtil.>getOrNull( - ConfigPropertiesUtil.getConfigProvider( - DeclarativeConfiguration.create(model(property))), - config -> config.getScalarList("bar", String.class), - "java", - "foo")) - .isEqualTo(expected); } } diff --git a/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigProviderUtilTest.java b/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigProviderUtilTest.java new file mode 100644 index 000000000000..d1166cff812c --- /dev/null +++ b/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/ConfigProviderUtilTest.java @@ -0,0 +1,201 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.api.internal; + +import static java.util.Arrays.asList; +import static java.util.Collections.emptyList; +import static java.util.Collections.singletonList; +import static org.assertj.core.api.Assertions.assertThat; + +import io.opentelemetry.api.GlobalOpenTelemetry; +import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.api.incubator.config.InstrumentationConfigUtil; +import io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfiguration; +import io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfigurationBuilder; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalLanguageSpecificInstrumentationModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.InstrumentationModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel; +import java.util.Collections; +import java.util.List; +import java.util.Optional; +import java.util.stream.Stream; +import javax.annotation.Nullable; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.params.ParameterizedTest; +import org.junit.jupiter.params.provider.Arguments; +import org.junit.jupiter.params.provider.MethodSource; +import org.junitpioneer.jupiter.SetEnvironmentVariable; +import org.junitpioneer.jupiter.SetSystemProperty; + +class ConfigProviderUtilTest { + @SetEnvironmentVariable(key = "OTEL_INSTRUMENTATION_TEST_PROPERTY_STRING", value = "env_value") + @SetSystemProperty(key = "otel.instrumentation.test.property.string", value = "sys_value") + @Test + void getString_withOpenTelemetry_systemProperty() { + assertString("sys_value"); + } + + @SetEnvironmentVariable(key = "OTEL_INSTRUMENTATION_TEST_PROPERTY_STRING", value = "env_value") + @Test + void getString_withOpenTelemetry_environmentVariable() { + assertString("env_value"); + } + + @Test + void getString_withOpenTelemetry_none() { + assertString(null); + } + + private static void assertString(@Nullable String expected) { + assertThat( + InstrumentationConfigUtil.getOrNull( + ConfigProviderUtil.getConfigProvider(GlobalOpenTelemetry.get()), + config -> config.getString("string"), + "java", + "test", + "property")) + .isEqualTo(expected); + } + + public static Stream stringValuesProvider() { + return Stream.of( + Arguments.of("value1", "value1"), + Arguments.of("", ""), + Arguments.of(null, null), + Arguments.of(123, null), // no type coercion in declarative config + Arguments.of(true, null)); // no type coercion in declarative config + } + + @ParameterizedTest + @MethodSource("stringValuesProvider") + void getString_declarativeConfig(Object property, String expected) { + assertThat( + InstrumentationConfigUtil.getOrNull( + ConfigProviderUtil.getConfigProvider( + DeclarativeConfiguration.create(model(property))), + config -> config.getString("bar"), + "java", + "foo")) + .isEqualTo(expected); + } + + @SetEnvironmentVariable(key = "OTEL_INSTRUMENTATION_TEST_PROPERTY_BOOLEAN", value = "false") + @SetSystemProperty(key = "otel.instrumentation.test.property.boolean", value = "true") + @Test + void getBoolean_systemProperty() { + assertBoolean(true); + } + + @SetEnvironmentVariable(key = "OTEL_INSTRUMENTATION_TEST_PROPERTY_BOOLEAN", value = "true") + @Test + void getBoolean_environmentVariable() { + assertBoolean(true); + } + + @Test + void getBoolean_none() { + assertBoolean(false); + } + + private static void assertBoolean(boolean expected) { + assertThat( + Optional.ofNullable( + InstrumentationConfigUtil.getOrNull( + ConfigProviderUtil.getConfigProvider(GlobalOpenTelemetry.get()), + config -> config.getBoolean("boolean"), + "java", + "test", + "property")) + .orElse(false)) + .isEqualTo(expected); + } + + public static Stream booleanValuesProvider() { + return Stream.of( + Arguments.of(true, true), + Arguments.of(false, false), + Arguments.of("invalid", null), + Arguments.of("true", null), // no type coercion in declarative config + Arguments.of(null, null)); + } + + @ParameterizedTest + @MethodSource("booleanValuesProvider") + void getBoolean_declarativeConfig(@Nullable Object property, @Nullable Boolean expected) { + assertThat( + InstrumentationConfigUtil.getOrNull( + ConfigProviderUtil.getConfigProvider( + DeclarativeConfiguration.create(model(property))), + config -> config.getBoolean("bar"), + "java", + "foo")) + .isEqualTo(expected); + } + + @SetEnvironmentVariable(key = "OTEL_INSTRUMENTATION_TEST_PROPERTY_LIST", value = "a,b,c") + @SetSystemProperty(key = "otel.instrumentation.test.property.list", value = "x,y,z") + @Test + void getList_systemProperty() { + assertList(asList("x", "y", "z")); + } + + @SetEnvironmentVariable(key = "OTEL_INSTRUMENTATION_TEST_PROPERTY_LIST", value = "a,b,c") + @Test + void getList_environmentVariable() { + assertList(asList("a", "b", "c")); + } + + @Test + void getList_none() { + assertList(null); + } + + private static void assertList(@Nullable List expected) { + assertThat( + InstrumentationConfigUtil.>getOrNull( + ConfigProviderUtil.getConfigProvider(OpenTelemetry.noop()), + config -> config.getScalarList("list", String.class), + "java", + "test", + "property")) + .isEqualTo(expected); + } + + public static Stream listValuesProvider() { + return Stream.of( + Arguments.of(asList("a", "b", "c"), asList("a", "b", "c")), + Arguments.of(singletonList("single"), singletonList("single")), + Arguments.of(emptyList(), emptyList()), + Arguments.of("invalid", null), + Arguments.of(null, null)); + } + + @ParameterizedTest + @MethodSource("listValuesProvider") + void getList_declarativeConfig(@Nullable Object property, @Nullable List expected) { + assertThat( + InstrumentationConfigUtil.>getOrNull( + ConfigProviderUtil.getConfigProvider( + DeclarativeConfiguration.create(model(property))), + config -> config.getScalarList("bar", String.class), + "java", + "foo")) + .isEqualTo(expected); + } + + private static OpenTelemetryConfigurationModel model(@Nullable Object value) { + return new DeclarativeConfigurationBuilder() + .customizeModel( + new OpenTelemetryConfigurationModel() + .withFileFormat("1.0-rc.1") + .withInstrumentationDevelopment( + new InstrumentationModel() + .withJava( + new ExperimentalLanguageSpecificInstrumentationModel() + .withAdditionalProperty( + "foo", Collections.singletonMap("bar", value))))); + } +} diff --git a/instrumentation/aws-sdk/aws-sdk-1.11/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v1_11/autoconfigure/TracingRequestHandler.java b/instrumentation/aws-sdk/aws-sdk-1.11/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v1_11/autoconfigure/TracingRequestHandler.java index 06db0aefca91..6a1050eaa46d 100644 --- a/instrumentation/aws-sdk/aws-sdk-1.11/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v1_11/autoconfigure/TracingRequestHandler.java +++ b/instrumentation/aws-sdk/aws-sdk-1.11/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v1_11/autoconfigure/TracingRequestHandler.java @@ -15,7 +15,7 @@ import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.api.incubator.config.InstrumentationConfigUtil; -import io.opentelemetry.instrumentation.api.internal.ConfigPropertiesUtil; +import io.opentelemetry.instrumentation.api.internal.ConfigProviderUtil; import io.opentelemetry.instrumentation.awssdk.v1_11.AwsSdkTelemetry; import java.util.Optional; @@ -27,7 +27,7 @@ public class TracingRequestHandler extends RequestHandler2 { private static final RequestHandler2 DELEGATE = buildDelegate(GlobalOpenTelemetry.get()); private static RequestHandler2 buildDelegate(OpenTelemetry openTelemetry) { - ConfigProvider configProvider = ConfigPropertiesUtil.getConfigProvider(openTelemetry); + ConfigProvider configProvider = ConfigProviderUtil.getConfigProvider(openTelemetry); return AwsSdkTelemetry.builder(openTelemetry) .setCaptureExperimentalSpanAttributes( Optional.ofNullable( diff --git a/instrumentation/aws-sdk/aws-sdk-2.2/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/autoconfigure/AwsSdkSingletons.java b/instrumentation/aws-sdk/aws-sdk-2.2/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/autoconfigure/AwsSdkSingletons.java index 667c9da2c3a2..b3a01c7ed343 100644 --- a/instrumentation/aws-sdk/aws-sdk-2.2/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/autoconfigure/AwsSdkSingletons.java +++ b/instrumentation/aws-sdk/aws-sdk-2.2/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/autoconfigure/AwsSdkSingletons.java @@ -10,7 +10,7 @@ import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.api.incubator.config.InstrumentationConfigUtil; -import io.opentelemetry.instrumentation.api.internal.ConfigPropertiesUtil; +import io.opentelemetry.instrumentation.api.internal.ConfigProviderUtil; import io.opentelemetry.instrumentation.awssdk.v2_2.AwsSdkTelemetry; import io.opentelemetry.instrumentation.awssdk.v2_2.internal.AbstractAwsSdkTelemetryFactory; import java.util.List; @@ -30,7 +30,7 @@ private static class AwsSdkTelemetryFactory extends AbstractAwsSdkTelemetryFacto protected List getCapturedHeaders() { return Optional.ofNullable( InstrumentationConfigUtil.getOrNull( - ConfigPropertiesUtil.getConfigProvider(GlobalOpenTelemetry.get()), + ConfigProviderUtil.getConfigProvider(GlobalOpenTelemetry.get()), config -> config.getScalarList("capture_headers/development", String.class), "java", "messaging")) @@ -50,7 +50,7 @@ protected boolean messagingReceiveInstrumentationEnabled() { @Override protected ConfigProvider getConfigProvider() { - return ConfigPropertiesUtil.getConfigProvider(GlobalOpenTelemetry.get()); + return ConfigProviderUtil.getConfigProvider(GlobalOpenTelemetry.get()); } } diff --git a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/OpenTelemetryDriver.java b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/OpenTelemetryDriver.java index 7a666f8b80fd..ea947fd4a679 100644 --- a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/OpenTelemetryDriver.java +++ b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/OpenTelemetryDriver.java @@ -27,7 +27,7 @@ import io.opentelemetry.api.incubator.config.InstrumentationConfigUtil; import io.opentelemetry.instrumentation.api.incubator.semconv.db.internal.SqlCommenter; import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; -import io.opentelemetry.instrumentation.api.internal.ConfigPropertiesUtil; +import io.opentelemetry.instrumentation.api.internal.ConfigProviderUtil; import io.opentelemetry.instrumentation.api.internal.EmbeddedInstrumentationProperties; import io.opentelemetry.instrumentation.jdbc.internal.DbRequest; import io.opentelemetry.instrumentation.jdbc.internal.JdbcConnectionUrlParser; @@ -67,7 +67,7 @@ public final class OpenTelemetryDriver implements Driver { private static final List DRIVER_CANDIDATES = new CopyOnWriteArrayList<>(); private static SqlCommenter getSqlCommenter(OpenTelemetry openTelemetry) { - ConfigProvider configProvider = ConfigPropertiesUtil.getConfigProvider(openTelemetry); + ConfigProvider configProvider = ConfigProviderUtil.getConfigProvider(openTelemetry); boolean defaultValue = Optional.ofNullable( InstrumentationConfigUtil.getOrNull( diff --git a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/JdbcInstrumenterFactory.java b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/JdbcInstrumenterFactory.java index 19ea5adfeb17..a77f8d912041 100644 --- a/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/JdbcInstrumenterFactory.java +++ b/instrumentation/jdbc/library/src/main/java/io/opentelemetry/instrumentation/jdbc/internal/JdbcInstrumenterFactory.java @@ -17,7 +17,7 @@ import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor; import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter; import io.opentelemetry.instrumentation.api.instrumenter.SpanKindExtractor; -import io.opentelemetry.instrumentation.api.internal.ConfigPropertiesUtil; +import io.opentelemetry.instrumentation.api.internal.ConfigProviderUtil; import io.opentelemetry.instrumentation.jdbc.internal.dbinfo.DbInfo; import java.util.List; import java.util.Optional; @@ -33,7 +33,7 @@ public final class JdbcInstrumenterFactory { public static boolean captureQueryParameters(OpenTelemetry openTelemetry) { return Optional.ofNullable( InstrumentationConfigUtil.getOrNull( - ConfigPropertiesUtil.getConfigProvider(openTelemetry), + ConfigProviderUtil.getConfigProvider(openTelemetry), config -> config.getBoolean("capture_query_parameters/development"), "java", "jdbc")) @@ -53,7 +53,7 @@ static Instrumenter createStatementInstrumenter( true, Optional.ofNullable( InstrumentationConfigUtil.getOrNull( - ConfigPropertiesUtil.getConfigProvider(openTelemetry), + ConfigProviderUtil.getConfigProvider(openTelemetry), config -> config.getBoolean("enabled"), "java", "common", @@ -109,7 +109,7 @@ public static Instrumenter createTransactionInstrumenter( openTelemetry, Optional.ofNullable( InstrumentationConfigUtil.getOrNull( - ConfigPropertiesUtil.getConfigProvider(openTelemetry), + ConfigProviderUtil.getConfigProvider(openTelemetry), config -> config.getBoolean("enabled"), "java", "jdbc", diff --git a/instrumentation/kafka/kafka-clients/kafka-clients-2.6/library/src/main/java/io/opentelemetry/instrumentation/kafkaclients/v2_6/TracingConsumerInterceptor.java b/instrumentation/kafka/kafka-clients/kafka-clients-2.6/library/src/main/java/io/opentelemetry/instrumentation/kafkaclients/v2_6/TracingConsumerInterceptor.java index 5de47fce39b5..15f1d309a7b7 100644 --- a/instrumentation/kafka/kafka-clients/kafka-clients-2.6/library/src/main/java/io/opentelemetry/instrumentation/kafkaclients/v2_6/TracingConsumerInterceptor.java +++ b/instrumentation/kafka/kafka-clients/kafka-clients-2.6/library/src/main/java/io/opentelemetry/instrumentation/kafkaclients/v2_6/TracingConsumerInterceptor.java @@ -13,7 +13,7 @@ import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.api.incubator.config.InstrumentationConfigUtil; import io.opentelemetry.context.Context; -import io.opentelemetry.instrumentation.api.internal.ConfigPropertiesUtil; +import io.opentelemetry.instrumentation.api.internal.ConfigProviderUtil; import io.opentelemetry.instrumentation.api.internal.Timer; import io.opentelemetry.instrumentation.kafkaclients.common.v0_11.internal.KafkaConsumerContext; import io.opentelemetry.instrumentation.kafkaclients.common.v0_11.internal.KafkaConsumerContextUtil; @@ -40,7 +40,7 @@ public class TracingConsumerInterceptor implements ConsumerInterceptor implements ProducerInterceptor config.getScalarList("capture_headers/development", String.class), "java", diff --git a/instrumentation/log4j/log4j-context-data/log4j-context-data-2.17/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/log4j/contextdata/v2_17/OpenTelemetryContextDataProvider.java b/instrumentation/log4j/log4j-context-data/log4j-context-data-2.17/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/log4j/contextdata/v2_17/OpenTelemetryContextDataProvider.java index 752eea199e46..3421afe3e291 100644 --- a/instrumentation/log4j/log4j-context-data/log4j-context-data-2.17/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/log4j/contextdata/v2_17/OpenTelemetryContextDataProvider.java +++ b/instrumentation/log4j/log4j-context-data/log4j-context-data-2.17/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/log4j/contextdata/v2_17/OpenTelemetryContextDataProvider.java @@ -12,7 +12,7 @@ import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.SpanContext; import io.opentelemetry.context.Context; -import io.opentelemetry.instrumentation.api.internal.ConfigPropertiesUtil; +import io.opentelemetry.instrumentation.api.internal.ConfigProviderUtil; import io.opentelemetry.instrumentation.log4j.contextdata.v2_17.internal.ContextDataKeys; import io.opentelemetry.javaagent.bootstrap.internal.ConfiguredResourceAttributesHolder; import java.util.Collections; @@ -30,7 +30,7 @@ public class OpenTelemetryContextDataProvider implements ContextDataProvider { private static final boolean BAGGAGE_ENABLED = Optional.ofNullable( InstrumentationConfigUtil.getOrNull( - ConfigPropertiesUtil.getConfigProvider(GlobalOpenTelemetry.get()), + ConfigProviderUtil.getConfigProvider(GlobalOpenTelemetry.get()), config -> config.getBoolean("add_baggage"), "java", "log4j_context_data")) diff --git a/instrumentation/log4j/log4j-context-data/log4j-context-data-2.17/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/log4j/contextdata/v2_17/internal/ContextDataKeys.java b/instrumentation/log4j/log4j-context-data/log4j-context-data-2.17/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/log4j/contextdata/v2_17/internal/ContextDataKeys.java index ed471c1a155a..f75705e60112 100644 --- a/instrumentation/log4j/log4j-context-data/log4j-context-data-2.17/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/log4j/contextdata/v2_17/internal/ContextDataKeys.java +++ b/instrumentation/log4j/log4j-context-data/log4j-context-data-2.17/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/log4j/contextdata/v2_17/internal/ContextDataKeys.java @@ -6,25 +6,33 @@ package io.opentelemetry.instrumentation.log4j.contextdata.v2_17.internal; import io.opentelemetry.api.GlobalOpenTelemetry; +import io.opentelemetry.api.incubator.config.InstrumentationConfigUtil; import io.opentelemetry.instrumentation.api.incubator.log.LoggingContextConstants; -import io.opentelemetry.instrumentation.api.internal.ConfigPropertiesUtil; +import io.opentelemetry.instrumentation.api.internal.ConfigProviderUtil; +import java.util.Optional; /** * This class is internal and is hence not for public use. Its APIs are unstable and can change at * any time. */ public final class ContextDataKeys { - public static final String TRACE_ID_KEY = - ConfigPropertiesUtil.getString(GlobalOpenTelemetry.get(), "common", "logging", "trace_id") - .orElse(LoggingContextConstants.TRACE_ID); + public static final String TRACE_ID_KEY = get("trace_id", LoggingContextConstants.TRACE_ID); - public static final String SPAN_ID_KEY = - ConfigPropertiesUtil.getString(GlobalOpenTelemetry.get(), "common", "logging", "span_id") - .orElse(LoggingContextConstants.SPAN_ID); + public static final String SPAN_ID_KEY = get("span_id", LoggingContextConstants.SPAN_ID); public static final String TRACE_FLAGS_KEY = - ConfigPropertiesUtil.getString(GlobalOpenTelemetry.get(), "common", "logging", "trace_flags") - .orElse(LoggingContextConstants.TRACE_FLAGS); + get("trace_flags", LoggingContextConstants.TRACE_FLAGS); + + private static String get(String traceId, String defaultValue) { + return Optional.ofNullable( + InstrumentationConfigUtil.getOrNull( + ConfigProviderUtil.getConfigProvider(GlobalOpenTelemetry.get()), + config -> config.getString(traceId), + "java", + "common", + "logging")) + .orElse(defaultValue); + } private ContextDataKeys() {} } diff --git a/instrumentation/servlet/servlet-common/bootstrap/build.gradle.kts b/instrumentation/servlet/servlet-common/bootstrap/build.gradle.kts index 072a96df450f..edd4ca6cf31c 100644 --- a/instrumentation/servlet/servlet-common/bootstrap/build.gradle.kts +++ b/instrumentation/servlet/servlet-common/bootstrap/build.gradle.kts @@ -1,3 +1,7 @@ plugins { id("otel.javaagent-bootstrap") } + +dependencies { + compileOnly("io.opentelemetry:opentelemetry-api-incubator") +} diff --git a/instrumentation/servlet/servlet-common/bootstrap/src/main/java/io/opentelemetry/javaagent/bootstrap/servlet/ExperimentalSnippetHolder.java b/instrumentation/servlet/servlet-common/bootstrap/src/main/java/io/opentelemetry/javaagent/bootstrap/servlet/ExperimentalSnippetHolder.java index 8f71ad931065..0d39a5d71563 100644 --- a/instrumentation/servlet/servlet-common/bootstrap/src/main/java/io/opentelemetry/javaagent/bootstrap/servlet/ExperimentalSnippetHolder.java +++ b/instrumentation/servlet/servlet-common/bootstrap/src/main/java/io/opentelemetry/javaagent/bootstrap/servlet/ExperimentalSnippetHolder.java @@ -8,7 +8,9 @@ import static java.util.logging.Level.WARNING; import io.opentelemetry.api.GlobalOpenTelemetry; +import io.opentelemetry.api.incubator.config.InstrumentationConfigUtil; import io.opentelemetry.instrumentation.api.internal.ConfigPropertiesUtil; +import io.opentelemetry.instrumentation.api.internal.ConfigProviderUtil; import java.util.Optional; import java.util.logging.Logger; @@ -24,8 +26,12 @@ public class ExperimentalSnippetHolder { private static String getSnippetSetting() { Optional snippet = - ConfigPropertiesUtil.getString( - GlobalOpenTelemetry.get(), "servlet", "javascript-snippet/development"); + Optional.ofNullable( + InstrumentationConfigUtil.getOrNull( + ConfigProviderUtil.getConfigProvider(GlobalOpenTelemetry.get()), + config -> config.getString("javascript-snippet/development"), + "java", + "servlet")); // Can remove deprecated fallback in 2.24.0 return snippet.orElseGet( () -> { From 7799b4825d3577073759222ee47e37ae414950b7 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Fri, 12 Dec 2025 19:44:06 +0100 Subject: [PATCH 63/79] simplify --- .../api/internal/ConfigProviderUtil.java | 17 +---------------- 1 file changed, 1 insertion(+), 16 deletions(-) diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigProviderUtil.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigProviderUtil.java index 532e7898614e..69d1be76dc63 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigProviderUtil.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigProviderUtil.java @@ -22,25 +22,10 @@ protected AbstractBridgedDeclarativeConfigProperties getProperties(String name) return new SystemPropertiesDeclarativeConfigProperties(name, null); } }; - private static final boolean supportsDeclarativeConfig = supportsDeclarativeConfig(); - - private static boolean supportsDeclarativeConfig() { - try { - Class.forName("io.opentelemetry.api.incubator.ExtendedOpenTelemetry"); - return true; - } catch (ClassNotFoundException e) { - // The incubator module is not available. - // This only happens in OpenTelemetry API instrumentation tests, where an older version of - // OpenTelemetry API is used that does not have ExtendedOpenTelemetry. - // Having the incubator module without ExtendedOpenTelemetry class should still return false - // for those tests to avoid a ClassNotFoundException. - return false; - } - } /** Returns true if the given OpenTelemetry instance supports Declarative Config. */ public static boolean isDeclarativeConfig(OpenTelemetry openTelemetry) { - return supportsDeclarativeConfig && openTelemetry instanceof ExtendedOpenTelemetry; + return openTelemetry instanceof ExtendedOpenTelemetry; } public static ConfigProvider getConfigProvider(OpenTelemetry openTelemetry) { From 0264b54620b80136e3a80125404fa5fb7ae0f5eb Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Fri, 12 Dec 2025 20:02:00 +0100 Subject: [PATCH 64/79] fix --- .../config/internal/CommonConfig.java | 6 ++--- .../properties/ConfigPropertiesBridge.java | 9 ++++++-- .../javaagent/tooling/AgentInstaller.java | 22 +++++++++---------- .../config/ConfigPropertiesBridge.java | 8 +++---- 4 files changed, 25 insertions(+), 20 deletions(-) diff --git a/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/config/internal/CommonConfig.java b/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/config/internal/CommonConfig.java index d273706143ce..1a0e5b3f66d5 100644 --- a/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/config/internal/CommonConfig.java +++ b/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/config/internal/CommonConfig.java @@ -16,6 +16,7 @@ import java.util.ArrayList; import java.util.HashSet; import java.util.List; +import java.util.Objects; import java.util.Set; import java.util.function.Supplier; import javax.annotation.Nullable; @@ -175,9 +176,8 @@ private static T getFromConfigProviderOrFallback( ValueProvider getFromConfigProvider, T defaultValue, Supplier fallback) { - ConfigProvider configProvider = config.getConfigProvider(); - if (config.isDeclarative() && configProvider != null) { - T value = getFromConfigProvider.get(configProvider); + if (config.isDeclarative()) { + T value = getFromConfigProvider.get(config.getConfigProvider()); return value != null ? value : defaultValue; } // fallback doesn't return null, so we can safely call it diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/properties/ConfigPropertiesBridge.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/properties/ConfigPropertiesBridge.java index 44f8cbac8487..29dd771d03e7 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/properties/ConfigPropertiesBridge.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/properties/ConfigPropertiesBridge.java @@ -28,10 +28,15 @@ public final class ConfigPropertiesBridge implements InstrumentationConfig { private final ConfigProperties configProperties; private final ConfigProvider configProvider; + private final boolean isDeclarativeConfig; - public ConfigPropertiesBridge(ConfigProperties configProperties, ConfigProvider configProvider) { + public ConfigPropertiesBridge( + ConfigProperties configProperties, + ConfigProvider configProvider, + boolean isDeclarativeConfig) { this.configProperties = configProperties; this.configProvider = configProvider; + this.isDeclarativeConfig = isDeclarativeConfig; } @Nullable @@ -118,7 +123,7 @@ public Map getMap(String name, Map defaultValue) @Override public boolean isDeclarative() { - return configProvider != null; + return isDeclarativeConfig; } @Override diff --git a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/AgentInstaller.java b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/AgentInstaller.java index a7743566fe22..a008376782ac 100644 --- a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/AgentInstaller.java +++ b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/AgentInstaller.java @@ -19,6 +19,7 @@ import io.opentelemetry.context.Context; import io.opentelemetry.context.ContextStorage; import io.opentelemetry.context.Scope; +import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; import io.opentelemetry.instrumentation.api.internal.EmbeddedInstrumentationProperties; import io.opentelemetry.instrumentation.config.bridge.ConfigPropertiesDeclarativeConfigProperties; import io.opentelemetry.javaagent.bootstrap.AgentClassLoader; @@ -78,7 +79,6 @@ import net.bytebuddy.dynamic.scaffold.InstrumentedType; import net.bytebuddy.dynamic.scaffold.MethodGraph; import net.bytebuddy.utility.JavaModule; -import org.jetbrains.annotations.NotNull; public class AgentInstaller { @@ -171,7 +171,7 @@ private static void installBytebuddyAgent( ConfigProperties sdkConfig = AutoConfigureUtil.getConfig(autoConfiguredSdk); AgentInstrumentationConfig.internalInitializeConfig( - getConfigPropertiesBridge(autoConfiguredSdk, sdkConfig)); + getInstrumentationConfig(autoConfiguredSdk, sdkConfig)); copyNecessaryConfigToSystemProperties(sdkConfig); setBootstrapPackages(sdkConfig, extensionClassLoader); @@ -230,18 +230,18 @@ private static void installBytebuddyAgent( runAfterAgentListeners(agentListeners, autoConfiguredSdk, sdkConfig); } - @NotNull - private static ConfigPropertiesBridge getConfigPropertiesBridge( + private static InstrumentationConfig getInstrumentationConfig( AutoConfiguredOpenTelemetrySdk autoConfiguredSdk, ConfigProperties sdkConfig) { - ConfigProvider configProvider = AutoConfigureUtil.getConfigProvider(autoConfiguredSdk); + ConfigProvider originalProvider = AutoConfigureUtil.getConfigProvider(autoConfiguredSdk); - return new ConfigPropertiesBridge( - sdkConfig, - configProvider != null - ? configProvider + boolean isDeclarativeConfig = originalProvider != null; + // use the bridge only if the configuration is not already declarative + ConfigProvider provider = + isDeclarativeConfig + ? originalProvider : ConfigPropertiesDeclarativeConfigProperties.create( - AutoConfigureUtil.getConfig(autoConfiguredSdk)), - configProvider != null); + AutoConfigureUtil.getConfig(autoConfiguredSdk)); + return new ConfigPropertiesBridge(sdkConfig, provider, isDeclarativeConfig); } private static AgentBuilder newAgentBuilder(ByteBuddy byteBuddy) { diff --git a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/ConfigPropertiesBridge.java b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/ConfigPropertiesBridge.java index dd22d6e2b37c..43a36e33b237 100644 --- a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/ConfigPropertiesBridge.java +++ b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/ConfigPropertiesBridge.java @@ -22,15 +22,15 @@ public final class ConfigPropertiesBridge implements InstrumentationConfig { private final ConfigProperties configProperties; private final ConfigProvider configProvider; - private final boolean useDeclarativeConfig; + private final boolean isDeclarativeConfig; public ConfigPropertiesBridge( ConfigProperties configProperties, ConfigProvider configProvider, - boolean useDeclarativeConfig) { + boolean isDeclarativeConfig) { this.configProperties = configProperties; this.configProvider = configProvider; - this.useDeclarativeConfig = useDeclarativeConfig; + this.isDeclarativeConfig = isDeclarativeConfig; } @Nullable @@ -117,7 +117,7 @@ public Map getMap(String name, Map defaultValue) @Override public boolean isDeclarative() { - return useDeclarativeConfig; + return isDeclarativeConfig; } @Override From 916479726a02eaf4c0f7a3810e3da5cec6b04de8 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Fri, 12 Dec 2025 20:07:19 +0100 Subject: [PATCH 65/79] fix --- .../api/incubator/config/internal/CommonConfig.java | 1 - .../instrumentation/api/internal/ConfigProviderUtil.java | 2 ++ 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/config/internal/CommonConfig.java b/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/config/internal/CommonConfig.java index 1a0e5b3f66d5..4bbdd9335a5a 100644 --- a/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/config/internal/CommonConfig.java +++ b/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/config/internal/CommonConfig.java @@ -16,7 +16,6 @@ import java.util.ArrayList; import java.util.HashSet; import java.util.List; -import java.util.Objects; import java.util.Set; import java.util.function.Supplier; import javax.annotation.Nullable; diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigProviderUtil.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigProviderUtil.java index 69d1be76dc63..823f9b32cd7d 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigProviderUtil.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigProviderUtil.java @@ -34,4 +34,6 @@ public static ConfigProvider getConfigProvider(OpenTelemetry openTelemetry) { } return BRIDGED_CONFIG_PROVIDER; } + + private ConfigProviderUtil() {} } From 30f19439e4596c450d1459dbad7f773b92be2ecb Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Fri, 12 Dec 2025 20:18:59 +0100 Subject: [PATCH 66/79] cleanup --- .../config/internal/InstrumentationConfig.java | 12 +++++++++++- .../internal/properties/ConfigPropertiesBridge.java | 11 ----------- .../internal/EmptyInstrumentationConfig.java | 6 ------ .../tooling/config/ConfigPropertiesBridge.java | 11 ----------- 4 files changed, 11 insertions(+), 29 deletions(-) diff --git a/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/config/internal/InstrumentationConfig.java b/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/config/internal/InstrumentationConfig.java index a17195f50658..5098e75505af 100644 --- a/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/config/internal/InstrumentationConfig.java +++ b/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/config/internal/InstrumentationConfig.java @@ -5,10 +5,12 @@ package io.opentelemetry.instrumentation.api.incubator.config.internal; +import static io.opentelemetry.api.incubator.config.DeclarativeConfigProperties.empty; import static java.util.Collections.emptyList; import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; +import io.opentelemetry.api.incubator.config.InstrumentationConfigUtil; import java.time.Duration; import java.util.List; import java.util.Map; @@ -127,7 +129,15 @@ default List getList(String name) { * @return the declarative configuration properties for the given node name * @throws IllegalStateException if {@link #isDeclarative()} returns {@code false} */ - DeclarativeConfigProperties getDeclarativeConfig(String node); + default DeclarativeConfigProperties getDeclarativeConfig(String node) { + DeclarativeConfigProperties config = + InstrumentationConfigUtil.javaInstrumentationConfig(getConfigProvider(), node); + if (config == null) { + // there is no declarative config for this node + return empty(); + } + return config; + } /** * Returns the {@link ConfigProvider}, which is a bridge to ConfigProperties if declarative diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/properties/ConfigPropertiesBridge.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/properties/ConfigPropertiesBridge.java index 29dd771d03e7..e75b3f294cc0 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/properties/ConfigPropertiesBridge.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/properties/ConfigPropertiesBridge.java @@ -126,17 +126,6 @@ public boolean isDeclarative() { return isDeclarativeConfig; } - @Override - public DeclarativeConfigProperties getDeclarativeConfig(String node) { - DeclarativeConfigProperties config = - InstrumentationConfigUtil.javaInstrumentationConfig(configProvider, node); - if (config == null) { - // there is no declarative config for this node - return empty(); - } - return config; - } - @Override public ConfigProvider getConfigProvider() { return configProvider; diff --git a/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/bootstrap/internal/EmptyInstrumentationConfig.java b/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/bootstrap/internal/EmptyInstrumentationConfig.java index 083ebf67fbdd..276a87f0b1e5 100644 --- a/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/bootstrap/internal/EmptyInstrumentationConfig.java +++ b/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/bootstrap/internal/EmptyInstrumentationConfig.java @@ -66,12 +66,6 @@ public boolean isDeclarative() { return false; } - @Override - public DeclarativeConfigProperties getDeclarativeConfig(String node) { - throw new IllegalStateException( - "Declarative configuration is not supported in the empty instrumentation config"); - } - @Override public ConfigProvider getConfigProvider() { return ConfigProvider.noop(); diff --git a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/ConfigPropertiesBridge.java b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/ConfigPropertiesBridge.java index 43a36e33b237..0ae316fb1607 100644 --- a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/ConfigPropertiesBridge.java +++ b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/ConfigPropertiesBridge.java @@ -120,17 +120,6 @@ public boolean isDeclarative() { return isDeclarativeConfig; } - @Override - public DeclarativeConfigProperties getDeclarativeConfig(String node) { - DeclarativeConfigProperties config = - InstrumentationConfigUtil.javaInstrumentationConfig(configProvider, node); - if (config == null) { - // there is no declarative config for this node - return empty(); - } - return config; - } - @Nullable @Override public ConfigProvider getConfigProvider() { From 2d2ed1a740a1c280ef691661fcee09f875468f62 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Fri, 12 Dec 2025 20:25:12 +0100 Subject: [PATCH 67/79] use bridge --- .../config/internal/InstrumentationConfig.java | 4 +--- .../ExternalAnnotationInstrumentation.java | 11 ++++------- 2 files changed, 5 insertions(+), 10 deletions(-) diff --git a/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/config/internal/InstrumentationConfig.java b/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/config/internal/InstrumentationConfig.java index 5098e75505af..26431c97baaa 100644 --- a/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/config/internal/InstrumentationConfig.java +++ b/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/config/internal/InstrumentationConfig.java @@ -117,9 +117,8 @@ default List getList(String name) { /** * Returns a {@link DeclarativeConfigProperties} for the given node name, which is usually an - * instrumentation name + * instrumentation name. If declarative configuration is not used, a bridge to ConfigProperties is * - *

Call {@link #isDeclarative()} first to check if declarative configuration is used. * *

Declarative configuration is used to configure instrumentation properties in a declarative * way, such as through YAML or JSON files. @@ -127,7 +126,6 @@ default List getList(String name) { * @param node the name of the instrumentation (e.g. "log4j"), the vendor name (e.g. "google"), or * "common" for common Java settings that don't apply to other languages. * @return the declarative configuration properties for the given node name - * @throws IllegalStateException if {@link #isDeclarative()} returns {@code false} */ default DeclarativeConfigProperties getDeclarativeConfig(String node) { DeclarativeConfigProperties config = diff --git a/instrumentation/external-annotations/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/extannotations/ExternalAnnotationInstrumentation.java b/instrumentation/external-annotations/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/extannotations/ExternalAnnotationInstrumentation.java index 5c39fc2bcbb2..0386a4865c1e 100644 --- a/instrumentation/external-annotations/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/extannotations/ExternalAnnotationInstrumentation.java +++ b/instrumentation/external-annotations/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/extannotations/ExternalAnnotationInstrumentation.java @@ -67,11 +67,6 @@ public class ExternalAnnotationInstrumentation implements TypeInstrumentation { "kamon.annotation.api.Trace", "org.springframework.cloud.sleuth.annotation.NewSpan"); - private static final String TRACE_ANNOTATIONS_CONFIG = - "otel.instrumentation.external-annotations.include"; - private static final String TRACE_ANNOTATED_METHODS_EXCLUDE_CONFIG = - "otel.instrumentation.external-annotations.exclude-methods"; - private final ElementMatcher.Junction classLoaderOptimization; private final ElementMatcher.Junction traceAnnotationMatcher; @@ -116,7 +111,7 @@ public void transform(TypeTransformer transformer) { // visible for testing static Set configureAdditionalTraceAnnotations(InstrumentationConfig config) { - String configString = config.getString(TRACE_ANNOTATIONS_CONFIG); + String configString = config.getDeclarativeConfig("external-annotations").getString("include"); if (configString == null) { return Collections.unmodifiableSet(new HashSet<>(DEFAULT_ANNOTATIONS)); } else if (configString.isEmpty()) { @@ -148,7 +143,9 @@ private static ElementMatcher.Junction configureExcludedMetho Map> excludedMethods = MethodsConfigurationParser.parse( - AgentInstrumentationConfig.get().getString(TRACE_ANNOTATED_METHODS_EXCLUDE_CONFIG)); + AgentInstrumentationConfig.get() + .getDeclarativeConfig("external-annotations") + .getString("exclude-methods")); for (Map.Entry> entry : excludedMethods.entrySet()) { String className = entry.getKey(); ElementMatcher.Junction classMather = From c2a048aa2497ab442936deceb4c4c2d466fba182 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Fri, 12 Dec 2025 20:33:09 +0100 Subject: [PATCH 68/79] use bridge --- .../config/internal/InstrumentationConfig.java | 1 - .../OpenTelemetryAutoConfiguration.java | 8 ++++---- .../properties/ConfigPropertiesBridge.java | 4 ---- .../SchedulingInstrumentationAspectTest.java | 11 ++--------- ...dulingInstrumentationAutoConfigurationTest.java | 12 ++---------- ...ebfluxInstrumentationAutoConfigurationTest.java | 12 ++---------- ...ebMvcInstrumentation5AutoConfigurationTest.java | 12 ++---------- ...ClientInstrumentationAutoConfigurationTest.java | 3 ++- ...ebMvcInstrumentation6AutoConfigurationTest.java | 3 ++- ...ctJdbcInstrumentationAutoConfigurationTest.java | 11 ++--------- ...tKafkaInstrumentationAutoConfigurationTest.java | 14 ++++++++------ ...tR2DbcInstrumentationAutoConfigurationTest.java | 12 ++---------- ...ingWebInstrumentationAutoConfigurationTest.java | 12 ++---------- .../internal/EmptyInstrumentationConfig.java | 1 - .../tooling/config/ConfigPropertiesBridge.java | 4 ---- 15 files changed, 30 insertions(+), 90 deletions(-) diff --git a/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/config/internal/InstrumentationConfig.java b/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/config/internal/InstrumentationConfig.java index 26431c97baaa..8d79ecb95b06 100644 --- a/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/config/internal/InstrumentationConfig.java +++ b/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/config/internal/InstrumentationConfig.java @@ -119,7 +119,6 @@ default List getList(String name) { * Returns a {@link DeclarativeConfigProperties} for the given node name, which is usually an * instrumentation name. If declarative configuration is not used, a bridge to ConfigProperties is * - * *

Declarative configuration is used to configure instrumentation properties in a declarative * way, such as through YAML or JSON files. * diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/OpenTelemetryAutoConfiguration.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/OpenTelemetryAutoConfiguration.java index 7e6af32fdb9c..15d04219271e 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/OpenTelemetryAutoConfiguration.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/OpenTelemetryAutoConfiguration.java @@ -153,7 +153,7 @@ public ConfigProvider configProvider(ConfigProperties properties) { @Bean public InstrumentationConfig instrumentationConfig( ConfigProperties properties, ConfigProvider configProvider) { - return new ConfigPropertiesBridge(properties, configProvider); + return new ConfigPropertiesBridge(properties, configProvider, false); } } @@ -198,7 +198,7 @@ public ConfigProperties otelProperties(ConfigProvider configProvider) { @Bean public InstrumentationConfig instrumentationConfig( ConfigProperties properties, ConfigProvider configProvider) { - return new ConfigPropertiesBridge(properties, configProvider); + return new ConfigPropertiesBridge(properties, configProvider, true); } @Bean @@ -245,7 +245,7 @@ public ConfigProvider configProvider() { @Bean public InstrumentationConfig instrumentationConfig( ConfigProperties properties, ConfigProvider configProvider) { - return new ConfigPropertiesBridge(properties, configProvider); + return new ConfigPropertiesBridge(properties, configProvider, false); } @Configuration @@ -292,7 +292,7 @@ static class FallbackInstrumentationConfig { @Bean public InstrumentationConfig instrumentationConfig( ConfigProperties properties, ConfigProvider configProvider) { - return new ConfigPropertiesBridge(properties, configProvider); + return new ConfigPropertiesBridge(properties, configProvider, false); } } diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/properties/ConfigPropertiesBridge.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/properties/ConfigPropertiesBridge.java index e75b3f294cc0..1ed3c97f675b 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/properties/ConfigPropertiesBridge.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/properties/ConfigPropertiesBridge.java @@ -5,11 +5,7 @@ package io.opentelemetry.instrumentation.spring.autoconfigure.internal.properties; -import static io.opentelemetry.api.incubator.config.DeclarativeConfigProperties.empty; - import io.opentelemetry.api.incubator.config.ConfigProvider; -import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; -import io.opentelemetry.api.incubator.config.InstrumentationConfigUtil; import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/scheduling/SchedulingInstrumentationAspectTest.java b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/scheduling/SchedulingInstrumentationAspectTest.java index 28151745ebf4..6cc872c3b9b7 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/scheduling/SchedulingInstrumentationAspectTest.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/scheduling/SchedulingInstrumentationAspectTest.java @@ -6,22 +6,19 @@ package io.opentelemetry.instrumentation.spring.autoconfigure.internal.instrumentation.scheduling; import static io.opentelemetry.api.trace.SpanKind.INTERNAL; +import static io.opentelemetry.instrumentation.spring.autoconfigure.internal.AbstractKafkaInstrumentationAutoConfigurationTest.EMPTY_INSTRUMENTATION_CONFIG; import static org.assertj.core.api.Assertions.assertThatThrownBy; import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.api.trace.Span; import io.opentelemetry.api.trace.Tracer; import io.opentelemetry.context.Context; import io.opentelemetry.context.Scope; import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; -import io.opentelemetry.instrumentation.spring.autoconfigure.internal.properties.ConfigPropertiesBridge; import io.opentelemetry.instrumentation.testing.junit.LibraryInstrumentationExtension; import io.opentelemetry.instrumentation.testing.junit.code.SemconvCodeStabilityUtil; -import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; import io.opentelemetry.sdk.testing.assertj.AttributeAssertion; import io.opentelemetry.sdk.trace.data.StatusData; -import java.util.Collections; import java.util.List; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.DisplayName; @@ -56,11 +53,7 @@ void setup() { factory.setTarget(unproxiedTester); SpringSchedulingInstrumentationAspect aspect = - newAspect( - testing.getOpenTelemetry(), - new ConfigPropertiesBridge( - DefaultConfigProperties.createFromMap(Collections.emptyMap()), - ConfigProvider.noop())); + newAspect(testing.getOpenTelemetry(), EMPTY_INSTRUMENTATION_CONFIG); factory.addAspect(aspect); schedulingTester = factory.getProxy(); diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/scheduling/SchedulingInstrumentationAutoConfigurationTest.java b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/scheduling/SchedulingInstrumentationAutoConfigurationTest.java index caa10eeadcc0..43b5b911f421 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/scheduling/SchedulingInstrumentationAutoConfigurationTest.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/scheduling/SchedulingInstrumentationAutoConfigurationTest.java @@ -5,14 +5,11 @@ package io.opentelemetry.instrumentation.spring.autoconfigure.internal.instrumentation.scheduling; +import static io.opentelemetry.instrumentation.spring.autoconfigure.internal.AbstractKafkaInstrumentationAutoConfigurationTest.EMPTY_INSTRUMENTATION_CONFIG; import static org.assertj.core.api.Assertions.assertThat; import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; -import io.opentelemetry.instrumentation.spring.autoconfigure.internal.properties.ConfigPropertiesBridge; -import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; -import java.util.Collections; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.runner.ApplicationContextRunner; @@ -21,12 +18,7 @@ class SchedulingInstrumentationAutoConfigurationTest { private final ApplicationContextRunner runner = new ApplicationContextRunner() .withBean(OpenTelemetry.class, OpenTelemetry::noop) - .withBean( - InstrumentationConfig.class, - () -> - new ConfigPropertiesBridge( - DefaultConfigProperties.createFromMap(Collections.emptyMap()), - ConfigProvider.noop())) + .withBean(InstrumentationConfig.class, () -> EMPTY_INSTRUMENTATION_CONFIG) .withConfiguration( AutoConfigurations.of(SpringSchedulingInstrumentationAutoConfiguration.class)); diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webflux/SpringWebfluxInstrumentationAutoConfigurationTest.java b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webflux/SpringWebfluxInstrumentationAutoConfigurationTest.java index 7e5585fdf151..52ecd59e72b5 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webflux/SpringWebfluxInstrumentationAutoConfigurationTest.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webflux/SpringWebfluxInstrumentationAutoConfigurationTest.java @@ -5,14 +5,11 @@ package io.opentelemetry.instrumentation.spring.autoconfigure.internal.instrumentation.webflux; +import static io.opentelemetry.instrumentation.spring.autoconfigure.internal.AbstractKafkaInstrumentationAutoConfigurationTest.EMPTY_INSTRUMENTATION_CONFIG; import static org.assertj.core.api.Assertions.assertThat; import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; -import io.opentelemetry.instrumentation.spring.autoconfigure.internal.properties.ConfigPropertiesBridge; -import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; -import java.util.Collections; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.runner.ApplicationContextRunner; @@ -22,12 +19,7 @@ class SpringWebfluxInstrumentationAutoConfigurationTest { private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() .withBean(OpenTelemetry.class, OpenTelemetry::noop) - .withBean( - InstrumentationConfig.class, - () -> - new ConfigPropertiesBridge( - DefaultConfigProperties.createFromMap(Collections.emptyMap()), - ConfigProvider.noop())) + .withBean(InstrumentationConfig.class, () -> EMPTY_INSTRUMENTATION_CONFIG) .withConfiguration( AutoConfigurations.of(SpringWebfluxInstrumentationAutoConfiguration.class)); diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webmvc/SpringWebMvcInstrumentation5AutoConfigurationTest.java b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webmvc/SpringWebMvcInstrumentation5AutoConfigurationTest.java index e331a17172b2..296f4961a8af 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webmvc/SpringWebMvcInstrumentation5AutoConfigurationTest.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webmvc/SpringWebMvcInstrumentation5AutoConfigurationTest.java @@ -5,15 +5,12 @@ package io.opentelemetry.instrumentation.spring.autoconfigure.internal.instrumentation.webmvc; +import static io.opentelemetry.instrumentation.spring.autoconfigure.internal.AbstractKafkaInstrumentationAutoConfigurationTest.EMPTY_INSTRUMENTATION_CONFIG; import static org.assertj.core.api.Assertions.assertThat; import static org.junit.jupiter.api.Assumptions.assumeFalse; import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; -import io.opentelemetry.instrumentation.spring.autoconfigure.internal.properties.ConfigPropertiesBridge; -import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; -import java.util.Collections; import javax.servlet.Filter; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -25,12 +22,7 @@ class SpringWebMvcInstrumentation5AutoConfigurationTest { private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() .withBean(OpenTelemetry.class, OpenTelemetry::noop) - .withBean( - InstrumentationConfig.class, - () -> - new ConfigPropertiesBridge( - DefaultConfigProperties.createFromMap(Collections.emptyMap()), - ConfigProvider.noop())) + .withBean(InstrumentationConfig.class, () -> EMPTY_INSTRUMENTATION_CONFIG) .withConfiguration( AutoConfigurations.of(SpringWebMvc5InstrumentationAutoConfiguration.class)); diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/testSpring3/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/web/RestClientInstrumentationAutoConfigurationTest.java b/instrumentation/spring/spring-boot-autoconfigure/src/testSpring3/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/web/RestClientInstrumentationAutoConfigurationTest.java index 8745c0830bc0..8eda7e82a1bb 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/testSpring3/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/web/RestClientInstrumentationAutoConfigurationTest.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/testSpring3/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/web/RestClientInstrumentationAutoConfigurationTest.java @@ -28,7 +28,8 @@ class RestClientInstrumentationAutoConfigurationTest { () -> new ConfigPropertiesBridge( DefaultConfigProperties.createFromMap(Collections.emptyMap()), - ConfigProvider.noop())) + ConfigProvider.noop(), + false)) .withBean(RestClient.class, RestClient::create) .withConfiguration( AutoConfigurations.of(RestClientInstrumentationAutoConfiguration.class)); diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/testSpring3/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webmvc/SpringWebMvcInstrumentation6AutoConfigurationTest.java b/instrumentation/spring/spring-boot-autoconfigure/src/testSpring3/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webmvc/SpringWebMvcInstrumentation6AutoConfigurationTest.java index 13adaebb0eda..bcaf695a13fb 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/testSpring3/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webmvc/SpringWebMvcInstrumentation6AutoConfigurationTest.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/testSpring3/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webmvc/SpringWebMvcInstrumentation6AutoConfigurationTest.java @@ -30,7 +30,8 @@ class SpringWebMvcInstrumentation6AutoConfigurationTest { () -> new ConfigPropertiesBridge( DefaultConfigProperties.createFromMap(Collections.emptyMap()), - ConfigProvider.noop())) + ConfigProvider.noop(), + false)) .withConfiguration( AutoConfigurations.of(SpringWebMvc6InstrumentationAutoConfiguration.class)); diff --git a/instrumentation/spring/spring-boot-autoconfigure/testing/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/AbstractJdbcInstrumentationAutoConfigurationTest.java b/instrumentation/spring/spring-boot-autoconfigure/testing/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/AbstractJdbcInstrumentationAutoConfigurationTest.java index 81264fb218b4..c7f5af335012 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/testing/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/AbstractJdbcInstrumentationAutoConfigurationTest.java +++ b/instrumentation/spring/spring-boot-autoconfigure/testing/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/AbstractJdbcInstrumentationAutoConfigurationTest.java @@ -5,17 +5,14 @@ package io.opentelemetry.instrumentation.spring.autoconfigure.internal; +import static io.opentelemetry.instrumentation.spring.autoconfigure.internal.AbstractKafkaInstrumentationAutoConfigurationTest.EMPTY_INSTRUMENTATION_CONFIG; import static io.opentelemetry.instrumentation.testing.junit.db.SemconvStabilityUtil.maybeStable; import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_STATEMENT; -import static java.util.Collections.emptyMap; import static org.assertj.core.api.Assertions.assertThat; import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; -import io.opentelemetry.instrumentation.spring.autoconfigure.internal.properties.ConfigPropertiesBridge; import io.opentelemetry.instrumentation.testing.junit.InstrumentationExtension; -import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; import java.sql.Connection; import java.sql.Statement; import javax.sql.DataSource; @@ -33,11 +30,7 @@ public abstract class AbstractJdbcInstrumentationAutoConfigurationTest { private final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withBean( - InstrumentationConfig.class, - () -> - new ConfigPropertiesBridge( - DefaultConfigProperties.createFromMap(emptyMap()), ConfigProvider.noop())) + .withBean(InstrumentationConfig.class, () -> EMPTY_INSTRUMENTATION_CONFIG) .withConfiguration(autoConfigurations()) .withBean("openTelemetry", OpenTelemetry.class, testing()::getOpenTelemetry); diff --git a/instrumentation/spring/spring-boot-autoconfigure/testing/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/AbstractKafkaInstrumentationAutoConfigurationTest.java b/instrumentation/spring/spring-boot-autoconfigure/testing/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/AbstractKafkaInstrumentationAutoConfigurationTest.java index ba7faa2f58f7..98d0d71534d5 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/testing/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/AbstractKafkaInstrumentationAutoConfigurationTest.java +++ b/instrumentation/spring/spring-boot-autoconfigure/testing/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/AbstractKafkaInstrumentationAutoConfigurationTest.java @@ -5,7 +5,6 @@ package io.opentelemetry.instrumentation.spring.autoconfigure.internal; -import static java.util.Collections.emptyMap; import static org.assertj.core.api.Assertions.assertThat; import io.opentelemetry.api.OpenTelemetry; @@ -13,6 +12,7 @@ import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; import io.opentelemetry.instrumentation.spring.autoconfigure.internal.properties.ConfigPropertiesBridge; import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; +import java.util.Collections; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.assertj.AssertableApplicationContext; @@ -20,17 +20,19 @@ public abstract class AbstractKafkaInstrumentationAutoConfigurationTest { + public static final ConfigPropertiesBridge EMPTY_INSTRUMENTATION_CONFIG = + new ConfigPropertiesBridge( + DefaultConfigProperties.createFromMap(Collections.emptyMap()), + ConfigProvider.noop(), + false); + protected abstract AutoConfigurations autoConfigurations(); protected abstract void factoryTestAssertion(AssertableApplicationContext context); protected final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withBean( - InstrumentationConfig.class, - () -> - new ConfigPropertiesBridge( - DefaultConfigProperties.createFromMap(emptyMap()), ConfigProvider.noop())) + .withBean(InstrumentationConfig.class, () -> EMPTY_INSTRUMENTATION_CONFIG) .withConfiguration(autoConfigurations()) .withBean("openTelemetry", OpenTelemetry.class, OpenTelemetry::noop); diff --git a/instrumentation/spring/spring-boot-autoconfigure/testing/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/AbstractR2DbcInstrumentationAutoConfigurationTest.java b/instrumentation/spring/spring-boot-autoconfigure/testing/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/AbstractR2DbcInstrumentationAutoConfigurationTest.java index c9bb1c9ef8ca..fdad3a062197 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/testing/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/AbstractR2DbcInstrumentationAutoConfigurationTest.java +++ b/instrumentation/spring/spring-boot-autoconfigure/testing/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/AbstractR2DbcInstrumentationAutoConfigurationTest.java @@ -5,16 +5,13 @@ package io.opentelemetry.instrumentation.spring.autoconfigure.internal; +import static io.opentelemetry.instrumentation.spring.autoconfigure.internal.AbstractKafkaInstrumentationAutoConfigurationTest.EMPTY_INSTRUMENTATION_CONFIG; import static io.opentelemetry.instrumentation.testing.junit.db.SemconvStabilityUtil.maybeStable; import static io.opentelemetry.semconv.incubating.DbIncubatingAttributes.DB_STATEMENT; import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; -import io.opentelemetry.instrumentation.spring.autoconfigure.internal.properties.ConfigPropertiesBridge; import io.opentelemetry.instrumentation.testing.junit.LibraryInstrumentationExtension; -import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; -import java.util.Collections; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.runner.ApplicationContextRunner; @@ -28,12 +25,7 @@ public abstract class AbstractR2DbcInstrumentationAutoConfigurationTest { protected final ApplicationContextRunner contextRunner = new ApplicationContextRunner() - .withBean( - InstrumentationConfig.class, - () -> - new ConfigPropertiesBridge( - DefaultConfigProperties.createFromMap(Collections.emptyMap()), - ConfigProvider.noop())) + .withBean(InstrumentationConfig.class, () -> EMPTY_INSTRUMENTATION_CONFIG) .withConfiguration(autoConfigurations()) .withBean("openTelemetry", OpenTelemetry.class, testing()::getOpenTelemetry); diff --git a/instrumentation/spring/spring-boot-autoconfigure/testing/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/AbstractSpringWebInstrumentationAutoConfigurationTest.java b/instrumentation/spring/spring-boot-autoconfigure/testing/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/AbstractSpringWebInstrumentationAutoConfigurationTest.java index 3d9e914f46ef..9d56280ea857 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/testing/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/AbstractSpringWebInstrumentationAutoConfigurationTest.java +++ b/instrumentation/spring/spring-boot-autoconfigure/testing/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/AbstractSpringWebInstrumentationAutoConfigurationTest.java @@ -5,15 +5,12 @@ package io.opentelemetry.instrumentation.spring.autoconfigure.internal; +import static io.opentelemetry.instrumentation.spring.autoconfigure.internal.AbstractKafkaInstrumentationAutoConfigurationTest.EMPTY_INSTRUMENTATION_CONFIG; import static org.assertj.core.api.Assertions.assertThat; import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; import io.opentelemetry.instrumentation.spring.autoconfigure.internal.instrumentation.web.RestTemplateBeanPostProcessor; -import io.opentelemetry.instrumentation.spring.autoconfigure.internal.properties.ConfigPropertiesBridge; -import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; -import java.util.Collections; import org.junit.jupiter.api.Test; import org.springframework.boot.autoconfigure.AutoConfigurations; import org.springframework.boot.test.context.runner.ApplicationContextRunner; @@ -26,12 +23,7 @@ public abstract class AbstractSpringWebInstrumentationAutoConfigurationTest { protected final ApplicationContextRunner contextRunner = new ApplicationContextRunner() .withBean(OpenTelemetry.class, OpenTelemetry::noop) - .withBean( - InstrumentationConfig.class, - () -> - new ConfigPropertiesBridge( - DefaultConfigProperties.createFromMap(Collections.emptyMap()), - ConfigProvider.noop())) + .withBean(InstrumentationConfig.class, () -> EMPTY_INSTRUMENTATION_CONFIG) .withBean(RestTemplate.class, RestTemplate::new) .withConfiguration(autoConfigurations()); diff --git a/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/bootstrap/internal/EmptyInstrumentationConfig.java b/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/bootstrap/internal/EmptyInstrumentationConfig.java index 276a87f0b1e5..e5a33a2ccaa3 100644 --- a/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/bootstrap/internal/EmptyInstrumentationConfig.java +++ b/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/bootstrap/internal/EmptyInstrumentationConfig.java @@ -6,7 +6,6 @@ package io.opentelemetry.javaagent.bootstrap.internal; import io.opentelemetry.api.incubator.config.ConfigProvider; -import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; import java.time.Duration; import java.util.List; diff --git a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/ConfigPropertiesBridge.java b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/ConfigPropertiesBridge.java index 0ae316fb1607..2f6e95b5c497 100644 --- a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/ConfigPropertiesBridge.java +++ b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/ConfigPropertiesBridge.java @@ -5,11 +5,7 @@ package io.opentelemetry.javaagent.tooling.config; -import static io.opentelemetry.api.incubator.config.DeclarativeConfigProperties.empty; - import io.opentelemetry.api.incubator.config.ConfigProvider; -import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; -import io.opentelemetry.api.incubator.config.InstrumentationConfigUtil; import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; From 22d71fcff911fd2f673d9d793f38dc1f530e3db6 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Fri, 12 Dec 2025 21:19:36 +0100 Subject: [PATCH 69/79] use bridge --- .../webflux/WebClientBeanPostProcessorTest.java | 10 ++-------- 1 file changed, 2 insertions(+), 8 deletions(-) diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webflux/WebClientBeanPostProcessorTest.java b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webflux/WebClientBeanPostProcessorTest.java index 35956bbb2a19..feba92760a54 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webflux/WebClientBeanPostProcessorTest.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/test/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webflux/WebClientBeanPostProcessorTest.java @@ -5,14 +5,11 @@ package io.opentelemetry.instrumentation.spring.autoconfigure.internal.instrumentation.webflux; +import static io.opentelemetry.instrumentation.spring.autoconfigure.internal.AbstractKafkaInstrumentationAutoConfigurationTest.EMPTY_INSTRUMENTATION_CONFIG; import static org.assertj.core.api.Assertions.assertThat; import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; -import io.opentelemetry.instrumentation.spring.autoconfigure.internal.properties.ConfigPropertiesBridge; -import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; -import java.util.Collections; import org.junit.jupiter.api.DisplayName; import org.junit.jupiter.api.Test; import org.springframework.beans.factory.config.BeanPostProcessor; @@ -25,10 +22,7 @@ class WebClientBeanPostProcessorTest { static { beanFactory.registerSingleton("openTelemetry", OpenTelemetry.noop()); - beanFactory.registerSingleton( - "configProperties", - new ConfigPropertiesBridge( - DefaultConfigProperties.createFromMap(Collections.emptyMap()), ConfigProvider.noop())); + beanFactory.registerSingleton("instrumentationConfig", EMPTY_INSTRUMENTATION_CONFIG); } @Test From 176e09b73967847e0c7c17dcf593711158bc2242 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Fri, 12 Dec 2025 21:44:04 +0100 Subject: [PATCH 70/79] fix --- .../tooling/config/ConfigPropertiesBridgeTest.java | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/config/ConfigPropertiesBridgeTest.java b/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/config/ConfigPropertiesBridgeTest.java index 796d7a90a9a3..0e05613ca528 100644 --- a/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/config/ConfigPropertiesBridgeTest.java +++ b/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/config/ConfigPropertiesBridgeTest.java @@ -9,7 +9,6 @@ import static java.util.Collections.emptyMap; import static org.assertj.core.api.Assertions.assertThat; -import io.opentelemetry.api.OpenTelemetry; import io.opentelemetry.instrumentation.api.incubator.config.internal.CommonConfig; import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; @@ -47,12 +46,11 @@ public static Stream emptyGeneralConfig() { return Stream.of( Arguments.of( - "config properties", - new ConfigPropertiesBridge(configProperties, null, OpenTelemetry.noop())), + "config properties", new ConfigPropertiesBridge(configProperties, null, false)), Arguments.of( "declarative config", new ConfigPropertiesBridge( - configProperties, SdkConfigProvider.create(emptyModel), OpenTelemetry.noop()))); + configProperties, SdkConfigProvider.create(emptyModel), false))); } @ParameterizedTest(name = "{0}") @@ -100,12 +98,11 @@ public static Stream fullGeneralConfig() { return Stream.of( Arguments.of( - "config properties", - new ConfigPropertiesBridge(configProperties, null, OpenTelemetry.noop())), + "config properties", new ConfigPropertiesBridge(configProperties, null, false)), Arguments.of( "declarative config", new ConfigPropertiesBridge( - configProperties, SdkConfigProvider.create(emptyModel), OpenTelemetry.noop()))); + configProperties, SdkConfigProvider.create(emptyModel), false))); } private static Map getProperties() { From 11d523d5d1766f4668c40515ccbfb9d5d6c0c0a6 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Fri, 12 Dec 2025 21:59:48 +0100 Subject: [PATCH 71/79] fix --- .../api/instrumenter/InstrumenterBuilder.java | 3 ++- .../instrumentation/api/internal/ConfigProviderUtil.java | 7 +------ .../instrumentation/extannotations/IncludeTest.java | 6 +++++- 3 files changed, 8 insertions(+), 8 deletions(-) diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/InstrumenterBuilder.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/InstrumenterBuilder.java index 4e9e65ad85b4..e41728bd2de2 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/InstrumenterBuilder.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/InstrumenterBuilder.java @@ -11,6 +11,7 @@ import com.google.errorprone.annotations.CanIgnoreReturnValue; import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.api.incubator.ExtendedOpenTelemetry; import io.opentelemetry.api.incubator.config.InstrumentationConfigUtil; import io.opentelemetry.api.metrics.Meter; import io.opentelemetry.api.metrics.MeterBuilder; @@ -374,7 +375,7 @@ SpanSuppressor buildSpanSuppressor() { // otel.instrumentation.experimental.* doesn't fit the usual pattern of configuration properties // for instrumentations, so we need to handle both declarative and non-declarative configs here String value = - ConfigProviderUtil.isDeclarativeConfig(openTelemetry) + openTelemetry instanceof ExtendedOpenTelemetry ? InstrumentationConfigUtil.getOrNull( ConfigProviderUtil.getConfigProvider(GlobalOpenTelemetry.get()), config -> config.getString("span_suppression_strategy/development"), diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigProviderUtil.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigProviderUtil.java index 823f9b32cd7d..5d02706db5a1 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigProviderUtil.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigProviderUtil.java @@ -23,13 +23,8 @@ protected AbstractBridgedDeclarativeConfigProperties getProperties(String name) } }; - /** Returns true if the given OpenTelemetry instance supports Declarative Config. */ - public static boolean isDeclarativeConfig(OpenTelemetry openTelemetry) { - return openTelemetry instanceof ExtendedOpenTelemetry; - } - public static ConfigProvider getConfigProvider(OpenTelemetry openTelemetry) { - if (isDeclarativeConfig(openTelemetry)) { + if (openTelemetry instanceof ExtendedOpenTelemetry) { return ((ExtendedOpenTelemetry) openTelemetry).getConfigProvider(); } return BRIDGED_CONFIG_PROVIDER; diff --git a/instrumentation/external-annotations/javaagent-unit-tests/src/test/java/io/opentelemetry/javaagent/instrumentation/extannotations/IncludeTest.java b/instrumentation/external-annotations/javaagent-unit-tests/src/test/java/io/opentelemetry/javaagent/instrumentation/extannotations/IncludeTest.java index 9f717b107392..7a20e8f1957b 100644 --- a/instrumentation/external-annotations/javaagent-unit-tests/src/test/java/io/opentelemetry/javaagent/instrumentation/extannotations/IncludeTest.java +++ b/instrumentation/external-annotations/javaagent-unit-tests/src/test/java/io/opentelemetry/javaagent/instrumentation/extannotations/IncludeTest.java @@ -9,6 +9,7 @@ import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.when; +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; import java.util.Arrays; import java.util.Collections; @@ -27,10 +28,13 @@ class IncludeTest { @Mock InstrumentationConfig config; + @Mock DeclarativeConfigProperties externalAnnotationsConfig; + @ParameterizedTest @MethodSource("provideArguments") void testConfiguration(String value, List expected) { - when(config.getString("otel.instrumentation.external-annotations.include")).thenReturn(value); + when(config.getDeclarativeConfig("external-annotations")).thenReturn(externalAnnotationsConfig); + when(externalAnnotationsConfig.getString("include")).thenReturn(value); assertThat(ExternalAnnotationInstrumentation.configureAdditionalTraceAnnotations(config)) .isEqualTo(new HashSet<>(expected)); From 2507ce40074e298c2cae9f40c7271e0008fbd491 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Fri, 12 Dec 2025 23:34:19 +0100 Subject: [PATCH 72/79] fix --- .../api/instrumenter/InstrumenterBuilder.java | 3 +-- .../api/internal/ConfigProviderUtil.java | 22 ++++++++++++++++++- 2 files changed, 22 insertions(+), 3 deletions(-) diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/InstrumenterBuilder.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/InstrumenterBuilder.java index e41728bd2de2..4e9e65ad85b4 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/InstrumenterBuilder.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/InstrumenterBuilder.java @@ -11,7 +11,6 @@ import com.google.errorprone.annotations.CanIgnoreReturnValue; import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.api.incubator.ExtendedOpenTelemetry; import io.opentelemetry.api.incubator.config.InstrumentationConfigUtil; import io.opentelemetry.api.metrics.Meter; import io.opentelemetry.api.metrics.MeterBuilder; @@ -375,7 +374,7 @@ SpanSuppressor buildSpanSuppressor() { // otel.instrumentation.experimental.* doesn't fit the usual pattern of configuration properties // for instrumentations, so we need to handle both declarative and non-declarative configs here String value = - openTelemetry instanceof ExtendedOpenTelemetry + ConfigProviderUtil.isDeclarativeConfig(openTelemetry) ? InstrumentationConfigUtil.getOrNull( ConfigProviderUtil.getConfigProvider(GlobalOpenTelemetry.get()), config -> config.getString("span_suppression_strategy/development"), diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigProviderUtil.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigProviderUtil.java index 5d02706db5a1..029dbedf4401 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigProviderUtil.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigProviderUtil.java @@ -22,9 +22,29 @@ protected AbstractBridgedDeclarativeConfigProperties getProperties(String name) return new SystemPropertiesDeclarativeConfigProperties(name, null); } }; + private static final boolean supportsDeclarativeConfig = supportsDeclarativeConfig(); + + private static boolean supportsDeclarativeConfig() { + try { + Class.forName("io.opentelemetry.api.incubator.ExtendedOpenTelemetry"); + return true; + } catch (ClassNotFoundException e) { + // The incubator module is not available. + // This only happens in OpenTelemetry API instrumentation tests, where an older version of + // OpenTelemetry API is used that does not have ExtendedOpenTelemetry. + // Having the incubator module without ExtendedOpenTelemetry class should still return false + // for those tests to avoid a ClassNotFoundException. + return false; + } + } + + /** Returns true if the given OpenTelemetry instance supports Declarative Config. */ + public static boolean isDeclarativeConfig(OpenTelemetry openTelemetry) { + return supportsDeclarativeConfig && openTelemetry instanceof ExtendedOpenTelemetry; + } public static ConfigProvider getConfigProvider(OpenTelemetry openTelemetry) { - if (openTelemetry instanceof ExtendedOpenTelemetry) { + if (isDeclarativeConfig(openTelemetry)) { return ((ExtendedOpenTelemetry) openTelemetry).getConfigProvider(); } return BRIDGED_CONFIG_PROVIDER; From a50c5e845f9f68e2a108052b6ef600bafc0b168a Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Sat, 13 Dec 2025 00:00:06 +0100 Subject: [PATCH 73/79] docs --- .../instrumentation/api/internal/ConfigProviderUtil.java | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigProviderUtil.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigProviderUtil.java index 029dbedf4401..f8b9f3339631 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigProviderUtil.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigProviderUtil.java @@ -43,6 +43,10 @@ public static boolean isDeclarativeConfig(OpenTelemetry openTelemetry) { return supportsDeclarativeConfig && openTelemetry instanceof ExtendedOpenTelemetry; } + /** + * Returns the ConfigProvider from declarative config if supported, otherwise returns a bridged + * ConfigProvider that reads from system properties or environment variables. + */ public static ConfigProvider getConfigProvider(OpenTelemetry openTelemetry) { if (isDeclarativeConfig(openTelemetry)) { return ((ExtendedOpenTelemetry) openTelemetry).getConfigProvider(); From e3b27117dc067b11a17b1f7070f1238ad76eff66 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Sat, 13 Dec 2025 18:58:51 +0100 Subject: [PATCH 74/79] fix --- .../api/instrumenter/InstrumenterBuilder.java | 23 ++++++++++++++++++- .../api/internal/ConfigProviderUtil.java | 22 +----------------- 2 files changed, 23 insertions(+), 22 deletions(-) diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/InstrumenterBuilder.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/InstrumenterBuilder.java index 4e9e65ad85b4..bd0cf9c1570e 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/InstrumenterBuilder.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/InstrumenterBuilder.java @@ -11,6 +11,7 @@ import com.google.errorprone.annotations.CanIgnoreReturnValue; import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.api.incubator.ExtendedOpenTelemetry; import io.opentelemetry.api.incubator.config.InstrumentationConfigUtil; import io.opentelemetry.api.metrics.Meter; import io.opentelemetry.api.metrics.MeterBuilder; @@ -51,6 +52,7 @@ public final class InstrumenterBuilder { private static final Logger logger = Logger.getLogger(InstrumenterBuilder.class.getName()); + private static final boolean supportsDeclarativeConfig = supportsDeclarativeConfig(); final OpenTelemetry openTelemetry; final String instrumentationName; @@ -74,6 +76,20 @@ public final class InstrumenterBuilder { boolean propagateOperationListenersToOnEnd = false; boolean enabled = true; + private static boolean supportsDeclarativeConfig() { + try { + Class.forName("io.opentelemetry.api.incubator.ExtendedOpenTelemetry"); + return true; + } catch (ClassNotFoundException e) { + // The incubator module is not available. + // This only happens in OpenTelemetry API instrumentation tests, where an older version of + // OpenTelemetry API is used that does not have ExtendedOpenTelemetry. + // Having the incubator module without ExtendedOpenTelemetry class should still return false + // for those tests to avoid a ClassNotFoundException. + return false; + } + } + static { Experimental.internalAddOperationListenerAttributesExtractor( (builder, operationListenerAttributesExtractor) -> @@ -374,7 +390,7 @@ SpanSuppressor buildSpanSuppressor() { // otel.instrumentation.experimental.* doesn't fit the usual pattern of configuration properties // for instrumentations, so we need to handle both declarative and non-declarative configs here String value = - ConfigProviderUtil.isDeclarativeConfig(openTelemetry) + isDeclarativeConfig(openTelemetry) ? InstrumentationConfigUtil.getOrNull( ConfigProviderUtil.getConfigProvider(GlobalOpenTelemetry.get()), config -> config.getString("span_suppression_strategy/development"), @@ -463,6 +479,11 @@ public void setSpanStatusExtractorCustomizer( } } + /** Returns true if the given OpenTelemetry instance supports Declarative Config. */ + public static boolean isDeclarativeConfig(OpenTelemetry openTelemetry) { + return supportsDeclarativeConfig && openTelemetry instanceof ExtendedOpenTelemetry; + } + private interface InstrumenterConstructor { Instrumenter create(InstrumenterBuilder builder); diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigProviderUtil.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigProviderUtil.java index f8b9f3339631..4637d3f54860 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigProviderUtil.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigProviderUtil.java @@ -22,33 +22,13 @@ protected AbstractBridgedDeclarativeConfigProperties getProperties(String name) return new SystemPropertiesDeclarativeConfigProperties(name, null); } }; - private static final boolean supportsDeclarativeConfig = supportsDeclarativeConfig(); - - private static boolean supportsDeclarativeConfig() { - try { - Class.forName("io.opentelemetry.api.incubator.ExtendedOpenTelemetry"); - return true; - } catch (ClassNotFoundException e) { - // The incubator module is not available. - // This only happens in OpenTelemetry API instrumentation tests, where an older version of - // OpenTelemetry API is used that does not have ExtendedOpenTelemetry. - // Having the incubator module without ExtendedOpenTelemetry class should still return false - // for those tests to avoid a ClassNotFoundException. - return false; - } - } - - /** Returns true if the given OpenTelemetry instance supports Declarative Config. */ - public static boolean isDeclarativeConfig(OpenTelemetry openTelemetry) { - return supportsDeclarativeConfig && openTelemetry instanceof ExtendedOpenTelemetry; - } /** * Returns the ConfigProvider from declarative config if supported, otherwise returns a bridged * ConfigProvider that reads from system properties or environment variables. */ public static ConfigProvider getConfigProvider(OpenTelemetry openTelemetry) { - if (isDeclarativeConfig(openTelemetry)) { + if (openTelemetry instanceof ExtendedOpenTelemetry) { return ((ExtendedOpenTelemetry) openTelemetry).getConfigProvider(); } return BRIDGED_CONFIG_PROVIDER; From 17e0ada25f431e61b2134033ea289c365c6c2a59 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Sat, 13 Dec 2025 19:11:48 +0100 Subject: [PATCH 75/79] avoid inheritance --- ...PropertiesDeclarativeConfigProperties.java | 32 ++++--------------- ...ertiesDeclarativeConfigPropertiesTest.java | 32 +++++++++++++++++++ .../AbstractBridgedConfigProvider.java | 2 +- ...> BridgedDeclarativeConfigProperties.java} | 30 ++++++++--------- .../api/internal/ConfigProviderUtil.java | 4 +-- ...PropertiesDeclarativeConfigProperties.java | 28 ---------------- ...idgedDeclarativeConfigPropertiesTest.java} | 9 +++--- 7 files changed, 61 insertions(+), 76 deletions(-) create mode 100644 declarative-config-bridge/src/test/java/io/opentelemetry/instrumentation/config/bridge/ConfigPropertiesDeclarativeConfigPropertiesTest.java rename instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/{AbstractBridgedDeclarativeConfigProperties.java => BridgedDeclarativeConfigProperties.java} (83%) delete mode 100644 instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/SystemPropertiesDeclarativeConfigProperties.java rename instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/{AbstractBridgedDeclarativeConfigPropertiesTest.java => BridgedDeclarativeConfigPropertiesTest.java} (72%) diff --git a/declarative-config-bridge/src/main/java/io/opentelemetry/instrumentation/config/bridge/ConfigPropertiesDeclarativeConfigProperties.java b/declarative-config-bridge/src/main/java/io/opentelemetry/instrumentation/config/bridge/ConfigPropertiesDeclarativeConfigProperties.java index d111a93e9ee4..a2ddb20231d8 100644 --- a/declarative-config-bridge/src/main/java/io/opentelemetry/instrumentation/config/bridge/ConfigPropertiesDeclarativeConfigProperties.java +++ b/declarative-config-bridge/src/main/java/io/opentelemetry/instrumentation/config/bridge/ConfigPropertiesDeclarativeConfigProperties.java @@ -7,40 +7,20 @@ import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.instrumentation.api.internal.AbstractBridgedConfigProvider; -import io.opentelemetry.instrumentation.api.internal.AbstractBridgedDeclarativeConfigProperties; +import io.opentelemetry.instrumentation.api.internal.BridgedDeclarativeConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; -import javax.annotation.Nullable; -public class ConfigPropertiesDeclarativeConfigProperties - extends AbstractBridgedDeclarativeConfigProperties { +public final class ConfigPropertiesDeclarativeConfigProperties { - private final ConfigProperties configProperties; - - private ConfigPropertiesDeclarativeConfigProperties( - ConfigProperties configProperties, - String node, - @Nullable ConfigPropertiesDeclarativeConfigProperties parent) { - super(node, parent); - this.configProperties = configProperties; - } + private ConfigPropertiesDeclarativeConfigProperties() {} public static ConfigProvider create(ConfigProperties configProperties) { return new AbstractBridgedConfigProvider() { @Override - protected AbstractBridgedDeclarativeConfigProperties getProperties(String name) { - return new ConfigPropertiesDeclarativeConfigProperties(configProperties, name, null); + protected BridgedDeclarativeConfigProperties getProperties(String name) { + return new BridgedDeclarativeConfigProperties(name, null, configProperties::getString); } }; } - - @Nullable - @Override - public String getStringValue(String systemPropertyKey) { - return configProperties.getString(systemPropertyKey); - } - - @Override - protected AbstractBridgedDeclarativeConfigProperties newChild(String node) { - return new ConfigPropertiesDeclarativeConfigProperties(configProperties, node, this); - } } + diff --git a/declarative-config-bridge/src/test/java/io/opentelemetry/instrumentation/config/bridge/ConfigPropertiesDeclarativeConfigPropertiesTest.java b/declarative-config-bridge/src/test/java/io/opentelemetry/instrumentation/config/bridge/ConfigPropertiesDeclarativeConfigPropertiesTest.java new file mode 100644 index 000000000000..f21cf5dde2fa --- /dev/null +++ b/declarative-config-bridge/src/test/java/io/opentelemetry/instrumentation/config/bridge/ConfigPropertiesDeclarativeConfigPropertiesTest.java @@ -0,0 +1,32 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.config.bridge; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.when; + +import io.opentelemetry.api.incubator.config.ConfigProvider; +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; +import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; +import org.junit.jupiter.api.Test; + +class ConfigPropertiesDeclarativeConfigPropertiesTest { + + @Test + void shouldBridgeConfigProperties() { + ConfigProperties configProperties = mock(ConfigProperties.class); + when(configProperties.getString("otel.instrumentation.foo.bar")).thenReturn("baz"); + when(configProperties.getString("otel.instrumentation.experimental.foo.bar")).thenReturn("qux"); + + ConfigProvider configProvider = ConfigPropertiesDeclarativeConfigProperties.create(configProperties); + DeclarativeConfigProperties properties = configProvider.getInstrumentationConfig(); + + assertThat(properties.getStructured("java").getStructured("foo").getString("bar")).isEqualTo("baz"); + assertThat(properties.getStructured("java").getStructured("foo/development").getString("bar")).isEqualTo("qux"); + } +} + diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/AbstractBridgedConfigProvider.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/AbstractBridgedConfigProvider.java index 5dbaebb6ed45..74dd710173c2 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/AbstractBridgedConfigProvider.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/AbstractBridgedConfigProvider.java @@ -37,7 +37,7 @@ public DeclarativeConfigProperties getStructured(String name) { }; } - protected abstract AbstractBridgedDeclarativeConfigProperties getProperties(String name); + protected abstract BridgedDeclarativeConfigProperties getProperties(String name); private abstract static class EmptyDeclarativeConfigProperties implements DeclarativeConfigProperties { diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/AbstractBridgedDeclarativeConfigProperties.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/BridgedDeclarativeConfigProperties.java similarity index 83% rename from instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/AbstractBridgedDeclarativeConfigProperties.java rename to instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/BridgedDeclarativeConfigProperties.java index ab9b58e67ea3..7c87621c8c8d 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/AbstractBridgedDeclarativeConfigProperties.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/BridgedDeclarativeConfigProperties.java @@ -11,6 +11,7 @@ import java.util.Arrays; import java.util.List; import java.util.Set; +import java.util.function.Function; import java.util.stream.Collectors; import javax.annotation.Nullable; @@ -18,15 +19,18 @@ * This class is internal and is hence not for public use. Its APIs are unstable and can change at * any time. */ -public abstract class AbstractBridgedDeclarativeConfigProperties - implements DeclarativeConfigProperties { - protected final String node; - @Nullable protected final AbstractBridgedDeclarativeConfigProperties parent; - - public AbstractBridgedDeclarativeConfigProperties( - String node, @Nullable AbstractBridgedDeclarativeConfigProperties parent) { +public final class BridgedDeclarativeConfigProperties implements DeclarativeConfigProperties { + private final String node; + @Nullable private final BridgedDeclarativeConfigProperties parent; + private final Function propertySource; + + public BridgedDeclarativeConfigProperties( + String node, + @Nullable BridgedDeclarativeConfigProperties parent, + Function propertySource) { this.node = node; this.parent = parent; + this.propertySource = propertySource; } private static List filterBlanksAndNulls(String[] values) { @@ -39,7 +43,7 @@ private static List filterBlanksAndNulls(String[] values) { @Nullable @Override public String getString(String name) { - return getStringValue(getSystemProperty(name)); + return propertySource.apply(getSystemProperty(name)); } @Nullable @@ -103,13 +107,13 @@ public List getScalarList(String name, Class scalarType) { return value == null ? null : (List) - AbstractBridgedDeclarativeConfigProperties.filterBlanksAndNulls(value.split(",")); + BridgedDeclarativeConfigProperties.filterBlanksAndNulls(value.split(",")); } @Nullable @Override public DeclarativeConfigProperties getStructured(String name) { - return newChild(name); + return new BridgedDeclarativeConfigProperties(name, this, propertySource); } @Nullable @@ -128,11 +132,6 @@ public ComponentLoader getComponentLoader() { throw new UnsupportedOperationException(); } - protected abstract AbstractBridgedDeclarativeConfigProperties newChild(String node); - - @Nullable - protected abstract String getStringValue(String systemPropertyKey); - private String getSystemProperty(String name) { List nodes = new ArrayList<>(); addSystemPropertyPathNodes(nodes); @@ -158,3 +157,4 @@ static String toSystemProperty(List nodes) { return "otel.instrumentation." + String.join(".", nodes).replace('_', '-'); } } + diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigProviderUtil.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigProviderUtil.java index 4637d3f54860..a0e6a76ebf08 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigProviderUtil.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigProviderUtil.java @@ -18,8 +18,8 @@ public class ConfigProviderUtil { static final AbstractBridgedConfigProvider BRIDGED_CONFIG_PROVIDER = new AbstractBridgedConfigProvider() { @Override - protected AbstractBridgedDeclarativeConfigProperties getProperties(String name) { - return new SystemPropertiesDeclarativeConfigProperties(name, null); + protected BridgedDeclarativeConfigProperties getProperties(String name) { + return new BridgedDeclarativeConfigProperties(name, null, ConfigPropertiesUtil::getString); } }; diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/SystemPropertiesDeclarativeConfigProperties.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/SystemPropertiesDeclarativeConfigProperties.java deleted file mode 100644 index d6bdc387a479..000000000000 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/SystemPropertiesDeclarativeConfigProperties.java +++ /dev/null @@ -1,28 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.instrumentation.api.internal; - -import javax.annotation.Nullable; - -class SystemPropertiesDeclarativeConfigProperties - extends AbstractBridgedDeclarativeConfigProperties { - - SystemPropertiesDeclarativeConfigProperties( - String node, @Nullable SystemPropertiesDeclarativeConfigProperties parent) { - super(node, parent); - } - - @Nullable - @Override - public String getStringValue(String systemPropertyKey) { - return ConfigPropertiesUtil.getString(systemPropertyKey); - } - - @Override - protected AbstractBridgedDeclarativeConfigProperties newChild(String node) { - return new SystemPropertiesDeclarativeConfigProperties(node, this); - } -} diff --git a/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/AbstractBridgedDeclarativeConfigPropertiesTest.java b/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/BridgedDeclarativeConfigPropertiesTest.java similarity index 72% rename from instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/AbstractBridgedDeclarativeConfigPropertiesTest.java rename to instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/BridgedDeclarativeConfigPropertiesTest.java index 288d76196792..6011c0ddfb83 100644 --- a/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/AbstractBridgedDeclarativeConfigPropertiesTest.java +++ b/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/BridgedDeclarativeConfigPropertiesTest.java @@ -10,20 +10,21 @@ import java.util.Arrays; import org.junit.jupiter.api.Test; -class AbstractBridgedDeclarativeConfigPropertiesTest { +class BridgedDeclarativeConfigPropertiesTest { @Test void toSystemProperty() { assertThat( - AbstractBridgedDeclarativeConfigProperties.toSystemProperty( + BridgedDeclarativeConfigProperties.toSystemProperty( Arrays.asList("a_b", "c", "d"))) .isEqualTo("otel.instrumentation.a-b.c.d"); assertThat( - AbstractBridgedDeclarativeConfigProperties.toSystemProperty( + BridgedDeclarativeConfigProperties.toSystemProperty( Arrays.asList("a_b/development", "c", "d"))) .isEqualTo("otel.instrumentation.experimental.a-b.c.d"); assertThat( - AbstractBridgedDeclarativeConfigProperties.toSystemProperty( + BridgedDeclarativeConfigProperties.toSystemProperty( Arrays.asList("a_experimental_b/development", "c", "d"))) .isEqualTo("otel.instrumentation.a-experimental-b.c.d"); } } + From c6b5ea3766aaaf15586f4b8dc66ce360e81ca84c Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Sat, 13 Dec 2025 19:30:33 +0100 Subject: [PATCH 76/79] avoid inheritance --- ...PropertiesDeclarativeConfigProperties.java | 11 +--- ...ertiesDeclarativeConfigPropertiesTest.java | 10 ++-- ...ovider.java => BridgedConfigProvider.java} | 58 +++++++++++++------ .../BridgedDeclarativeConfigProperties.java | 4 +- .../api/internal/ConfigProviderUtil.java | 9 +-- ...ridgedDeclarativeConfigPropertiesTest.java | 5 +- 6 files changed, 51 insertions(+), 46 deletions(-) rename instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/{AbstractBridgedConfigProvider.java => BridgedConfigProvider.java} (55%) diff --git a/declarative-config-bridge/src/main/java/io/opentelemetry/instrumentation/config/bridge/ConfigPropertiesDeclarativeConfigProperties.java b/declarative-config-bridge/src/main/java/io/opentelemetry/instrumentation/config/bridge/ConfigPropertiesDeclarativeConfigProperties.java index a2ddb20231d8..3626bb8de17c 100644 --- a/declarative-config-bridge/src/main/java/io/opentelemetry/instrumentation/config/bridge/ConfigPropertiesDeclarativeConfigProperties.java +++ b/declarative-config-bridge/src/main/java/io/opentelemetry/instrumentation/config/bridge/ConfigPropertiesDeclarativeConfigProperties.java @@ -6,8 +6,7 @@ package io.opentelemetry.instrumentation.config.bridge; import io.opentelemetry.api.incubator.config.ConfigProvider; -import io.opentelemetry.instrumentation.api.internal.AbstractBridgedConfigProvider; -import io.opentelemetry.instrumentation.api.internal.BridgedDeclarativeConfigProperties; +import io.opentelemetry.instrumentation.api.internal.BridgedConfigProvider; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; public final class ConfigPropertiesDeclarativeConfigProperties { @@ -15,12 +14,6 @@ public final class ConfigPropertiesDeclarativeConfigProperties { private ConfigPropertiesDeclarativeConfigProperties() {} public static ConfigProvider create(ConfigProperties configProperties) { - return new AbstractBridgedConfigProvider() { - @Override - protected BridgedDeclarativeConfigProperties getProperties(String name) { - return new BridgedDeclarativeConfigProperties(name, null, configProperties::getString); - } - }; + return new BridgedConfigProvider(configProperties::getString); } } - diff --git a/declarative-config-bridge/src/test/java/io/opentelemetry/instrumentation/config/bridge/ConfigPropertiesDeclarativeConfigPropertiesTest.java b/declarative-config-bridge/src/test/java/io/opentelemetry/instrumentation/config/bridge/ConfigPropertiesDeclarativeConfigPropertiesTest.java index f21cf5dde2fa..238d89fe5aa0 100644 --- a/declarative-config-bridge/src/test/java/io/opentelemetry/instrumentation/config/bridge/ConfigPropertiesDeclarativeConfigPropertiesTest.java +++ b/declarative-config-bridge/src/test/java/io/opentelemetry/instrumentation/config/bridge/ConfigPropertiesDeclarativeConfigPropertiesTest.java @@ -22,11 +22,13 @@ void shouldBridgeConfigProperties() { when(configProperties.getString("otel.instrumentation.foo.bar")).thenReturn("baz"); when(configProperties.getString("otel.instrumentation.experimental.foo.bar")).thenReturn("qux"); - ConfigProvider configProvider = ConfigPropertiesDeclarativeConfigProperties.create(configProperties); + ConfigProvider configProvider = + ConfigPropertiesDeclarativeConfigProperties.create(configProperties); DeclarativeConfigProperties properties = configProvider.getInstrumentationConfig(); - assertThat(properties.getStructured("java").getStructured("foo").getString("bar")).isEqualTo("baz"); - assertThat(properties.getStructured("java").getStructured("foo/development").getString("bar")).isEqualTo("qux"); + assertThat(properties.getStructured("java").getStructured("foo").getString("bar")) + .isEqualTo("baz"); + assertThat(properties.getStructured("java").getStructured("foo/development").getString("bar")) + .isEqualTo("qux"); } } - diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/AbstractBridgedConfigProvider.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/BridgedConfigProvider.java similarity index 55% rename from instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/AbstractBridgedConfigProvider.java rename to instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/BridgedConfigProvider.java index 74dd710173c2..d5bcd34bf05d 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/AbstractBridgedConfigProvider.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/BridgedConfigProvider.java @@ -10,37 +10,57 @@ import io.opentelemetry.common.ComponentLoader; import java.util.List; import java.util.Set; +import java.util.function.Function; import javax.annotation.Nullable; /** * This class is internal and is hence not for public use. Its APIs are unstable and can change at * any time. */ -public abstract class AbstractBridgedConfigProvider implements ConfigProvider { +public final class BridgedConfigProvider implements ConfigProvider { + + private final Function propertySource; + + public BridgedConfigProvider(Function propertySource) { + this.propertySource = propertySource; + } + @Nullable @Override public DeclarativeConfigProperties getInstrumentationConfig() { - return new EmptyDeclarativeConfigProperties() { - @Nullable - @Override - public DeclarativeConfigProperties getStructured(String name) { - if (name.equals("java")) { - return new EmptyDeclarativeConfigProperties() { - @Override - public DeclarativeConfigProperties getStructured(String name) { - return getProperties(name); - } - }; - } - return super.getStructured(name); - } - }; + return createEmptyDeclarativeConfigProperties( + java -> { + if (java.equals("java")) { + return createEmptyDeclarativeConfigProperties( + name -> new BridgedDeclarativeConfigProperties(name, null, propertySource)); + } + throw new UnsupportedOperationException(); + }); } - protected abstract BridgedDeclarativeConfigProperties getProperties(String name); + private static DeclarativeConfigProperties createEmptyDeclarativeConfigProperties( + Function getStructuredFunc) { + return EmptyDeclarativeConfigPropertiesFactory.create(getStructuredFunc); + } + + private static final class EmptyDeclarativeConfigPropertiesFactory { + private EmptyDeclarativeConfigPropertiesFactory() {} - private abstract static class EmptyDeclarativeConfigProperties + static DeclarativeConfigProperties create( + Function getStructuredFunc) { + return new DeclarativeConfigPropertiesImpl(getStructuredFunc); + } + } + + private static final class DeclarativeConfigPropertiesImpl implements DeclarativeConfigProperties { + private final Function getStructuredFunc; + + DeclarativeConfigPropertiesImpl( + Function getStructuredFunc) { + this.getStructuredFunc = getStructuredFunc; + } + @Nullable @Override public String getString(String name) { @@ -80,7 +100,7 @@ public List getScalarList(String name, Class scalarType) { @Nullable @Override public DeclarativeConfigProperties getStructured(String name) { - throw new UnsupportedOperationException(); + return getStructuredFunc.apply(name); } @Nullable diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/BridgedDeclarativeConfigProperties.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/BridgedDeclarativeConfigProperties.java index 7c87621c8c8d..08b79e0c79eb 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/BridgedDeclarativeConfigProperties.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/BridgedDeclarativeConfigProperties.java @@ -106,8 +106,7 @@ public List getScalarList(String name, Class scalarType) { String value = getString(name); return value == null ? null - : (List) - BridgedDeclarativeConfigProperties.filterBlanksAndNulls(value.split(",")); + : (List) BridgedDeclarativeConfigProperties.filterBlanksAndNulls(value.split(",")); } @Nullable @@ -157,4 +156,3 @@ static String toSystemProperty(List nodes) { return "otel.instrumentation." + String.join(".", nodes).replace('_', '-'); } } - diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigProviderUtil.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigProviderUtil.java index a0e6a76ebf08..9c2fbf2680a5 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigProviderUtil.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigProviderUtil.java @@ -15,13 +15,8 @@ */ public class ConfigProviderUtil { - static final AbstractBridgedConfigProvider BRIDGED_CONFIG_PROVIDER = - new AbstractBridgedConfigProvider() { - @Override - protected BridgedDeclarativeConfigProperties getProperties(String name) { - return new BridgedDeclarativeConfigProperties(name, null, ConfigPropertiesUtil::getString); - } - }; + static final BridgedConfigProvider BRIDGED_CONFIG_PROVIDER = + new BridgedConfigProvider(ConfigPropertiesUtil::getString); /** * Returns the ConfigProvider from declarative config if supported, otherwise returns a bridged diff --git a/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/BridgedDeclarativeConfigPropertiesTest.java b/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/BridgedDeclarativeConfigPropertiesTest.java index 6011c0ddfb83..683791c1d888 100644 --- a/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/BridgedDeclarativeConfigPropertiesTest.java +++ b/instrumentation-api/src/test/java/io/opentelemetry/instrumentation/api/internal/BridgedDeclarativeConfigPropertiesTest.java @@ -13,9 +13,7 @@ class BridgedDeclarativeConfigPropertiesTest { @Test void toSystemProperty() { - assertThat( - BridgedDeclarativeConfigProperties.toSystemProperty( - Arrays.asList("a_b", "c", "d"))) + assertThat(BridgedDeclarativeConfigProperties.toSystemProperty(Arrays.asList("a_b", "c", "d"))) .isEqualTo("otel.instrumentation.a-b.c.d"); assertThat( BridgedDeclarativeConfigProperties.toSystemProperty( @@ -27,4 +25,3 @@ void toSystemProperty() { .isEqualTo("otel.instrumentation.a-experimental-b.c.d"); } } - From d4eb195198d73df054030b4c4d5643a7a50d4806 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Sat, 13 Dec 2025 19:31:27 +0100 Subject: [PATCH 77/79] avoid inheritance --- .../instrumentation/api/internal/BridgedConfigProvider.java | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/BridgedConfigProvider.java b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/BridgedConfigProvider.java index d5bcd34bf05d..675bc803aa09 100644 --- a/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/BridgedConfigProvider.java +++ b/instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/BridgedConfigProvider.java @@ -48,15 +48,15 @@ private EmptyDeclarativeConfigPropertiesFactory() {} static DeclarativeConfigProperties create( Function getStructuredFunc) { - return new DeclarativeConfigPropertiesImpl(getStructuredFunc); + return new InnerDeclarativeConfigProperties(getStructuredFunc); } } - private static final class DeclarativeConfigPropertiesImpl + private static final class InnerDeclarativeConfigProperties implements DeclarativeConfigProperties { private final Function getStructuredFunc; - DeclarativeConfigPropertiesImpl( + InnerDeclarativeConfigProperties( Function getStructuredFunc) { this.getStructuredFunc = getStructuredFunc; } From ece1b214bdd5e6d43d0ff62ff156acf8a114d947 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Sat, 13 Dec 2025 19:41:32 +0100 Subject: [PATCH 78/79] simplify logic to determine bridged config provider --- .../config/internal/InstrumentationConfig.java | 5 ++++- .../OpenTelemetryAutoConfiguration.java | 8 ++++---- .../properties/ConfigPropertiesBridge.java | 14 ++------------ ...ClientInstrumentationAutoConfigurationTest.java | 3 +-- ...ebMvcInstrumentation6AutoConfigurationTest.java | 3 +-- ...tKafkaInstrumentationAutoConfigurationTest.java | 4 +--- .../internal/EmptyInstrumentationConfig.java | 5 ----- .../javaagent/tooling/AgentInstaller.java | 5 +++-- .../tooling/config/ConfigPropertiesBridge.java | 12 +----------- .../tooling/config/ConfigPropertiesBridgeTest.java | 12 ++++-------- 10 files changed, 21 insertions(+), 50 deletions(-) diff --git a/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/config/internal/InstrumentationConfig.java b/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/config/internal/InstrumentationConfig.java index 8d79ecb95b06..3a70371cd393 100644 --- a/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/config/internal/InstrumentationConfig.java +++ b/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/config/internal/InstrumentationConfig.java @@ -11,6 +11,7 @@ import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.api.incubator.config.InstrumentationConfigUtil; +import io.opentelemetry.instrumentation.api.internal.BridgedConfigProvider; import java.time.Duration; import java.util.List; import java.util.Map; @@ -113,7 +114,9 @@ default List getList(String name) { Map getMap(String name, Map defaultValue); /** Returns {@code true} if declarative configuration is used in this configuration. */ - boolean isDeclarative(); + default boolean isDeclarative() { + return !(getConfigProvider() instanceof BridgedConfigProvider); + } /** * Returns a {@link DeclarativeConfigProperties} for the given node name, which is usually an diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/OpenTelemetryAutoConfiguration.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/OpenTelemetryAutoConfiguration.java index 15d04219271e..7e6af32fdb9c 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/OpenTelemetryAutoConfiguration.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/OpenTelemetryAutoConfiguration.java @@ -153,7 +153,7 @@ public ConfigProvider configProvider(ConfigProperties properties) { @Bean public InstrumentationConfig instrumentationConfig( ConfigProperties properties, ConfigProvider configProvider) { - return new ConfigPropertiesBridge(properties, configProvider, false); + return new ConfigPropertiesBridge(properties, configProvider); } } @@ -198,7 +198,7 @@ public ConfigProperties otelProperties(ConfigProvider configProvider) { @Bean public InstrumentationConfig instrumentationConfig( ConfigProperties properties, ConfigProvider configProvider) { - return new ConfigPropertiesBridge(properties, configProvider, true); + return new ConfigPropertiesBridge(properties, configProvider); } @Bean @@ -245,7 +245,7 @@ public ConfigProvider configProvider() { @Bean public InstrumentationConfig instrumentationConfig( ConfigProperties properties, ConfigProvider configProvider) { - return new ConfigPropertiesBridge(properties, configProvider, false); + return new ConfigPropertiesBridge(properties, configProvider); } @Configuration @@ -292,7 +292,7 @@ static class FallbackInstrumentationConfig { @Bean public InstrumentationConfig instrumentationConfig( ConfigProperties properties, ConfigProvider configProvider) { - return new ConfigPropertiesBridge(properties, configProvider, false); + return new ConfigPropertiesBridge(properties, configProvider); } } diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/properties/ConfigPropertiesBridge.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/properties/ConfigPropertiesBridge.java index 1ed3c97f675b..68486d677999 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/properties/ConfigPropertiesBridge.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/properties/ConfigPropertiesBridge.java @@ -24,15 +24,10 @@ public final class ConfigPropertiesBridge implements InstrumentationConfig { private final ConfigProperties configProperties; private final ConfigProvider configProvider; - private final boolean isDeclarativeConfig; - public ConfigPropertiesBridge( - ConfigProperties configProperties, - ConfigProvider configProvider, - boolean isDeclarativeConfig) { + public ConfigPropertiesBridge(ConfigProperties configProperties, ConfigProvider configProvider) { this.configProperties = configProperties; this.configProvider = configProvider; - this.isDeclarativeConfig = isDeclarativeConfig; } @Nullable @@ -117,12 +112,7 @@ public Map getMap(String name, Map defaultValue) } } - @Override - public boolean isDeclarative() { - return isDeclarativeConfig; - } - - @Override + @Override public ConfigProvider getConfigProvider() { return configProvider; } diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/testSpring3/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/web/RestClientInstrumentationAutoConfigurationTest.java b/instrumentation/spring/spring-boot-autoconfigure/src/testSpring3/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/web/RestClientInstrumentationAutoConfigurationTest.java index 8eda7e82a1bb..8745c0830bc0 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/testSpring3/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/web/RestClientInstrumentationAutoConfigurationTest.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/testSpring3/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/web/RestClientInstrumentationAutoConfigurationTest.java @@ -28,8 +28,7 @@ class RestClientInstrumentationAutoConfigurationTest { () -> new ConfigPropertiesBridge( DefaultConfigProperties.createFromMap(Collections.emptyMap()), - ConfigProvider.noop(), - false)) + ConfigProvider.noop())) .withBean(RestClient.class, RestClient::create) .withConfiguration( AutoConfigurations.of(RestClientInstrumentationAutoConfiguration.class)); diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/testSpring3/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webmvc/SpringWebMvcInstrumentation6AutoConfigurationTest.java b/instrumentation/spring/spring-boot-autoconfigure/src/testSpring3/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webmvc/SpringWebMvcInstrumentation6AutoConfigurationTest.java index bcaf695a13fb..13adaebb0eda 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/testSpring3/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webmvc/SpringWebMvcInstrumentation6AutoConfigurationTest.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/testSpring3/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/webmvc/SpringWebMvcInstrumentation6AutoConfigurationTest.java @@ -30,8 +30,7 @@ class SpringWebMvcInstrumentation6AutoConfigurationTest { () -> new ConfigPropertiesBridge( DefaultConfigProperties.createFromMap(Collections.emptyMap()), - ConfigProvider.noop(), - false)) + ConfigProvider.noop())) .withConfiguration( AutoConfigurations.of(SpringWebMvc6InstrumentationAutoConfiguration.class)); diff --git a/instrumentation/spring/spring-boot-autoconfigure/testing/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/AbstractKafkaInstrumentationAutoConfigurationTest.java b/instrumentation/spring/spring-boot-autoconfigure/testing/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/AbstractKafkaInstrumentationAutoConfigurationTest.java index 98d0d71534d5..66dc6d35ddbb 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/testing/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/AbstractKafkaInstrumentationAutoConfigurationTest.java +++ b/instrumentation/spring/spring-boot-autoconfigure/testing/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/AbstractKafkaInstrumentationAutoConfigurationTest.java @@ -22,9 +22,7 @@ public abstract class AbstractKafkaInstrumentationAutoConfigurationTest { public static final ConfigPropertiesBridge EMPTY_INSTRUMENTATION_CONFIG = new ConfigPropertiesBridge( - DefaultConfigProperties.createFromMap(Collections.emptyMap()), - ConfigProvider.noop(), - false); + DefaultConfigProperties.createFromMap(Collections.emptyMap()), ConfigProvider.noop()); protected abstract AutoConfigurations autoConfigurations(); diff --git a/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/bootstrap/internal/EmptyInstrumentationConfig.java b/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/bootstrap/internal/EmptyInstrumentationConfig.java index e5a33a2ccaa3..b99c30e45444 100644 --- a/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/bootstrap/internal/EmptyInstrumentationConfig.java +++ b/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/bootstrap/internal/EmptyInstrumentationConfig.java @@ -60,11 +60,6 @@ public Map getMap(String name, Map defaultValue) return defaultValue; } - @Override - public boolean isDeclarative() { - return false; - } - @Override public ConfigProvider getConfigProvider() { return ConfigProvider.noop(); diff --git a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/AgentInstaller.java b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/AgentInstaller.java index a008376782ac..a49af71ba868 100644 --- a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/AgentInstaller.java +++ b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/AgentInstaller.java @@ -10,6 +10,7 @@ import static io.opentelemetry.javaagent.tooling.SafeServiceLoader.loadOrdered; import static io.opentelemetry.javaagent.tooling.Utils.getResourceName; import static java.util.Arrays.asList; +import static java.util.Objects.requireNonNull; import static java.util.logging.Level.FINE; import static java.util.logging.Level.SEVERE; import static net.bytebuddy.matcher.ElementMatchers.any; @@ -240,8 +241,8 @@ private static InstrumentationConfig getInstrumentationConfig( isDeclarativeConfig ? originalProvider : ConfigPropertiesDeclarativeConfigProperties.create( - AutoConfigureUtil.getConfig(autoConfiguredSdk)); - return new ConfigPropertiesBridge(sdkConfig, provider, isDeclarativeConfig); + requireNonNull(AutoConfigureUtil.getConfig(autoConfiguredSdk))); + return new ConfigPropertiesBridge(sdkConfig, provider); } private static AgentBuilder newAgentBuilder(ByteBuddy byteBuddy) { diff --git a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/ConfigPropertiesBridge.java b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/ConfigPropertiesBridge.java index 2f6e95b5c497..d28afe95da47 100644 --- a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/ConfigPropertiesBridge.java +++ b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/ConfigPropertiesBridge.java @@ -18,15 +18,10 @@ public final class ConfigPropertiesBridge implements InstrumentationConfig { private final ConfigProperties configProperties; private final ConfigProvider configProvider; - private final boolean isDeclarativeConfig; - public ConfigPropertiesBridge( - ConfigProperties configProperties, - ConfigProvider configProvider, - boolean isDeclarativeConfig) { + public ConfigPropertiesBridge(ConfigProperties configProperties, ConfigProvider configProvider) { this.configProperties = configProperties; this.configProvider = configProvider; - this.isDeclarativeConfig = isDeclarativeConfig; } @Nullable @@ -111,11 +106,6 @@ public Map getMap(String name, Map defaultValue) } } - @Override - public boolean isDeclarative() { - return isDeclarativeConfig; - } - @Nullable @Override public ConfigProvider getConfigProvider() { diff --git a/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/config/ConfigPropertiesBridgeTest.java b/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/config/ConfigPropertiesBridgeTest.java index 0e05613ca528..6adba8deacfd 100644 --- a/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/config/ConfigPropertiesBridgeTest.java +++ b/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/config/ConfigPropertiesBridgeTest.java @@ -45,12 +45,10 @@ public static Stream emptyGeneralConfig() { DefaultConfigProperties configProperties = DefaultConfigProperties.createFromMap(emptyMap()); return Stream.of( - Arguments.of( - "config properties", new ConfigPropertiesBridge(configProperties, null, false)), + Arguments.of("config properties", new ConfigPropertiesBridge(configProperties, null)), Arguments.of( "declarative config", - new ConfigPropertiesBridge( - configProperties, SdkConfigProvider.create(emptyModel), false))); + new ConfigPropertiesBridge(configProperties, SdkConfigProvider.create(emptyModel)))); } @ParameterizedTest(name = "{0}") @@ -97,12 +95,10 @@ public static Stream fullGeneralConfig() { DefaultConfigProperties.createFromMap(getProperties()); return Stream.of( - Arguments.of( - "config properties", new ConfigPropertiesBridge(configProperties, null, false)), + Arguments.of("config properties", new ConfigPropertiesBridge(configProperties, null)), Arguments.of( "declarative config", - new ConfigPropertiesBridge( - configProperties, SdkConfigProvider.create(emptyModel), false))); + new ConfigPropertiesBridge(configProperties, SdkConfigProvider.create(emptyModel)))); } private static Map getProperties() { From a9fd3e21f6e3a64fa9ce0d7a39b5ada6df1358d9 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Sat, 13 Dec 2025 20:18:09 +0100 Subject: [PATCH 79/79] api --- .../current_vs_latest/opentelemetry-instrumentation-api.txt | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-instrumentation-api.txt b/docs/apidiffs/current_vs_latest/opentelemetry-instrumentation-api.txt index dda7a3ca5e05..787b54ffc48a 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-instrumentation-api.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-instrumentation-api.txt @@ -1,2 +1,5 @@ Comparing source compatibility of opentelemetry-instrumentation-api-2.24.0-SNAPSHOT.jar against opentelemetry-instrumentation-api-2.23.0.jar -No changes. \ No newline at end of file +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + GENERIC TEMPLATES: === REQUEST:java.lang.Object, === RESPONSE:java.lang.Object + +++ NEW METHOD: PUBLIC(+) STATIC(+) boolean isDeclarativeConfig(io.opentelemetry.api.OpenTelemetry)