From 438d6ebef9b779e22bf57dd95fad7eb89483fc22 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Thu, 11 Dec 2025 12:55:35 +0100 Subject: [PATCH 1/6] translate /development in DeclarativeConfigPropertiesBridge --- .../bridge/DeclarativeConfigPropertiesBridge.java | 5 ++++- .../bridge/DeclarativeConfigPropertiesBridgeTest.java | 11 ++++++++++- .../src/test/resources/config.yaml | 7 ++++--- 3 files changed, 18 insertions(+), 5 deletions(-) diff --git a/declarative-config-bridge/src/main/java/io/opentelemetry/instrumentation/config/bridge/DeclarativeConfigPropertiesBridge.java b/declarative-config-bridge/src/main/java/io/opentelemetry/instrumentation/config/bridge/DeclarativeConfigPropertiesBridge.java index 0421148323e6..fac8904a5cf3 100644 --- a/declarative-config-bridge/src/main/java/io/opentelemetry/instrumentation/config/bridge/DeclarativeConfigPropertiesBridge.java +++ b/declarative-config-bridge/src/main/java/io/opentelemetry/instrumentation/config/bridge/DeclarativeConfigPropertiesBridge.java @@ -182,7 +182,10 @@ static String[] getSegments(String property) { property = property.substring(OTEL_INSTRUMENTATION_PREFIX.length()); } // Split the remainder of the property on "." - return property.replace('-', '_').split("\\."); + return property + .replaceAll("experimental[.-]([^.]+)", "$1/development") + .replace('-', '_') + .split("\\."); } private String translateProperty(String property) { diff --git a/declarative-config-bridge/src/test/java/io/opentelemetry/instrumentation/config/bridge/DeclarativeConfigPropertiesBridgeTest.java b/declarative-config-bridge/src/test/java/io/opentelemetry/instrumentation/config/bridge/DeclarativeConfigPropertiesBridgeTest.java index 29f9d424cd9d..360293eb8ee2 100644 --- a/declarative-config-bridge/src/test/java/io/opentelemetry/instrumentation/config/bridge/DeclarativeConfigPropertiesBridgeTest.java +++ b/declarative-config-bridge/src/test/java/io/opentelemetry/instrumentation/config/bridge/DeclarativeConfigPropertiesBridgeTest.java @@ -60,7 +60,7 @@ void getProperties() { .isTrue(); // common cases - assertThat(bridge.getBoolean("otel.instrumentation.runtime-telemetry.enabled")).isFalse(); + assertThat(bridge.getBoolean("otel.instrumentation.runtime-telemetry.enabled")).isTrue(); // check all the types Map expectedMap = new HashMap<>(); @@ -141,4 +141,13 @@ void agentTranslation() { assertThat(bridge.getBoolean("otel.javaagent.experimental.indy")).isTrue(); assertThat(bridge.getString("otel.javaagent.logging")).isEqualTo("application"); } + + @Test + void developmentTranslation() { + String prefix = "otel.instrumentation.runtime-telemetry"; + assertThat(bridge.getBoolean(prefix + ".experimental-gc-profiler.experimental-metrics")) + .isTrue(); + assertThat(bridge.getBoolean(prefix + ".experimental.gc-profiler.experimental.metrics")) + .isTrue(); + } } diff --git a/declarative-config-bridge/src/test/resources/config.yaml b/declarative-config-bridge/src/test/resources/config.yaml index 5f8bbd1943b0..1204924c5063 100644 --- a/declarative-config-bridge/src/test/resources/config.yaml +++ b/declarative-config-bridge/src/test/resources/config.yaml @@ -5,10 +5,11 @@ instrumentation/development: full_name: preserved: true agent: - experimental: - indy: true + indy/development: true runtime_telemetry: - enabled: false + enabled: true + gc_profiler/development: + metrics/development: true example_instrumentation: string_key: value bool_key: true From 3adc07eda44f1ec4bd6c3b2b226b57934eecb5b7 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Thu, 11 Dec 2025 13:52:52 +0100 Subject: [PATCH 2/6] translate /development in DeclarativeConfigPropertiesBridge --- .../config/bridge/DeclarativeConfigPropertiesBridge.java | 2 +- .../config/bridge/DeclarativeConfigPropertiesBridgeTest.java | 5 +++++ declarative-config-bridge/src/test/resources/config.yaml | 1 + 3 files changed, 7 insertions(+), 1 deletion(-) diff --git a/declarative-config-bridge/src/main/java/io/opentelemetry/instrumentation/config/bridge/DeclarativeConfigPropertiesBridge.java b/declarative-config-bridge/src/main/java/io/opentelemetry/instrumentation/config/bridge/DeclarativeConfigPropertiesBridge.java index fac8904a5cf3..0635cfce9480 100644 --- a/declarative-config-bridge/src/main/java/io/opentelemetry/instrumentation/config/bridge/DeclarativeConfigPropertiesBridge.java +++ b/declarative-config-bridge/src/main/java/io/opentelemetry/instrumentation/config/bridge/DeclarativeConfigPropertiesBridge.java @@ -183,7 +183,7 @@ static String[] getSegments(String property) { } // Split the remainder of the property on "." return property - .replaceAll("experimental[.-]([^.]+)", "$1/development") + .replaceAll(".experimental[.-]([^.]+)", ".$1/development") .replace('-', '_') .split("\\."); } diff --git a/declarative-config-bridge/src/test/java/io/opentelemetry/instrumentation/config/bridge/DeclarativeConfigPropertiesBridgeTest.java b/declarative-config-bridge/src/test/java/io/opentelemetry/instrumentation/config/bridge/DeclarativeConfigPropertiesBridgeTest.java index 360293eb8ee2..d4718a4fa40c 100644 --- a/declarative-config-bridge/src/test/java/io/opentelemetry/instrumentation/config/bridge/DeclarativeConfigPropertiesBridgeTest.java +++ b/declarative-config-bridge/src/test/java/io/opentelemetry/instrumentation/config/bridge/DeclarativeConfigPropertiesBridgeTest.java @@ -149,5 +149,10 @@ void developmentTranslation() { .isTrue(); assertThat(bridge.getBoolean(prefix + ".experimental.gc-profiler.experimental.metrics")) .isTrue(); + + // experimental in the middle of the property name should be preserved + assertThat( + bridge.getBoolean("otel.instrumentation.runtime-telemetry.emit-experimental-telemetry")) + .isTrue(); } } diff --git a/declarative-config-bridge/src/test/resources/config.yaml b/declarative-config-bridge/src/test/resources/config.yaml index 1204924c5063..808c5db21b19 100644 --- a/declarative-config-bridge/src/test/resources/config.yaml +++ b/declarative-config-bridge/src/test/resources/config.yaml @@ -7,6 +7,7 @@ instrumentation/development: agent: indy/development: true runtime_telemetry: + emit_experimental_telemetry: true enabled: true gc_profiler/development: metrics/development: true From ca58effe63edef7260e0ec4841830ed7a37ed9a4 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Thu, 11 Dec 2025 14:03:12 +0100 Subject: [PATCH 3/6] translate internal "experimental", too --- .../config/bridge/DeclarativeConfigPropertiesBridge.java | 6 ++++-- declarative-config-bridge/src/test/resources/config.yaml | 2 +- .../src/test/resources/declarative-config.yaml | 2 +- .../src/testDeclarativeConfig/resources/application.yaml | 4 ++-- .../spring-boot-3.2/src/main/resources/application.yaml | 4 ++-- 5 files changed, 10 insertions(+), 8 deletions(-) diff --git a/declarative-config-bridge/src/main/java/io/opentelemetry/instrumentation/config/bridge/DeclarativeConfigPropertiesBridge.java b/declarative-config-bridge/src/main/java/io/opentelemetry/instrumentation/config/bridge/DeclarativeConfigPropertiesBridge.java index 0635cfce9480..acfc01ab23c8 100644 --- a/declarative-config-bridge/src/main/java/io/opentelemetry/instrumentation/config/bridge/DeclarativeConfigPropertiesBridge.java +++ b/declarative-config-bridge/src/main/java/io/opentelemetry/instrumentation/config/bridge/DeclarativeConfigPropertiesBridge.java @@ -182,10 +182,12 @@ static String[] getSegments(String property) { property = property.substring(OTEL_INSTRUMENTATION_PREFIX.length()); } // Split the remainder of the property on "." - return property - .replaceAll(".experimental[.-]([^.]+)", ".$1/development") + String[] s = property + .replaceAll("\\.experimental[.-]([^.]+)", ".$1/development") + .replaceAll("\\.([^.]+experimental[^.]+)", ".$1/development") .replace('-', '_') .split("\\."); + return s; } private String translateProperty(String property) { diff --git a/declarative-config-bridge/src/test/resources/config.yaml b/declarative-config-bridge/src/test/resources/config.yaml index 808c5db21b19..9f3b591c4cfb 100644 --- a/declarative-config-bridge/src/test/resources/config.yaml +++ b/declarative-config-bridge/src/test/resources/config.yaml @@ -7,7 +7,7 @@ instrumentation/development: agent: indy/development: true runtime_telemetry: - emit_experimental_telemetry: true + emit_experimental_telemetry/development: true enabled: true gc_profiler/development: metrics/development: true diff --git a/instrumentation-api-incubator/javaagent-testing/src/test/resources/declarative-config.yaml b/instrumentation-api-incubator/javaagent-testing/src/test/resources/declarative-config.yaml index 8c6c7dbe60ef..18379249f803 100644 --- a/instrumentation-api-incubator/javaagent-testing/src/test/resources/declarative-config.yaml +++ b/instrumentation-api-incubator/javaagent-testing/src/test/resources/declarative-config.yaml @@ -5,7 +5,7 @@ instrumentation/development: java: http: client: - emit_experimental_telemetry: true + emit_experimental_telemetry/development: true url_template_rules: - pattern: "http://localhost:.*/hello/.*" template: "/hello/*" diff --git a/smoke-tests-otel-starter/spring-boot-2/src/testDeclarativeConfig/resources/application.yaml b/smoke-tests-otel-starter/spring-boot-2/src/testDeclarativeConfig/resources/application.yaml index 6b24c0ee67fa..6a552dba4218 100644 --- a/smoke-tests-otel-starter/spring-boot-2/src/testDeclarativeConfig/resources/application.yaml +++ b/smoke-tests-otel-starter/spring-boot-2/src/testDeclarativeConfig/resources/application.yaml @@ -41,7 +41,7 @@ otel: instrumentation/development: java: runtime-telemetry: - emit_experimental_telemetry: true + emit_experimental_telemetry/development: true http: client: - emit_experimental_telemetry: true + emit_experimental_telemetry/development: true diff --git a/smoke-tests-otel-starter/spring-boot-3.2/src/main/resources/application.yaml b/smoke-tests-otel-starter/spring-boot-3.2/src/main/resources/application.yaml index 0533d63c9b88..924a63db7be1 100644 --- a/smoke-tests-otel-starter/spring-boot-3.2/src/main/resources/application.yaml +++ b/smoke-tests-otel-starter/spring-boot-3.2/src/main/resources/application.yaml @@ -41,7 +41,7 @@ otel: instrumentation/development: java: runtime-telemetry: - emit_experimental_telemetry: true + emit_experimental_telemetry/development: true http: client: - emit_experimental_telemetry: true + emit_experimental_telemetry/development: true From fa83b26c16101755d771ea1cd6ffa2a99cae893b Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Thu, 11 Dec 2025 14:04:34 +0100 Subject: [PATCH 4/6] translate internal "experimental", too --- .../config/bridge/DeclarativeConfigPropertiesBridge.java | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/declarative-config-bridge/src/main/java/io/opentelemetry/instrumentation/config/bridge/DeclarativeConfigPropertiesBridge.java b/declarative-config-bridge/src/main/java/io/opentelemetry/instrumentation/config/bridge/DeclarativeConfigPropertiesBridge.java index acfc01ab23c8..a1efbcdf1e1f 100644 --- a/declarative-config-bridge/src/main/java/io/opentelemetry/instrumentation/config/bridge/DeclarativeConfigPropertiesBridge.java +++ b/declarative-config-bridge/src/main/java/io/opentelemetry/instrumentation/config/bridge/DeclarativeConfigPropertiesBridge.java @@ -182,12 +182,11 @@ static String[] getSegments(String property) { property = property.substring(OTEL_INSTRUMENTATION_PREFIX.length()); } // Split the remainder of the property on "." - String[] s = property + return property .replaceAll("\\.experimental[.-]([^.]+)", ".$1/development") .replaceAll("\\.([^.]+experimental[^.]+)", ".$1/development") .replace('-', '_') .split("\\."); - return s; } private String translateProperty(String property) { From 93b7b687df9097cc6ae1582e91a8ddf2de47de45 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Thu, 11 Dec 2025 15:23:17 +0100 Subject: [PATCH 5/6] use pre-compiled --- .../bridge/DeclarativeConfigPropertiesBridge.java | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/declarative-config-bridge/src/main/java/io/opentelemetry/instrumentation/config/bridge/DeclarativeConfigPropertiesBridge.java b/declarative-config-bridge/src/main/java/io/opentelemetry/instrumentation/config/bridge/DeclarativeConfigPropertiesBridge.java index a1efbcdf1e1f..8e2667dd5cef 100644 --- a/declarative-config-bridge/src/main/java/io/opentelemetry/instrumentation/config/bridge/DeclarativeConfigPropertiesBridge.java +++ b/declarative-config-bridge/src/main/java/io/opentelemetry/instrumentation/config/bridge/DeclarativeConfigPropertiesBridge.java @@ -17,6 +17,7 @@ import java.util.Objects; import java.util.function.BiFunction; import java.util.function.Function; +import java.util.regex.Pattern; import javax.annotation.Nullable; /** @@ -51,6 +52,9 @@ final class DeclarativeConfigPropertiesBridge implements ConfigProperties { private static final String OTEL_INSTRUMENTATION_PREFIX = "otel.instrumentation."; + private static final Pattern EXPERIMENTAL_PATTERN = Pattern.compile("\\.experimental[.-]([^.]+)"); + private static final Pattern EXPERIMENTAL_IN_NAME_PATTERN = + Pattern.compile("\\.([^.]+experimental[^.]+)"); private final DeclarativeConfigProperties baseNode; @@ -182,9 +186,9 @@ static String[] getSegments(String property) { property = property.substring(OTEL_INSTRUMENTATION_PREFIX.length()); } // Split the remainder of the property on "." - return property - .replaceAll("\\.experimental[.-]([^.]+)", ".$1/development") - .replaceAll("\\.([^.]+experimental[^.]+)", ".$1/development") + return EXPERIMENTAL_IN_NAME_PATTERN + .matcher(EXPERIMENTAL_PATTERN.matcher(property).replaceAll(".$1/development")) + .replaceAll(".$1/development") .replace('-', '_') .split("\\."); } From 35219d6c954d0db2cbabfd1811d36ecdc6c87aca Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Thu, 11 Dec 2025 15:26:32 +0100 Subject: [PATCH 6/6] clean up --- .../DeclarativeConfigPropertiesBridge.java | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/declarative-config-bridge/src/main/java/io/opentelemetry/instrumentation/config/bridge/DeclarativeConfigPropertiesBridge.java b/declarative-config-bridge/src/main/java/io/opentelemetry/instrumentation/config/bridge/DeclarativeConfigPropertiesBridge.java index 8e2667dd5cef..314c99d6b5ed 100644 --- a/declarative-config-bridge/src/main/java/io/opentelemetry/instrumentation/config/bridge/DeclarativeConfigPropertiesBridge.java +++ b/declarative-config-bridge/src/main/java/io/opentelemetry/instrumentation/config/bridge/DeclarativeConfigPropertiesBridge.java @@ -182,15 +182,22 @@ private T getPropertyValue( } static String[] getSegments(String property) { + // Remove "otel.instrumentation." prefix if present if (property.startsWith(OTEL_INSTRUMENTATION_PREFIX)) { property = property.substring(OTEL_INSTRUMENTATION_PREFIX.length()); } - // Split the remainder of the property on "." - return EXPERIMENTAL_IN_NAME_PATTERN - .matcher(EXPERIMENTAL_PATTERN.matcher(property).replaceAll(".$1/development")) - .replaceAll(".$1/development") - .replace('-', '_') - .split("\\."); + + // Transform experimental patterns: + // - ".experimental-foo" or ".experimental.foo" becomes ".foo/development" + String transformed = EXPERIMENTAL_PATTERN.matcher(property).replaceAll(".$1/development"); + // - ".foo-experimental-bar" becomes ".foo_experimental_bar/development" + transformed = EXPERIMENTAL_IN_NAME_PATTERN.matcher(transformed).replaceAll(".$1/development"); + + // Replace dashes with underscores for property normalization + transformed = transformed.replace('-', '_'); + + // Split into segments on dots + return transformed.split("\\."); } private String translateProperty(String property) {