diff --git a/declarative-config-bridge/src/main/java/io/opentelemetry/instrumentation/config/bridge/ConfigPropertiesBackedDeclarativeConfigProperties.java b/declarative-config-bridge/src/main/java/io/opentelemetry/instrumentation/config/bridge/ConfigPropertiesBackedDeclarativeConfigProperties.java index 744098e56841..4745ed03605c 100644 --- a/declarative-config-bridge/src/main/java/io/opentelemetry/instrumentation/config/bridge/ConfigPropertiesBackedDeclarativeConfigProperties.java +++ b/declarative-config-bridge/src/main/java/io/opentelemetry/instrumentation/config/bridge/ConfigPropertiesBackedDeclarativeConfigProperties.java @@ -30,12 +30,6 @@ public final class ConfigPropertiesBackedDeclarativeConfigProperties private static final String JAVA_COMMON_SERVICE_PEER_MAPPING = "java.common.service_peer_mapping"; - private static final String AGENT_INSTRUMENTATION_MODE = "java.agent.instrumentation_mode"; - private static final String SPRING_STARTER_INSTRUMENTATION_MODE = - "java.spring_starter.instrumentation_mode"; - private static final String COMMON_DEFAULT_ENABLED = - "otel.instrumentation.common.default-enabled"; - private static final Map SPECIAL_MAPPINGS; static { @@ -114,17 +108,6 @@ private ConfigPropertiesBackedDeclarativeConfigProperties( @Nullable @Override public String getString(String name) { - String fullPath = pathWithName(name); - - if (fullPath.equals(AGENT_INSTRUMENTATION_MODE) - || fullPath.equals(SPRING_STARTER_INSTRUMENTATION_MODE)) { - Boolean value = configProperties.getBoolean(COMMON_DEFAULT_ENABLED); - if (value != null) { - return value ? "default" : "none"; - } - return null; - } - return configProperties.getString(resolvePropertyKey(name)); } @@ -240,15 +223,7 @@ private String resolvePropertyKey(String name) { translatedPath.append(translateName(segments[i])); } - String translated = translatedPath.toString(); - - // Handle agent prefix: java.agent.* → otel.javaagent.* - if (translated.startsWith("agent.")) { - return "otel.java" + translated; - } - - // Standard mapping - return "otel.instrumentation." + translated; + return "otel.instrumentation." + translatedPath; } private String pathWithName(String name) { 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 ce3f261eb037..2494b1ad7188 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 @@ -5,7 +5,6 @@ package io.opentelemetry.instrumentation.config.bridge; -import static io.opentelemetry.api.incubator.config.DeclarativeConfigProperties.empty; import static java.util.Collections.emptyList; import static java.util.Collections.emptyMap; import static java.util.Objects.requireNonNull; @@ -171,7 +170,7 @@ private T getPropertyValue( DeclarativeConfigProperties target = baseNode; if (segments.length > 1) { for (int i = 0; i < segments.length - 1; i++) { - target = target.getStructured(segments[i], empty()); + target = target.get(segments[i]); } } String lastPart = segments[segments.length - 1]; diff --git a/declarative-config-bridge/src/test/java/io/opentelemetry/instrumentation/config/bridge/ConfigPropertiesBackedDeclarativeConfigPropertiesTest.java b/declarative-config-bridge/src/test/java/io/opentelemetry/instrumentation/config/bridge/ConfigPropertiesBackedDeclarativeConfigPropertiesTest.java index 7d43c8be39f0..92176a14d2f2 100644 --- a/declarative-config-bridge/src/test/java/io/opentelemetry/instrumentation/config/bridge/ConfigPropertiesBackedDeclarativeConfigPropertiesTest.java +++ b/declarative-config-bridge/src/test/java/io/opentelemetry/instrumentation/config/bridge/ConfigPropertiesBackedDeclarativeConfigPropertiesTest.java @@ -76,15 +76,6 @@ void testTranslateName_withExperimentalInMiddle() { .isTrue(); } - @Test - void testAgentPrefix() { - DeclarativeConfigProperties config = createConfig("otel.javaagent.experimental.indy", "true"); - - assertThat(config.getStructured("java").getStructured("agent").getBoolean("indy/development")) - .isNotNull() - .isTrue(); - } - @Test void testJmxPrefix() { DeclarativeConfigProperties config = createConfig("otel.jmx.enabled", "true"); @@ -243,61 +234,6 @@ void testWithoutJavaPrefix_doesNotMatch() { .isNull(); } - @Test - void testAgentInstrumentationMode_getString_booleanTrue() { - DeclarativeConfigProperties config = - createConfig("otel.instrumentation.common.default-enabled", "true"); - - assertThat( - config.getStructured("java").getStructured("agent").getString("instrumentation_mode")) - .isEqualTo("default"); - } - - @Test - void testAgentInstrumentationMode_getString_booleanFalse() { - DeclarativeConfigProperties config = - createConfig("otel.instrumentation.common.default-enabled", "false"); - - assertThat( - config.getStructured("java").getStructured("agent").getString("instrumentation_mode")) - .isEqualTo("none"); - } - - @Test - void testSpringStarterInstrumentationMode_getString_booleanTrue() { - DeclarativeConfigProperties config = - createConfig("otel.instrumentation.common.default-enabled", "true"); - - assertThat( - config - .getStructured("java") - .getStructured("spring_starter") - .getString("instrumentation_mode")) - .isEqualTo("default"); - } - - @Test - void testSpringStarterInstrumentationMode_getString_booleanFalse() { - DeclarativeConfigProperties config = - createConfig("otel.instrumentation.common.default-enabled", "false"); - - assertThat( - config - .getStructured("java") - .getStructured("spring_starter") - .getString("instrumentation_mode")) - .isEqualTo("none"); - } - - @Test - void testAgentInstrumentationMode_notSet() { - DeclarativeConfigProperties config = createConfig("some.other.property", "value"); - - assertThat( - config.getStructured("java").getStructured("agent").getString("instrumentation_mode")) - .isNull(); - } - private static DeclarativeConfigProperties createConfig(String key, String value) { Map properties = new HashMap<>(); properties.put(key, value); 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 a902d0a216df..25f0a8afaee7 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 @@ -5,12 +5,10 @@ package io.opentelemetry.instrumentation.config.bridge; -import static java.util.Objects.requireNonNull; import static org.assertj.core.api.Assertions.assertThat; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfiguration; -import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalInstrumentationModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel; import io.opentelemetry.sdk.internal.SdkConfigProvider; import java.time.Duration; @@ -23,22 +21,10 @@ class DeclarativeConfigPropertiesBridgeTest { private ConfigProperties bridge; - private ConfigProperties emptyBridge; @BeforeEach void setup() { bridge = create(new DeclarativeConfigPropertiesBridgeBuilder()); - - OpenTelemetryConfigurationModel emptyModel = - new OpenTelemetryConfigurationModel() - .withAdditionalProperty( - "instrumentation/development", new ExperimentalInstrumentationModel()); - SdkConfigProvider emptyConfigProvider = - SdkConfigProvider.create(DeclarativeConfiguration.toConfigProperties(emptyModel)); - emptyBridge = - new DeclarativeConfigPropertiesBridgeBuilder() - .buildFromInstrumentationConfig( - requireNonNull(emptyConfigProvider.getInstrumentationConfig())); } private static ConfigProperties create(DeclarativeConfigPropertiesBridgeBuilder builder) { @@ -58,9 +44,6 @@ void getProperties() { // asking for properties which don't exist or inaccessible shouldn't result in an error assertThat(bridge.getString("file_format")).isNull(); assertThat(bridge.getString("file_format", "foo")).isEqualTo("foo"); - assertThat(emptyBridge.getBoolean("otel.instrumentation.common.default-enabled")).isNull(); - assertThat(emptyBridge.getBoolean("otel.instrumentation.common.default-enabled", true)) - .isTrue(); // common cases assertThat(bridge.getBoolean("otel.instrumentation.runtime-telemetry.enabled")).isFalse(); diff --git a/instrumentation/oshi/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/oshi/OshiMetricsInstaller.java b/instrumentation/oshi/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/oshi/OshiMetricsInstaller.java index bbe976063531..0883a9bb7459 100644 --- a/instrumentation/oshi/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/oshi/OshiMetricsInstaller.java +++ b/instrumentation/oshi/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/oshi/OshiMetricsInstaller.java @@ -6,9 +6,8 @@ package io.opentelemetry.javaagent.instrumentation.oshi; import com.google.auto.service.AutoService; -import io.opentelemetry.instrumentation.api.incubator.config.internal.DeclarativeConfigUtil; import io.opentelemetry.javaagent.extension.AgentListener; -import io.opentelemetry.javaagent.tooling.config.AgentConfig; +import io.opentelemetry.javaagent.extension.instrumentation.internal.AgentDistributionConfig; import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk; import java.lang.reflect.Method; @@ -21,11 +20,8 @@ public class OshiMetricsInstaller implements AgentListener { @Override public void afterAgent(AutoConfiguredOpenTelemetrySdk autoConfiguredSdk) { - boolean enabled = - DeclarativeConfigUtil.getInstrumentationConfig( - autoConfiguredSdk.getOpenTelemetrySdk(), "oshi") - .getBoolean("enabled", AgentConfig.instrumentationMode().equals("default")); - if (!enabled) { + AgentDistributionConfig config = AgentDistributionConfig.get(); + if (!config.isInstrumentationEnabled("oshi")) { return; } diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java17/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/runtimemetrics/java17/Java17RuntimeMetricsInstaller.java b/instrumentation/runtime-telemetry/runtime-telemetry-java17/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/runtimemetrics/java17/Java17RuntimeMetricsInstaller.java index ba2b1d0de1e2..3aac8a9ebab5 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java17/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/runtimemetrics/java17/Java17RuntimeMetricsInstaller.java +++ b/instrumentation/runtime-telemetry/runtime-telemetry-java17/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/runtimemetrics/java17/Java17RuntimeMetricsInstaller.java @@ -10,7 +10,7 @@ import io.opentelemetry.instrumentation.runtimemetrics.java17.RuntimeMetrics; import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.RuntimeMetricsConfigUtil; import io.opentelemetry.javaagent.extension.AgentListener; -import io.opentelemetry.javaagent.tooling.config.AgentConfig; +import io.opentelemetry.javaagent.extension.instrumentation.internal.AgentDistributionConfig; import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk; /** An {@link AgentListener} that enables runtime metrics during agent startup. */ @@ -23,7 +23,7 @@ public void afterAgent(AutoConfiguredOpenTelemetrySdk autoConfiguredSdk) { RuntimeMetricsConfigUtil.configure( RuntimeMetrics.builder(GlobalOpenTelemetry.get()), GlobalOpenTelemetry.get(), - AgentConfig.instrumentationMode()); + AgentDistributionConfig.get().isInstrumentationDefaultEnabled()); if (runtimeMetrics != null) { Runtime.getRuntime() .addShutdownHook( diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/RuntimeMetricsConfigUtil.java b/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/RuntimeMetricsConfigUtil.java index 221e1e86db89..171561f4f4c6 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/RuntimeMetricsConfigUtil.java +++ b/instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/RuntimeMetricsConfigUtil.java @@ -20,7 +20,7 @@ private RuntimeMetricsConfigUtil() {} @Nullable public static RuntimeMetrics configure( - RuntimeMetricsBuilder builder, OpenTelemetry openTelemetry, String instrumentationMode) { + RuntimeMetricsBuilder builder, OpenTelemetry openTelemetry, boolean defaultEnabled) { /* By default, don't use any JFR metrics. May change this once semantic conventions are updated. If enabled, default to only the metrics not already covered by runtime-telemetry-java8 @@ -33,7 +33,7 @@ public static RuntimeMetrics configure( .getBoolean("enabled", false)) { // default configuration } else if (DeclarativeConfigUtil.getInstrumentationConfig(openTelemetry, "runtime_telemetry") - .getBoolean("enabled", instrumentationMode.equals("default"))) { + .getBoolean("enabled", defaultEnabled)) { // This only uses metrics gathered by JMX builder.disableAllFeatures(); } else { diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java8/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/runtimemetrics/java8/Java8RuntimeMetricsInstaller.java b/instrumentation/runtime-telemetry/runtime-telemetry-java8/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/runtimemetrics/java8/Java8RuntimeMetricsInstaller.java index 4b6a8c5b7030..a2d185be53b7 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java8/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/runtimemetrics/java8/Java8RuntimeMetricsInstaller.java +++ b/instrumentation/runtime-telemetry/runtime-telemetry-java8/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/runtimemetrics/java8/Java8RuntimeMetricsInstaller.java @@ -10,7 +10,7 @@ import io.opentelemetry.instrumentation.runtimemetrics.java8.RuntimeMetrics; import io.opentelemetry.instrumentation.runtimemetrics.java8.internal.RuntimeMetricsConfigUtil; import io.opentelemetry.javaagent.extension.AgentListener; -import io.opentelemetry.javaagent.tooling.config.AgentConfig; +import io.opentelemetry.javaagent.extension.instrumentation.internal.AgentDistributionConfig; import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk; /** An {@link AgentListener} that enables runtime metrics during agent startup. */ @@ -27,7 +27,7 @@ public void afterAgent(AutoConfiguredOpenTelemetrySdk autoConfiguredSdk) { RuntimeMetricsConfigUtil.configure( RuntimeMetrics.builder(GlobalOpenTelemetry.get()), GlobalOpenTelemetry.get(), - AgentConfig.instrumentationMode()); + AgentDistributionConfig.get().isInstrumentationDefaultEnabled()); if (runtimeMetrics != null) { Runtime.getRuntime() .addShutdownHook( diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/RuntimeMetricsConfigUtil.java b/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/RuntimeMetricsConfigUtil.java index 2e1b4800df63..a62bcfab9eb1 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/RuntimeMetricsConfigUtil.java +++ b/instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/RuntimeMetricsConfigUtil.java @@ -21,10 +21,10 @@ private RuntimeMetricsConfigUtil() {} @Nullable public static RuntimeMetrics configure( - RuntimeMetricsBuilder builder, OpenTelemetry openTelemetry, String instrumentationMode) { + RuntimeMetricsBuilder builder, OpenTelemetry openTelemetry, boolean defaultEnabled) { DeclarativeConfigProperties config = DeclarativeConfigUtil.getInstrumentationConfig(openTelemetry, "runtime_telemetry"); - if (!config.getBoolean("enabled", instrumentationMode.equals("default"))) { + if (!config.getBoolean("enabled", defaultEnabled)) { // nothing is enabled return null; } diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/EarlyConfig.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/EarlyConfig.java index 480320cb2546..4197457cae0e 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/EarlyConfig.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/EarlyConfig.java @@ -5,7 +5,11 @@ package io.opentelemetry.instrumentation.spring.autoconfigure.internal; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; +import static java.util.Collections.emptyList; + +import java.util.Arrays; +import java.util.List; +import org.springframework.boot.context.properties.bind.Binder; import org.springframework.core.env.Environment; /** @@ -18,7 +22,7 @@ private EarlyConfig() {} public static boolean otelEnabled(Environment environment) { boolean disabled = environment.getProperty( - getPropertyName(environment, "otel.sdk.disabled", "otel.disabled"), + isDeclarativeConfig(environment) ? "otel.disabled" : "otel.sdk.disabled", Boolean.class, false); return !disabled; @@ -28,48 +32,51 @@ public static boolean isDeclarativeConfig(Environment environment) { return environment.getProperty("otel.file_format", String.class) != null; } - public static boolean isDefaultEnabled(Environment environment) { + public static boolean isInstrumentationEnabled( + Environment environment, String name, boolean enabledByDefault) { if (isDeclarativeConfig(environment)) { - String mode = - environment.getProperty( - "otel.instrumentation/development.java.spring_starter.instrumentation_mode", - String.class, - "default"); + String snakeCase = name.replace('-', '_'); - switch (mode) { - case "none": - return false; - case "default": - return true; - default: - throw new ConfigurationException("Unknown instrumentation mode: " + mode); + List disabled = + bindList(environment, "otel.distribution.spring_starter.instrumentation.disabled"); + if (disabled.contains(snakeCase)) { + return false; + } + + List enabled = + bindList(environment, "otel.distribution.spring_starter.instrumentation.enabled"); + if (enabled.contains(snakeCase)) { + return true; + } + + if (!enabledByDefault) { + return false; } - } else { return environment.getProperty( - "otel.instrumentation.common.default-enabled", Boolean.class, true); + "otel.distribution.spring_starter.instrumentation.default_enabled", Boolean.class, true); } - } - public static boolean isInstrumentationEnabled( - Environment environment, String name, boolean defaultValue) { - String property = - getPropertyName( - environment, - String.format("otel.instrumentation.%s.enabled", name), - String.format( - "otel.instrumentation/development.java.%s.enabled", name.replace('-', '_'))); - Boolean explicit = environment.getProperty(property, Boolean.class); + Boolean explicit = + environment.getProperty( + String.format("otel.instrumentation.%s.enabled", name), Boolean.class); if (explicit != null) { return explicit; } - if (!defaultValue) { + if (!enabledByDefault) { return false; } - return isDefaultEnabled(environment); + return environment.getProperty( + "otel.instrumentation.common.default-enabled", Boolean.class, true); } - private static String getPropertyName( - Environment environment, String propertyBased, String declarative) { - return isDeclarativeConfig(environment) ? declarative : propertyBased; + // Environment.getProperty(key, List.class) does not handle indexed properties (e.g. + // enabled[0]=spring_web); Binder handles both indexed and comma-separated list formats + private static List bindList(Environment environment, String key) { + // Binder requires canonical property names (lowercase with hyphens, no underscores) + String canonicalKey = key.replace('_', '-'); + return Binder.get(environment) + .bind(canonicalKey, String[].class) + .map(Arrays::asList) + .orElse(emptyList()); } } diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/runtimemetrics/Java17RuntimeMetricsAutoConfiguration.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/runtimemetrics/Java17RuntimeMetricsAutoConfiguration.java index d9e595a82e00..efb8ac7d76a3 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/runtimemetrics/Java17RuntimeMetricsAutoConfiguration.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/runtimemetrics/Java17RuntimeMetricsAutoConfiguration.java @@ -6,11 +6,9 @@ package io.opentelemetry.instrumentation.spring.autoconfigure.internal.instrumentation.runtimemetrics; import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.instrumentation.api.incubator.config.internal.DeclarativeConfigUtil; import io.opentelemetry.instrumentation.runtimemetrics.java17.RuntimeMetrics; import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.RuntimeMetricsConfigUtil; import io.opentelemetry.instrumentation.spring.autoconfigure.internal.ConditionalOnEnabledInstrumentation; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import javax.annotation.Nullable; import javax.annotation.PreDestroy; import org.slf4j.Logger; @@ -54,18 +52,6 @@ public void handleApplicationReadyEvent(ApplicationReadyEvent event) { logger.debug("Use runtime metrics instrumentation for Java 17+"); this.closeable = RuntimeMetricsConfigUtil.configure( - RuntimeMetrics.builder(openTelemetry), - openTelemetry, - instrumentationMode(openTelemetry)); - } - - private static String instrumentationMode(OpenTelemetry openTelemetry) { - String mode = - DeclarativeConfigUtil.getInstrumentationConfig(openTelemetry, "spring_starter") - .getString("instrumentation_mode", "default"); - if (!mode.equals("default") && !mode.equals("none")) { - throw new ConfigurationException("Unknown instrumentation mode: " + mode); - } - return mode; + RuntimeMetrics.builder(openTelemetry), openTelemetry, true); } } diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/runtimemetrics/Java8RuntimeMetricsAutoConfiguration.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/runtimemetrics/Java8RuntimeMetricsAutoConfiguration.java index 7cc748211058..3811afcaa8a4 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/runtimemetrics/Java8RuntimeMetricsAutoConfiguration.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/instrumentation/runtimemetrics/Java8RuntimeMetricsAutoConfiguration.java @@ -6,11 +6,9 @@ package io.opentelemetry.instrumentation.spring.autoconfigure.internal.instrumentation.runtimemetrics; import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.instrumentation.api.incubator.config.internal.DeclarativeConfigUtil; import io.opentelemetry.instrumentation.runtimemetrics.java8.RuntimeMetrics; import io.opentelemetry.instrumentation.runtimemetrics.java8.internal.RuntimeMetricsConfigUtil; import io.opentelemetry.instrumentation.spring.autoconfigure.internal.ConditionalOnEnabledInstrumentation; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import javax.annotation.Nullable; import javax.annotation.PreDestroy; import org.slf4j.Logger; @@ -54,18 +52,6 @@ public void handleApplicationReadyEvent(ApplicationReadyEvent event) { logger.debug("Use runtime metrics instrumentation for Java 8"); this.closeable = RuntimeMetricsConfigUtil.configure( - RuntimeMetrics.builder(openTelemetry), - openTelemetry, - instrumentationMode(openTelemetry)); - } - - private static String instrumentationMode(OpenTelemetry openTelemetry) { - String mode = - DeclarativeConfigUtil.getInstrumentationConfig(openTelemetry, "spring_starter") - .getString("instrumentation_mode", "default"); - if (!mode.equals("default") && !mode.equals("none")) { - throw new ConfigurationException("Unknown instrumentation mode: " + mode); - } - return mode; + RuntimeMetrics.builder(openTelemetry), openTelemetry, true); } } diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/testDeclarativeConfig/java/io/opentelemetry/instrumentation/spring/autoconfigure/DeclarativeConfigTest.java b/instrumentation/spring/spring-boot-autoconfigure/src/testDeclarativeConfig/java/io/opentelemetry/instrumentation/spring/autoconfigure/DeclarativeConfigTest.java index da76066daa51..390f1f61005f 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/testDeclarativeConfig/java/io/opentelemetry/instrumentation/spring/autoconfigure/DeclarativeConfigTest.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/testDeclarativeConfig/java/io/opentelemetry/instrumentation/spring/autoconfigure/DeclarativeConfigTest.java @@ -101,7 +101,7 @@ void shouldNotLoadInstrumentationWhenDefaultIsDisabled() { .withConfiguration(AutoConfigurations.of(SpringWebInstrumentationAutoConfiguration.class)) .withPropertyValues( "otel.file_format=1.0-rc.1", - "otel.instrumentation/development.java.spring_starter.instrumentation_mode=none") + "otel.distribution.spring_starter.instrumentation.default_enabled=false") .run(context -> assertThat(context).doesNotHaveBean("otelRestTemplateBeanPostProcessor")); } @@ -111,8 +111,8 @@ void shouldLoadInstrumentationWhenExplicitlyEnabled() { .withConfiguration(AutoConfigurations.of(SpringWebInstrumentationAutoConfiguration.class)) .withPropertyValues( "otel.file_format=1.0-rc.1", - "otel.instrumentation/development.java.spring_starter.instrumentation_mode=none", - "otel.instrumentation/development.java.spring_web.enabled=true") + "otel.distribution.spring_starter.instrumentation.default_enabled=false", + "otel.distribution.spring_starter.instrumentation.enabled=spring_web") .run(context -> assertThat(context).hasBean("otelRestTemplateBeanPostProcessor")); } @@ -122,8 +122,29 @@ void shouldNotLoadInstrumentationWhenExplicitlyDisabled() { .withConfiguration(AutoConfigurations.of(SpringWebInstrumentationAutoConfiguration.class)) .withPropertyValues( "otel.file_format=1.0-rc.1", - "otel.instrumentation/development.java.spring_starter.instrumentation_mode=none", - "otel.instrumentation/development.java.spring_web.enabled=false") + "otel.distribution.spring_starter.instrumentation.default_enabled=false", + "otel.distribution.spring_starter.instrumentation.disabled=spring_web") + .run(context -> assertThat(context).doesNotHaveBean("otelRestTemplateBeanPostProcessor")); + } + + @Test + void shouldLoadInstrumentationWhenExplicitlyEnabledWithIndexedProperty() { + this.contextRunner + .withConfiguration(AutoConfigurations.of(SpringWebInstrumentationAutoConfiguration.class)) + .withPropertyValues( + "otel.file_format=1.0-rc.1", + "otel.distribution.spring_starter.instrumentation.default_enabled=false", + "otel.distribution.spring_starter.instrumentation.enabled[0]=spring_web") + .run(context -> assertThat(context).hasBean("otelRestTemplateBeanPostProcessor")); + } + + @Test + void shouldNotLoadInstrumentationWhenExplicitlyDisabledWithIndexedProperty() { + this.contextRunner + .withConfiguration(AutoConfigurations.of(SpringWebInstrumentationAutoConfiguration.class)) + .withPropertyValues( + "otel.file_format=1.0-rc.1", + "otel.distribution.spring_starter.instrumentation.disabled[0]=spring_web") .run(context -> assertThat(context).doesNotHaveBean("otelRestTemplateBeanPostProcessor")); } diff --git a/javaagent-extension-api/build.gradle.kts b/javaagent-extension-api/build.gradle.kts index d50a3ef40bd1..93d84f0ffc55 100644 --- a/javaagent-extension-api/build.gradle.kts +++ b/javaagent-extension-api/build.gradle.kts @@ -9,6 +9,7 @@ dependencies { api("io.opentelemetry:opentelemetry-sdk") api("io.opentelemetry:opentelemetry-sdk-extension-autoconfigure-spi") api("net.bytebuddy:byte-buddy-dep") + compileOnly("com.fasterxml.jackson.core:jackson-annotations") implementation(project(":instrumentation-api")) implementation(project(":instrumentation-api-incubator")) diff --git a/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/extension/instrumentation/InstrumentationModule.java b/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/extension/instrumentation/InstrumentationModule.java index 9e50fcbfd1c3..ab160efff0cc 100644 --- a/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/extension/instrumentation/InstrumentationModule.java +++ b/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/extension/instrumentation/InstrumentationModule.java @@ -10,10 +10,8 @@ import static java.util.Collections.unmodifiableSet; import static net.bytebuddy.matcher.ElementMatchers.any; -import io.opentelemetry.api.GlobalOpenTelemetry; -import io.opentelemetry.instrumentation.api.incubator.config.internal.DeclarativeConfigUtil; +import io.opentelemetry.javaagent.extension.instrumentation.internal.AgentDistributionConfig; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; import io.opentelemetry.sdk.autoconfigure.spi.Ordered; import java.util.LinkedHashSet; import java.util.List; @@ -91,13 +89,7 @@ public final String instrumentationName() { * themselves on some other condition. */ public boolean defaultEnabled() { - String mode = - DeclarativeConfigUtil.getInstrumentationConfig(GlobalOpenTelemetry.get(), "agent") - .getString("instrumentation_mode", "default"); - if (!mode.equals("default") && !mode.equals("none")) { - throw new ConfigurationException("Unknown instrumentation mode: " + mode); - } - return mode.equals("default"); + return AgentDistributionConfig.get().isInstrumentationDefaultEnabled(); } /** @@ -179,9 +171,7 @@ private static class IndyConfigurationHolder { private static final boolean indyEnabled; static { - indyEnabled = - DeclarativeConfigUtil.getInstrumentationConfig(GlobalOpenTelemetry.get(), "agent") - .getBoolean("indy/development", false); + indyEnabled = AgentDistributionConfig.get().isIndyEnabled(); if (indyEnabled) { logger.info("Enabled indy for instrumentation modules"); } diff --git a/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/extension/instrumentation/internal/AgentDistributionConfig.java b/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/extension/instrumentation/internal/AgentDistributionConfig.java new file mode 100644 index 000000000000..5324e8662230 --- /dev/null +++ b/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/extension/instrumentation/internal/AgentDistributionConfig.java @@ -0,0 +1,249 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.extension.instrumentation.internal; + +import static java.util.Collections.singletonList; + +import com.fasterxml.jackson.annotation.JsonCreator; +import com.fasterxml.jackson.annotation.JsonProperty; +import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; +import java.util.ArrayList; +import java.util.HashSet; +import java.util.List; +import java.util.Set; + +/** + * Javaagent distribution-specific configuration. + * + *

This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +public class AgentDistributionConfig { + private static volatile AgentDistributionConfig instance = new AgentDistributionConfig(); + + private static volatile boolean initialized; + + private final boolean indyEnabled; + + // This property may be set to force synchronous AgentListener#afterAgent() execution: the + // condition for delaying the AgentListener initialization is pretty broad and in case it covers + // too much javaagent users can file a bug, force sync execution by setting this property to true + // and continue using the javaagent + private final boolean forceSynchronousAgentListeners; + + private final List excludeClasses; + + private final List excludeClassLoaders; + + private final InstrumentationConfig instrumentation; + + public static AgentDistributionConfig get() { + return instance; + } + + // Only used by tests + public static void resetForTest() { + instance = new AgentDistributionConfig(); + initialized = false; + } + + /** + * Creates a new instance for testing or fallback configuration scenarios. + * + *

This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ + public static AgentDistributionConfig create() { + return new AgentDistributionConfig(); + } + + /** + * Creates a new instance from ConfigProperties. + * + *

This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ + public static AgentDistributionConfig fromConfigProperties(ConfigProperties configProperties) { + return new ConfigPropertiesAgentDistributionConfig(configProperties); + } + + public static void set(AgentDistributionConfig distributionConfig) { + if (initialized) { + throw new IllegalStateException("AgentDistributionConfig has already been initialized"); + } + initialized = true; + instance = distributionConfig; + } + + @JsonCreator + AgentDistributionConfig( + @JsonProperty("indy/development") Boolean indyEnabled, + @JsonProperty("force_synchronous_agent_listeners/development") + Boolean forceSynchronousAgentListeners, + @JsonProperty("exclude_classes") List excludeClasses, + @JsonProperty("exclude_class_loaders") List excludeClassLoaders, + @JsonProperty("instrumentation") InstrumentationConfig instrumentation) { + this.indyEnabled = indyEnabled != null ? indyEnabled : false; + this.forceSynchronousAgentListeners = + forceSynchronousAgentListeners != null ? forceSynchronousAgentListeners : false; + this.excludeClasses = + excludeClasses != null ? new ArrayList<>(excludeClasses) : new ArrayList<>(); + this.excludeClassLoaders = + excludeClassLoaders != null ? new ArrayList<>(excludeClassLoaders) : new ArrayList<>(); + this.instrumentation = instrumentation != null ? instrumentation : new InstrumentationConfig(); + } + + // Default constructor for testing + AgentDistributionConfig() { + this(null, null, null, null, null); + } + + /** + * Returns whether instrumentations are enabled by default. + * + * @return {@code true} if instrumentations are enabled by default, {@code false} otherwise + */ + // TODO remove after + // https://github.com/open-telemetry/opentelemetry-java-instrumentation/pull/16087 + public boolean isInstrumentationDefaultEnabled() { + return instrumentation.isDefaultEnabled(); + } + + /** + * Returns whether any of the given instrumentations is enabled, falling back to {@code + * defaultEnabled} if none of the names are explicitly configured. + * + *

Names are checked in order; the first name found in either the disabled or enabled list + * wins. For any given name, disabled takes priority over enabled. + * + * @param names the instrumentation names to check + * @param defaultEnabled the default to use if no name is explicitly configured + * @return {@code true} if the instrumentation is enabled, {@code false} otherwise + */ + public boolean isInstrumentationEnabled(Iterable names, boolean defaultEnabled) { + for (String name : names) { + String normalizedName = name.replace('-', '_'); + if (instrumentation.getDisabled().contains(normalizedName)) { + return false; + } + if (instrumentation.getEnabled().contains(normalizedName)) { + return true; + } + } + return defaultEnabled; + } + + /** + * Returns whether the given instrumentation is enabled, falling back to {@code defaultEnabled} if + * not explicitly configured. + */ + public boolean isInstrumentationEnabled(String name, boolean defaultEnabled) { + return isInstrumentationEnabled(singletonList(name), defaultEnabled); + } + + /** + * Returns whether the given instrumentation is enabled, falling back to {@link + * #isInstrumentationDefaultEnabled()} if not explicitly configured. + */ + public boolean isInstrumentationEnabled(String name) { + return isInstrumentationEnabled(singletonList(name), isInstrumentationDefaultEnabled()); + } + + // Only used by tests + InstrumentationConfig getInstrumentation() { + return instrumentation; + } + + public boolean isIndyEnabled() { + return indyEnabled; + } + + public boolean isForceSynchronousAgentListeners() { + return forceSynchronousAgentListeners; + } + + public List getExcludeClasses() { + return excludeClasses; + } + + public List getExcludeClassLoaders() { + return excludeClassLoaders; + } + + static class InstrumentationConfig { + @JsonProperty("default_enabled") + private final boolean defaultEnabled; + + @JsonProperty("disabled") + private final Set disabled; + + @JsonProperty("enabled") + private final Set enabled; + + @JsonCreator + InstrumentationConfig( + @JsonProperty("default_enabled") Boolean defaultEnabled, + @JsonProperty("disabled") List disabled, + @JsonProperty("enabled") List enabled) { + this.defaultEnabled = defaultEnabled != null ? defaultEnabled : true; + this.disabled = disabled != null ? new HashSet<>(disabled) : new HashSet<>(); + this.enabled = enabled != null ? new HashSet<>(enabled) : new HashSet<>(); + } + + // Default constructor + InstrumentationConfig() { + this(null, null, null); + } + + Set getDisabled() { + return disabled; + } + + Set getEnabled() { + return enabled; + } + + boolean isDefaultEnabled() { + return defaultEnabled; + } + } + + /** + * This class is internal and is hence not for public use. Its APIs are unstable and can change at + * any time. + */ + private static final class ConfigPropertiesAgentDistributionConfig + extends AgentDistributionConfig { + private final ConfigProperties configProperties; + + ConfigPropertiesAgentDistributionConfig(ConfigProperties configProperties) { + super( + configProperties.getBoolean("otel.javaagent.experimental.indy", false), + configProperties.getBoolean( + "otel.javaagent.experimental.force-synchronous-agent-listeners", false), + configProperties.getList("otel.javaagent.exclude-classes"), + configProperties.getList("otel.javaagent.exclude-class-loaders"), + null); + this.configProperties = configProperties; + } + + @Override + public boolean isInstrumentationDefaultEnabled() { + return configProperties.getBoolean("otel.instrumentation.common.default-enabled", true); + } + + @Override + public boolean isInstrumentationEnabled(Iterable names, boolean defaultEnabled) { + for (String name : names) { + Boolean enabled = configProperties.getBoolean("otel.instrumentation." + name + ".enabled"); + if (enabled != null) { + return enabled; + } + } + return defaultEnabled; + } + } +} diff --git a/javaagent-tooling/build.gradle.kts b/javaagent-tooling/build.gradle.kts index c265beb999c0..db5a52415650 100644 --- a/javaagent-tooling/build.gradle.kts +++ b/javaagent-tooling/build.gradle.kts @@ -51,6 +51,7 @@ dependencies { api("net.bytebuddy:byte-buddy-dep") implementation("org.ow2.asm:asm-tree") implementation("org.ow2.asm:asm-util") + implementation("com.fasterxml.jackson.core:jackson-databind") annotationProcessor("com.google.auto.service:auto-service") compileOnly("com.google.auto.service:auto-service-annotations") @@ -62,7 +63,6 @@ dependencies { testImplementation("io.opentelemetry.javaagent:opentelemetry-testing-common") testImplementation("com.google.guava:guava") - testImplementation("com.fasterxml.jackson.core:jackson-databind") } testing { @@ -109,6 +109,24 @@ testing { implementation("uk.org.webcompere:system-stubs-jupiter") } } + + val testDistributionConfig by registering(JvmTestSuite::class) { + dependencies { + implementation(project(":javaagent-extension-api")) + implementation(project(":instrumentation-api-incubator")) + implementation(project(":javaagent-tooling")) + implementation("io.opentelemetry:opentelemetry-sdk-extension-autoconfigure") + } + targets { + all { + testTask.configure { + jvmArgs( + "-Dotel.experimental.config.file=$projectDir/src/testDistributionConfig/resources/distribution-config.yaml" + ) + } + } + } + } } } 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 58572cd1ef4e..344a1b776d63 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,11 +15,9 @@ import static net.bytebuddy.matcher.ElementMatchers.any; import static net.bytebuddy.matcher.ElementMatchers.none; -import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.context.Context; import io.opentelemetry.context.ContextStorage; import io.opentelemetry.context.Scope; -import io.opentelemetry.instrumentation.api.incubator.config.internal.DeclarativeConfigUtil; import io.opentelemetry.instrumentation.api.internal.EmbeddedInstrumentationProperties; import io.opentelemetry.javaagent.bootstrap.AgentClassLoader; import io.opentelemetry.javaagent.bootstrap.BootstrapPackagePrefixesHolder; @@ -35,6 +33,7 @@ import io.opentelemetry.javaagent.bootstrap.internal.sqlcommenter.SqlCommenterCustomizerHolder; import io.opentelemetry.javaagent.extension.AgentListener; import io.opentelemetry.javaagent.extension.ignore.IgnoredTypesConfigurer; +import io.opentelemetry.javaagent.extension.instrumentation.internal.AgentDistributionConfig; import io.opentelemetry.javaagent.extension.instrumentation.internal.EarlyInstrumentationModule; import io.opentelemetry.javaagent.tooling.asyncannotationsupport.WeakRefAsyncOperationEndStrategies; import io.opentelemetry.javaagent.tooling.bootstrap.BootstrapPackagesBuilderImpl; @@ -80,13 +79,6 @@ public class AgentInstaller { private static final Logger logger = Logger.getLogger(AgentInstaller.class.getName()); - // This property may be set to force synchronous AgentListener#afterAgent() execution: the - // condition for delaying the AgentListener initialization is pretty broad and in case it covers - // too much javaagent users can file a bug, force sync execution by setting this property to true - // and continue using the javaagent - private static final String FORCE_SYNCHRONOUS_AGENT_LISTENERS_CONFIG = - "force_synchronous_agent_listeners/development"; - private static final String STRICT_CONTEXT_STRESSOR_MILLIS = "otel.javaagent.testing.strict-context-stressor-millis"; @@ -357,11 +349,10 @@ private static void runAfterAgentListeners( // Once we see the LogManager class loading, it's safe to run AgentListener#afterAgent() because // the application is already setting the global LogManager and AgentListener won't be able // to touch it due to class loader locking. - boolean shouldForceSynchronousAgentListenersCalls = - DeclarativeConfigUtil.getInstrumentationConfig(GlobalOpenTelemetry.get(), "agent") - .getBoolean(FORCE_SYNCHRONOUS_AGENT_LISTENERS_CONFIG, false); boolean javaBefore9 = isJavaBefore9(); - if (!shouldForceSynchronousAgentListenersCalls && javaBefore9 && isAppUsingCustomLogManager()) { + if (!AgentDistributionConfig.get().isForceSynchronousAgentListeners() + && javaBefore9 + && isAppUsingCustomLogManager()) { logger.fine("Custom JUL LogManager detected: delaying AgentListener#afterAgent() calls"); registerClassLoadCallback( "java.util.logging.LogManager", diff --git a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/OpenTelemetryInstaller.java b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/OpenTelemetryInstaller.java index 4623f3ae083a..ef5e7ef177e3 100644 --- a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/OpenTelemetryInstaller.java +++ b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/OpenTelemetryInstaller.java @@ -8,6 +8,7 @@ import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.instrumentation.config.bridge.ConfigPropertiesBackedConfigProvider; import io.opentelemetry.javaagent.bootstrap.OpenTelemetrySdkAccess; +import io.opentelemetry.javaagent.extension.instrumentation.internal.AgentDistributionConfig; import io.opentelemetry.sdk.OpenTelemetrySdk; import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk; import io.opentelemetry.sdk.autoconfigure.SdkAutoconfigureAccess; @@ -34,12 +35,15 @@ public static AutoConfiguredOpenTelemetrySdk installOpenTelemetrySdk( .build(); OpenTelemetrySdk sdk = autoConfiguredSdk.getOpenTelemetrySdk(); ConfigProperties configProperties = AutoConfigureUtil.getConfig(autoConfiguredSdk); - if (configProperties != null) { + boolean declarativeConfigUsed = configProperties == null; + + if (!declarativeConfigUsed) { // Provide a fake declarative configuration based on config properties // so that declarative configuration API can be used everywhere sdk = new ExtendedOpenTelemetrySdkWrapper( sdk, ConfigPropertiesBackedConfigProvider.create(configProperties)); + AgentDistributionConfig.set(AgentDistributionConfig.fromConfigProperties(configProperties)); } setForceFlush(sdk); diff --git a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/AgentConfig.java b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/AgentConfig.java deleted file mode 100644 index 10d2af1220c3..000000000000 --- a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/AgentConfig.java +++ /dev/null @@ -1,25 +0,0 @@ -/* - * Copyright The OpenTelemetry Authors - * SPDX-License-Identifier: Apache-2.0 - */ - -package io.opentelemetry.javaagent.tooling.config; - -import io.opentelemetry.api.GlobalOpenTelemetry; -import io.opentelemetry.instrumentation.api.incubator.config.internal.DeclarativeConfigUtil; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException; - -public final class AgentConfig { - - public static String instrumentationMode() { - String mode = - DeclarativeConfigUtil.getInstrumentationConfig(GlobalOpenTelemetry.get(), "agent") - .getString("instrumentation_mode", "default"); - if (!mode.equals("default") && !mode.equals("none")) { - throw new ConfigurationException("Unknown instrumentation mode: " + mode); - } - return mode; - } - - private AgentConfig() {} -} diff --git a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/JavaagentDistributionAccessCustomizerProvider.java b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/JavaagentDistributionAccessCustomizerProvider.java new file mode 100644 index 000000000000..b8e18d819761 --- /dev/null +++ b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/config/JavaagentDistributionAccessCustomizerProvider.java @@ -0,0 +1,75 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.tooling.config; + +import com.fasterxml.jackson.core.JsonParser; +import com.fasterxml.jackson.databind.DeserializationContext; +import com.fasterxml.jackson.databind.JsonDeserializer; +import com.fasterxml.jackson.databind.ObjectMapper; +import com.fasterxml.jackson.databind.deser.DeserializationProblemHandler; +import com.google.auto.service.AutoService; +import io.opentelemetry.api.incubator.config.ConfigProvider; +import io.opentelemetry.javaagent.extension.instrumentation.internal.AgentDistributionConfig; +import io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfigurationCustomizer; +import io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfigurationCustomizerProvider; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.DistributionModel; +import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.DistributionPropertyModel; +import java.io.IOException; +import java.util.logging.Level; +import java.util.logging.Logger; + +/** + * Allows access to the Javaagent distribution node, which cannot be accessed using the {@link + * ConfigProvider} API. + */ +@AutoService(DeclarativeConfigurationCustomizerProvider.class) +public final class JavaagentDistributionAccessCustomizerProvider + implements DeclarativeConfigurationCustomizerProvider { + + private static final Logger logger = + Logger.getLogger(JavaagentDistributionAccessCustomizerProvider.class.getName()); + + private static final ObjectMapper MAPPER = + new ObjectMapper() + .addHandler( + new DeserializationProblemHandler() { + @Override + public boolean handleUnknownProperty( + DeserializationContext ctxt, + JsonParser p, + JsonDeserializer deserializer, + Object beanOrClass, + String propertyName) + throws IOException { + logger.warning("Unknown distribution.javaagent property: " + propertyName); + p.skipChildren(); + return true; + } + }); + + @Override + public void customize(DeclarativeConfigurationCustomizer customizer) { + customizer.addModelCustomizer( + model -> { + AgentDistributionConfig.set(parseConfig(model.getDistribution())); + return model; + }); + } + + private static AgentDistributionConfig parseConfig(DistributionModel distribution) { + if (distribution != null) { + DistributionPropertyModel javaagent = distribution.getAdditionalProperties().get("javaagent"); + if (javaagent != null) { + try { + return MAPPER.convertValue(javaagent, AgentDistributionConfig.class); + } catch (IllegalArgumentException e) { + logger.log(Level.WARNING, "Failed to parse distribution.javaagent configuration", e); + } + } + } + return AgentDistributionConfig.create(); + } +} diff --git a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/ignore/AdditionalLibraryIgnoredTypesConfigurer.java b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/ignore/AdditionalLibraryIgnoredTypesConfigurer.java index 04bad0454bdf..90fde6aab12b 100644 --- a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/ignore/AdditionalLibraryIgnoredTypesConfigurer.java +++ b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/ignore/AdditionalLibraryIgnoredTypesConfigurer.java @@ -6,8 +6,6 @@ package io.opentelemetry.javaagent.tooling.ignore; import com.google.auto.service.AutoService; -import io.opentelemetry.api.GlobalOpenTelemetry; -import io.opentelemetry.instrumentation.api.incubator.config.internal.DeclarativeConfigUtil; import io.opentelemetry.javaagent.extension.ignore.IgnoredTypesBuilder; import io.opentelemetry.javaagent.extension.ignore.IgnoredTypesConfigurer; @@ -22,17 +20,15 @@ @AutoService(IgnoredTypesConfigurer.class) public class AdditionalLibraryIgnoredTypesConfigurer implements IgnoredTypesConfigurer { + // We set this system property when running the agent with unit tests to allow verifying that we + // don't ignore libraries that we actually attempt to instrument. It means either the list is + // wrong or a type matcher is. + private static final String ADDITIONAL_LIBRARY_IGNORES_ENABLED = + "otel.javaagent.testing.additional-library-ignores.enabled"; + @Override public void configure(IgnoredTypesBuilder builder) { - // We set this system property when running the agent with unit tests to allow verifying that we - // don't ignore libraries that we actually attempt to instrument. It means either the list is - // wrong or a type matcher is. - boolean enabled = - DeclarativeConfigUtil.getInstrumentationConfig(GlobalOpenTelemetry.get(), "agent") - .get("testing") - .get("additional_library_ignores") - .getBoolean("enabled", true); - if (enabled) { + if (!"false".equals(System.getProperty(ADDITIONAL_LIBRARY_IGNORES_ENABLED))) { configureInternal(builder); } } diff --git a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/ignore/UserExcludedClassLoadersConfigurer.java b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/ignore/UserExcludedClassLoadersConfigurer.java index 2bbfc0e24637..aff060d97490 100644 --- a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/ignore/UserExcludedClassLoadersConfigurer.java +++ b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/ignore/UserExcludedClassLoadersConfigurer.java @@ -5,13 +5,10 @@ package io.opentelemetry.javaagent.tooling.ignore; -import static java.util.Collections.emptyList; - import com.google.auto.service.AutoService; -import io.opentelemetry.api.GlobalOpenTelemetry; -import io.opentelemetry.instrumentation.api.incubator.config.internal.DeclarativeConfigUtil; import io.opentelemetry.javaagent.extension.ignore.IgnoredTypesBuilder; import io.opentelemetry.javaagent.extension.ignore.IgnoredTypesConfigurer; +import io.opentelemetry.javaagent.extension.instrumentation.internal.AgentDistributionConfig; import java.util.List; @AutoService(IgnoredTypesConfigurer.class) @@ -19,10 +16,7 @@ public class UserExcludedClassLoadersConfigurer implements IgnoredTypesConfigure @Override public void configure(IgnoredTypesBuilder builder) { - List excludedClassLoaders = - DeclarativeConfigUtil.getInstrumentationConfig(GlobalOpenTelemetry.get(), "agent") - .getScalarList("exclude_class_loaders", String.class, emptyList()); - configureInternal(builder, excludedClassLoaders); + configureInternal(builder, AgentDistributionConfig.get().getExcludeClassLoaders()); } // Visible for testing diff --git a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/ignore/UserExcludedClassesConfigurer.java b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/ignore/UserExcludedClassesConfigurer.java index 232ac768e99f..d3a945cb9124 100644 --- a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/ignore/UserExcludedClassesConfigurer.java +++ b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/ignore/UserExcludedClassesConfigurer.java @@ -5,13 +5,10 @@ package io.opentelemetry.javaagent.tooling.ignore; -import static java.util.Collections.emptyList; - import com.google.auto.service.AutoService; -import io.opentelemetry.api.GlobalOpenTelemetry; -import io.opentelemetry.instrumentation.api.incubator.config.internal.DeclarativeConfigUtil; import io.opentelemetry.javaagent.extension.ignore.IgnoredTypesBuilder; import io.opentelemetry.javaagent.extension.ignore.IgnoredTypesConfigurer; +import io.opentelemetry.javaagent.extension.instrumentation.internal.AgentDistributionConfig; import java.util.List; @AutoService(IgnoredTypesConfigurer.class) @@ -19,10 +16,7 @@ public class UserExcludedClassesConfigurer implements IgnoredTypesConfigurer { @Override public void configure(IgnoredTypesBuilder builder) { - List excludedClasses = - DeclarativeConfigUtil.getInstrumentationConfig(GlobalOpenTelemetry.get(), "agent") - .getScalarList("exclude_classes", String.class, emptyList()); - configureInternal(builder, excludedClasses); + configureInternal(builder, AgentDistributionConfig.get().getExcludeClasses()); } // Visible for testing diff --git a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/instrumentation/InstrumentationModuleInstaller.java b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/instrumentation/InstrumentationModuleInstaller.java index a44d9b459445..c421cb0f6364 100644 --- a/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/instrumentation/InstrumentationModuleInstaller.java +++ b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/instrumentation/InstrumentationModuleInstaller.java @@ -12,10 +12,9 @@ import static net.bytebuddy.matcher.ElementMatchers.named; import static net.bytebuddy.matcher.ElementMatchers.not; -import io.opentelemetry.api.GlobalOpenTelemetry; -import io.opentelemetry.instrumentation.api.incubator.config.internal.DeclarativeConfigUtil; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; +import io.opentelemetry.javaagent.extension.instrumentation.internal.AgentDistributionConfig; import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.internal.injection.InjectionMode; import io.opentelemetry.javaagent.tooling.HelperClassDefinition; @@ -70,9 +69,10 @@ AgentBuilder install( InstrumentationModule instrumentationModule, AgentBuilder parentAgentBuilder, ConfigProperties config) { - if (!isInstrumentationEnabled( - instrumentationModule.instrumentationNames(), - instrumentationModule.defaultEnabled(config))) { + if (!AgentDistributionConfig.get() + .isInstrumentationEnabled( + instrumentationModule.instrumentationNames(), + instrumentationModule.defaultEnabled(config))) { logger.log( FINE, "Instrumentation {0} is disabled", instrumentationModule.instrumentationName()); return parentAgentBuilder; @@ -238,20 +238,6 @@ private AgentBuilder installInjectingModule( return agentBuilder; } - static boolean isInstrumentationEnabled( - Iterable instrumentationNames, boolean defaultEnabled) { - for (String name : instrumentationNames) { - String normalizedName = name.replace('-', '_'); - Boolean enabled = - DeclarativeConfigUtil.getInstrumentationConfig(GlobalOpenTelemetry.get(), normalizedName) - .getBoolean("enabled"); - if (enabled != null) { - return enabled; - } - } - return defaultEnabled; - } - private static AgentBuilder.Identified.Narrowable setTypeMatcher( AgentBuilder agentBuilder, InstrumentationModule instrumentationModule, diff --git a/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/OpenTelemetryInstallerTest.java b/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/OpenTelemetryInstallerTest.java index 79e635c88932..d6f71593bda8 100644 --- a/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/OpenTelemetryInstallerTest.java +++ b/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/OpenTelemetryInstallerTest.java @@ -9,6 +9,7 @@ import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.api.OpenTelemetry; +import io.opentelemetry.javaagent.extension.instrumentation.internal.AgentDistributionConfig; import io.opentelemetry.javaagent.tooling.config.EarlyInitAgentConfig; import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk; import org.junit.jupiter.api.AfterEach; @@ -21,6 +22,7 @@ class OpenTelemetryInstallerTest { @AfterEach void setUp() { GlobalOpenTelemetry.resetForTest(); + AgentDistributionConfig.resetForTest(); } @Test 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 a8efc22cbb63..6a14625d6e31 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 @@ -11,6 +11,7 @@ import io.opentelemetry.api.GlobalOpenTelemetry; import io.opentelemetry.instrumentation.api.incubator.config.internal.DeclarativeConfigUtil; +import io.opentelemetry.javaagent.extension.instrumentation.internal.AgentDistributionConfig; import io.opentelemetry.javaagent.tooling.OpenTelemetryInstaller; import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk; import io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer; @@ -32,6 +33,7 @@ class ConfigurationPropertiesSupplierTest { @AfterEach void setUp() { GlobalOpenTelemetry.resetForTest(); + AgentDistributionConfig.resetForTest(); ConfigurationFile.resetForTest(); } diff --git a/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/config/OtlpProtocolPropertiesSupplierTest.java b/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/config/OtlpProtocolPropertiesSupplierTest.java index 267018dfe2f2..fa8b9332fe7e 100644 --- a/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/config/OtlpProtocolPropertiesSupplierTest.java +++ b/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/config/OtlpProtocolPropertiesSupplierTest.java @@ -8,6 +8,7 @@ import static org.assertj.core.api.Assertions.assertThat; import io.opentelemetry.api.GlobalOpenTelemetry; +import io.opentelemetry.javaagent.extension.instrumentation.internal.AgentDistributionConfig; import io.opentelemetry.javaagent.tooling.OpenTelemetryInstaller; import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk; import io.opentelemetry.sdk.autoconfigure.internal.AutoConfigureUtil; @@ -22,6 +23,7 @@ class OtlpProtocolPropertiesSupplierTest { @AfterEach void setUp() { GlobalOpenTelemetry.resetForTest(); + AgentDistributionConfig.resetForTest(); } @SetSystemProperty( diff --git a/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/instrumentation/InstrumentationModuleInstallerTest.java b/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/instrumentation/InstrumentationModuleInstallerTest.java index a234e6c13c92..887e80c744c1 100644 --- a/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/instrumentation/InstrumentationModuleInstallerTest.java +++ b/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/instrumentation/InstrumentationModuleInstallerTest.java @@ -6,29 +6,26 @@ package io.opentelemetry.javaagent.tooling.instrumentation; import static java.util.Arrays.asList; +import static java.util.Collections.emptyList; import static org.assertj.core.api.Assertions.assertThat; import static org.mockito.Mockito.mock; -import static org.mockito.Mockito.spy; import static org.mockito.Mockito.when; -import io.opentelemetry.api.GlobalOpenTelemetry; -import io.opentelemetry.api.OpenTelemetry; -import io.opentelemetry.api.incubator.ExtendedOpenTelemetry; -import io.opentelemetry.api.incubator.config.ConfigProvider; -import io.opentelemetry.instrumentation.config.bridge.ConfigPropertiesBackedDeclarativeConfigProperties; +import io.opentelemetry.javaagent.extension.instrumentation.internal.AgentDistributionConfig; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; -import java.util.TreeSet; import java.util.stream.Stream; import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.params.ParameterizedTest; import org.junit.jupiter.params.provider.Arguments; import org.junit.jupiter.params.provider.MethodSource; class InstrumentationModuleInstallerTest { + @BeforeEach @AfterEach void tearDown() { - GlobalOpenTelemetry.resetForTest(); + AgentDistributionConfig.resetForTest(); } @ParameterizedTest(name = "isInstrumentationEnabled({0}) = {4}") @@ -43,13 +40,21 @@ void testIsInstrumentationEnabled( ConfigProperties config = mock(ConfigProperties.class); when(config.getBoolean("otel.instrumentation.first.enabled")).thenReturn(firstEnabled); when(config.getBoolean("otel.instrumentation.second.enabled")).thenReturn(secondEnabled); + when(config.getBoolean("otel.instrumentation.common.default-enabled", true)) + .thenReturn(defaultEnabled); + when(config.getBoolean("otel.javaagent.experimental.indy", false)).thenReturn(false); + when(config.getBoolean("otel.javaagent.experimental.force-synchronous-agent-listeners", false)) + .thenReturn(false); + when(config.getList("otel.javaagent.exclude-classes")).thenReturn(emptyList()); + when(config.getList("otel.javaagent.exclude-class-loaders")).thenReturn(emptyList()); - OpenTelemetry openTelemetry = createOpenTelemetry(config); - GlobalOpenTelemetry.set(openTelemetry); + AgentDistributionConfig distributionConfig = + AgentDistributionConfig.fromConfigProperties(config); + AgentDistributionConfig.set(distributionConfig); assertThat( - InstrumentationModuleInstaller.isInstrumentationEnabled( - new TreeSet<>(asList("first", "second")), defaultEnabled)) + AgentDistributionConfig.get() + .isInstrumentationEnabled(asList("first", "second"), defaultEnabled)) .isEqualTo(expected); } @@ -92,14 +97,4 @@ private static Stream instrumentationEnabledParams() { true), Arguments.of("disabled by default", null, null, false, false)); } - - private static OpenTelemetry createOpenTelemetry(ConfigProperties config) { - ExtendedOpenTelemetry otel = spy(ExtendedOpenTelemetry.class); - ConfigProvider configProvider = spy(ConfigProvider.class); - when(otel.getConfigProvider()).thenReturn(configProvider); - when(configProvider.getInstrumentationConfig()) - .thenReturn( - ConfigPropertiesBackedDeclarativeConfigProperties.createInstrumentationConfig(config)); - return otel; - } } diff --git a/javaagent-tooling/src/testDistributionConfig/java/io/opentelemetry/javaagent/extension/instrumentation/internal/AgentDistributionConfigTest.java b/javaagent-tooling/src/testDistributionConfig/java/io/opentelemetry/javaagent/extension/instrumentation/internal/AgentDistributionConfigTest.java new file mode 100644 index 000000000000..679396151824 --- /dev/null +++ b/javaagent-tooling/src/testDistributionConfig/java/io/opentelemetry/javaagent/extension/instrumentation/internal/AgentDistributionConfigTest.java @@ -0,0 +1,90 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.extension.instrumentation.internal; + +import static org.assertj.core.api.Assertions.assertThat; + +import io.opentelemetry.javaagent.tooling.OpenTelemetryInstaller; +import java.util.Arrays; +import org.junit.jupiter.api.BeforeAll; +import org.junit.jupiter.api.Test; + +class AgentDistributionConfigTest { + + @BeforeAll + static void setUp() { + // Initialize OpenTelemetry SDK to load declarative configuration + OpenTelemetryInstaller.installOpenTelemetrySdk( + AgentDistributionConfigTest.class.getClassLoader()); + } + + @Test + void testIndyDevelopmentProperty() { + assertThat(AgentDistributionConfig.get().isIndyEnabled()).isTrue(); + } + + @Test + void testForceSynchronousAgentListeners() { + assertThat(AgentDistributionConfig.get().isForceSynchronousAgentListeners()).isFalse(); + } + + @Test + void testExcludeClasses() { + assertThat(AgentDistributionConfig.get().getExcludeClasses()) + .containsExactly("com.example.excluded.Class1", "com.example.excluded.Class2"); + } + + @Test + void testExcludeClassLoaders() { + assertThat(AgentDistributionConfig.get().getExcludeClassLoaders()) + .containsExactly("com.example.ExcludedClassLoader"); + } + + @Test + void testInstrumentationDefaultEnabledByDefault() { + assertThat(AgentDistributionConfig.get().isInstrumentationDefaultEnabled()).isTrue(); + } + + @Test + void testInstrumentationEnabled() { + AgentDistributionConfig config = AgentDistributionConfig.get(); + assertThat(config.isInstrumentationEnabled("tomcat", false)).isTrue(); + assertThat(config.isInstrumentationEnabled("spring_webmvc", false)).isTrue(); + assertThat(config.isInstrumentationEnabled("unknown", false)).isFalse(); + } + + @Test + void testUnknownInstrumentationUsesDefaultEnabled() { + // An unknown instrumentation with defaultEnabled=true should be enabled + AgentDistributionConfig config = AgentDistributionConfig.get(); + assertThat(config.isInstrumentationEnabled("unknown", true)).isTrue(); + } + + @Test + void testInstrumentationEnabledOrderMatters() { + // armeria is enabled, armeria_grpc is disabled + // first matching name wins (matches ConfigProperties behavior) + AgentDistributionConfig config = AgentDistributionConfig.get(); + + // armeria-grpc listed first: disabled wins + assertThat( + config.isInstrumentationEnabled( + Arrays.asList("armeria-grpc", "armeria-grpc-1.14", "armeria", "armeria-1.14"), + true)) + .isFalse(); + + // armeria listed first: enabled wins + assertThat( + config.isInstrumentationEnabled( + Arrays.asList("armeria", "armeria-1.14", "armeria-grpc", "armeria-grpc-1.14"), + true)) + .isTrue(); + + // armeria alone should be enabled + assertThat(config.isInstrumentationEnabled(Arrays.asList("armeria", "armeria-1.14"), true)) + .isTrue(); + } +} diff --git a/javaagent-tooling/src/testDistributionConfig/resources/distribution-config.yaml b/javaagent-tooling/src/testDistributionConfig/resources/distribution-config.yaml new file mode 100644 index 000000000000..760c8cde983c --- /dev/null +++ b/javaagent-tooling/src/testDistributionConfig/resources/distribution-config.yaml @@ -0,0 +1,18 @@ +file_format: "1.0-rc.1" + +distribution: + javaagent: + indy/development: true + force_synchronous_agent_listeners/development: false + exclude_classes: + - com.example.excluded.Class1 + - com.example.excluded.Class2 + exclude_class_loaders: + - com.example.ExcludedClassLoader + instrumentation: + enabled: + - tomcat + - spring_webmvc + - armeria + disabled: + - armeria_grpc diff --git a/smoke-tests/src/test/java/io/opentelemetry/smoketest/DeclarativeConfigurationSmokeTest.java b/smoke-tests/src/test/java/io/opentelemetry/smoketest/DeclarativeConfigurationSmokeTest.java index 512024787aff..6e5ee1e8b220 100644 --- a/smoke-tests/src/test/java/io/opentelemetry/smoketest/DeclarativeConfigurationSmokeTest.java +++ b/smoke-tests/src/test/java/io/opentelemetry/smoketest/DeclarativeConfigurationSmokeTest.java @@ -35,7 +35,7 @@ void springBootSmokeTest(int jdk) { client().get("/greeting").aggregate().join(); // There is one span (io.opentelemetry.opentelemetry-instrumentation-annotations-1.16 is - // not used, because instrumentation_mode=none) + // not used, because default_enabled=false) testing.waitAndAssertTraces( trace -> trace.hasSpansSatisfyingExactly( diff --git a/smoke-tests/src/test/resources/declarative-config.yaml b/smoke-tests/src/test/resources/declarative-config.yaml index 86091dc4d39f..0a866ad6293c 100644 --- a/smoke-tests/src/test/resources/declarative-config.yaml +++ b/smoke-tests/src/test/resources/declarative-config.yaml @@ -20,9 +20,9 @@ resource: - name: service.name value: declarative-config-smoke-test -instrumentation/development: - java: - agent: - instrumentation_mode: none - tomcat: - enabled: true +distribution: + javaagent: + instrumentation: + default_enabled: false + enabled: + - tomcat