From c58a577c82fa63b8c96bfaad3e00d7ab860a2d86 Mon Sep 17 00:00:00 2001 From: Gregor Zeitlinger Date: Fri, 5 Jul 2024 17:25:50 +0200 Subject: [PATCH] reuse-agent-config --- .../internal/InstrumentationModuleConfig.java | 32 +++++++++ .../InstrumentationModuleConfigTest.java | 10 ++- .../InstrumentationPropertyEnabled.java | 32 +++++---- .../SpringInstrumentationConfig.java | 70 +++++++++++++++++++ .../javaagent/tooling/config/AgentConfig.java | 18 ----- .../InstrumentationModuleInstaller.java | 7 +- 6 files changed, 129 insertions(+), 40 deletions(-) create mode 100644 instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/config/internal/InstrumentationModuleConfig.java rename javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/config/AgentConfigTest.java => instrumentation-api-incubator/src/test/java/io/opentelemetry/instrumentation/api/incubator/config/internal/InstrumentationModuleConfigTest.java (89%) create mode 100644 instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/properties/SpringInstrumentationConfig.java diff --git a/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/config/internal/InstrumentationModuleConfig.java b/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/config/internal/InstrumentationModuleConfig.java new file mode 100644 index 000000000000..f8400e5d26fb --- /dev/null +++ b/instrumentation-api-incubator/src/main/java/io/opentelemetry/instrumentation/api/incubator/config/internal/InstrumentationModuleConfig.java @@ -0,0 +1,32 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.api.incubator.config.internal; + +/** + * This class is internal and is hence not for public use. Its APIs are unstable and can change at + * any time. + */ +public final class InstrumentationModuleConfig { + private InstrumentationModuleConfig() {} + + public static boolean isInstrumentationEnabled( + InstrumentationConfig config, Iterable instrumentationNames, boolean defaultEnabled) { + // If default is enabled, we want to disable individually, + // if default is disabled, we want to enable individually. + boolean anyEnabled = defaultEnabled; + for (String name : instrumentationNames) { + String propertyName = "otel.instrumentation." + name + ".enabled"; + boolean enabled = config.getBoolean(propertyName, defaultEnabled); + + if (defaultEnabled) { + anyEnabled &= enabled; + } else { + anyEnabled |= enabled; + } + } + return anyEnabled; + } +} diff --git a/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/config/AgentConfigTest.java b/instrumentation-api-incubator/src/test/java/io/opentelemetry/instrumentation/api/incubator/config/internal/InstrumentationModuleConfigTest.java similarity index 89% rename from javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/config/AgentConfigTest.java rename to instrumentation-api-incubator/src/test/java/io/opentelemetry/instrumentation/api/incubator/config/internal/InstrumentationModuleConfigTest.java index e4b36be6c51a..02fd27dbdb53 100644 --- a/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/config/AgentConfigTest.java +++ b/instrumentation-api-incubator/src/test/java/io/opentelemetry/instrumentation/api/incubator/config/internal/InstrumentationModuleConfigTest.java @@ -3,14 +3,13 @@ * SPDX-License-Identifier: Apache-2.0 */ -package io.opentelemetry.javaagent.tooling.config; +package io.opentelemetry.instrumentation.api.incubator.config.internal; import static java.util.Arrays.asList; import static org.junit.jupiter.api.Assertions.assertEquals; import static org.mockito.Mockito.mock; import static org.mockito.Mockito.when; -import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import java.util.TreeSet; import java.util.stream.Stream; import org.junit.jupiter.api.extension.ExtensionContext; @@ -19,8 +18,7 @@ import org.junit.jupiter.params.provider.ArgumentsProvider; import org.junit.jupiter.params.provider.ArgumentsSource; -class AgentConfigTest { - +class InstrumentationModuleConfigTest { @ParameterizedTest(name = "isInstrumentationEnabled({0}) = {4}") @ArgumentsSource(InstrumentationEnabledParams.class) void testIsInstrumentationEnabled( @@ -30,7 +28,7 @@ void testIsInstrumentationEnabled( boolean defaultEnabled, boolean expected) { - ConfigProperties config = mock(ConfigProperties.class); + InstrumentationConfig config = mock(InstrumentationConfig.class); when(config.getBoolean("otel.instrumentation.first.enabled", defaultEnabled)) .thenReturn(firstEnabled); when(config.getBoolean("otel.instrumentation.second.enabled", defaultEnabled)) @@ -38,7 +36,7 @@ void testIsInstrumentationEnabled( assertEquals( expected, - AgentConfig.isInstrumentationEnabled( + InstrumentationModuleConfig.isInstrumentationEnabled( config, new TreeSet<>(asList("first", "second")), defaultEnabled)); } diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/InstrumentationPropertyEnabled.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/InstrumentationPropertyEnabled.java index 87687f668b6c..0f608a5f113d 100644 --- a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/InstrumentationPropertyEnabled.java +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/InstrumentationPropertyEnabled.java @@ -5,9 +5,14 @@ package io.opentelemetry.instrumentation.spring.autoconfigure.internal; +import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationModuleConfig; +import io.opentelemetry.instrumentation.spring.autoconfigure.internal.properties.SpringInstrumentationConfig; +import java.util.Collections; import java.util.Map; +import java.util.Objects; import org.springframework.context.annotation.Condition; import org.springframework.context.annotation.ConditionContext; +import org.springframework.core.env.Environment; import org.springframework.core.type.AnnotatedTypeMetadata; /** @@ -19,19 +24,20 @@ public class InstrumentationPropertyEnabled implements Condition { @Override public boolean matches(ConditionContext context, AnnotatedTypeMetadata metadata) { Map attributes = - metadata.getAnnotationAttributes(ConditionalOnEnabledInstrumentation.class.getName()); + Objects.requireNonNull( + metadata.getAnnotationAttributes(ConditionalOnEnabledInstrumentation.class.getName())); - String name = String.format("otel.instrumentation.%s.enabled", attributes.get("module")); - Boolean explicit = context.getEnvironment().getProperty(name, Boolean.class); - if (explicit != null) { - return explicit; - } - boolean defaultValue = (boolean) attributes.get("enabledByDefault"); - if (!defaultValue) { - return false; - } - return context - .getEnvironment() - .getProperty("otel.instrumentation.common.default-enabled", Boolean.class, true); + Environment environment = context.getEnvironment(); + return InstrumentationModuleConfig.isInstrumentationEnabled( + new SpringInstrumentationConfig(environment), + Collections.singleton((String) attributes.get("module")), + isEnabledByDefault(attributes, environment)); + } + + private static boolean isEnabledByDefault( + Map attributes, Environment environment) { + return (boolean) attributes.get("enabledByDefault") + && environment.getProperty( + "otel.instrumentation.common.default-enabled", Boolean.class, true); } } diff --git a/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/properties/SpringInstrumentationConfig.java b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/properties/SpringInstrumentationConfig.java new file mode 100644 index 000000000000..15bdd72b7717 --- /dev/null +++ b/instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/properties/SpringInstrumentationConfig.java @@ -0,0 +1,70 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.instrumentation.spring.autoconfigure.internal.properties; + +import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationConfig; +import java.time.Duration; +import java.util.List; +import java.util.Map; +import org.springframework.core.env.Environment; + +/** + * This class is internal and is hence not for public use. Its APIs are unstable and can change at + * any time. + */ +public class SpringInstrumentationConfig implements InstrumentationConfig { + + private final Environment environment; + + public SpringInstrumentationConfig(Environment environment) { + this.environment = environment; + } + + @Override + public String getString(String name) { + return environment.getProperty(name); + } + + @Override + public String getString(String name, String defaultValue) { + return environment.getProperty(name, defaultValue); + } + + @Override + public boolean getBoolean(String name, boolean defaultValue) { + return environment.getProperty(name, Boolean.class, defaultValue); + } + + @Override + public int getInt(String name, int defaultValue) { + return environment.getProperty(name, Integer.class, defaultValue); + } + + @Override + public long getLong(String name, long defaultValue) { + return environment.getProperty(name, Long.class, defaultValue); + } + + @Override + public double getDouble(String name, double defaultValue) { + throw new UnsupportedOperationException(); + } + + @Override + public Duration getDuration(String name, Duration defaultValue) { + throw new UnsupportedOperationException(); + } + + @Override + public List getList(String name, List defaultValue) { + throw new UnsupportedOperationException(); + } + + @Override + public Map getMap(String name, Map defaultValue) { + throw new UnsupportedOperationException(); + } +} 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 index 3077b56536c0..a59fe6b11432 100644 --- 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 @@ -9,24 +9,6 @@ public final class AgentConfig { - public static boolean isInstrumentationEnabled( - ConfigProperties config, Iterable instrumentationNames, boolean defaultEnabled) { - // If default is enabled, we want to enable individually, - // if default is disabled, we want to disable individually. - boolean anyEnabled = defaultEnabled; - for (String name : instrumentationNames) { - String propertyName = "otel.instrumentation." + name + ".enabled"; - boolean enabled = config.getBoolean(propertyName, defaultEnabled); - - if (defaultEnabled) { - anyEnabled &= enabled; - } else { - anyEnabled |= enabled; - } - } - return anyEnabled; - } - public static boolean isDebugModeEnabled(ConfigProperties config) { return config.getBoolean("otel.javaagent.debug", false); } 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 b4ea4b948639..5e414af13037 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 @@ -11,6 +11,7 @@ import static net.bytebuddy.matcher.ElementMatchers.named; import static net.bytebuddy.matcher.ElementMatchers.not; +import io.opentelemetry.instrumentation.api.incubator.config.internal.InstrumentationModuleConfig; import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule; import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation; import io.opentelemetry.javaagent.extension.instrumentation.internal.ExperimentalInstrumentationModule; @@ -20,7 +21,7 @@ import io.opentelemetry.javaagent.tooling.TransformSafeLogger; import io.opentelemetry.javaagent.tooling.Utils; import io.opentelemetry.javaagent.tooling.bytebuddy.LoggingFailSafeMatcher; -import io.opentelemetry.javaagent.tooling.config.AgentConfig; +import io.opentelemetry.javaagent.tooling.config.ConfigPropertiesBridge; import io.opentelemetry.javaagent.tooling.field.VirtualFieldImplementationInstaller; import io.opentelemetry.javaagent.tooling.field.VirtualFieldImplementationInstallerFactory; import io.opentelemetry.javaagent.tooling.instrumentation.indy.ClassInjectorImpl; @@ -64,8 +65,8 @@ AgentBuilder install( InstrumentationModule instrumentationModule, AgentBuilder parentAgentBuilder, ConfigProperties config) { - if (!AgentConfig.isInstrumentationEnabled( - config, + if (!InstrumentationModuleConfig.isInstrumentationEnabled( + new ConfigPropertiesBridge(config), instrumentationModule.instrumentationNames(), instrumentationModule.defaultEnabled(config))) { logger.log(