From 478404539d3f2104b93a95451b828c136e62e309 Mon Sep 17 00:00:00 2001 From: Angel <107818450+anhermon@users.noreply.github.com> Date: Thu, 11 Jan 2024 17:50:46 +0200 Subject: [PATCH] Add UserExcludedClassloadersConfigurer (#10134) --- docs/advanced-configuration-options.md | 8 +++ .../UserExcludedClassLoadersConfigurer.java | 34 ++++++++++++ ...serExcludedClassLoadersConfigurerTest.java | 55 +++++++++++++++++++ 3 files changed, 97 insertions(+) create mode 100644 javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/ignore/UserExcludedClassLoadersConfigurer.java create mode 100644 javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/ignore/UserExcludedClassLoadersConfigurerTest.java diff --git a/docs/advanced-configuration-options.md b/docs/advanced-configuration-options.md index bd513d885b..afcc6dfa90 100644 --- a/docs/advanced-configuration-options.md +++ b/docs/advanced-configuration-options.md @@ -18,6 +18,14 @@ which could have unknown side-effects. | ------------------------------ | ------------------------------ | -------------------------------------------------------------------------------------------------- | | otel.javaagent.exclude-classes | OTEL_JAVAAGENT_EXCLUDE_CLASSES | Suppresses all instrumentation for specific classes, format is "my.package.MyClass,my.package2.\*" | +## Excluding specific classes loaders + +This option can be used to exclude classes loaded by given class loaders from being instrumented. + +| System property | Environment variable | Purpose | +|--------------------------------------|--------------------------------------|---------------------------------------------------------------------------------| +| otel.javaagent.exclude-class-loaders | OTEL_JAVAAGENT_EXCLUDE_CLASS_LOADERS | Ignore the specified class loaders, format is "my.package.MyClass,my.package2." | + ## Running application with security manager This option can be used to let agent run with all privileges without being affected by security policy restricting some operations. 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 new file mode 100644 index 0000000000..d2d386ca4f --- /dev/null +++ b/javaagent-tooling/src/main/java/io/opentelemetry/javaagent/tooling/ignore/UserExcludedClassLoadersConfigurer.java @@ -0,0 +1,34 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.tooling.ignore; + +import static java.util.Collections.emptyList; + +import com.google.auto.service.AutoService; +import io.opentelemetry.javaagent.extension.ignore.IgnoredTypesBuilder; +import io.opentelemetry.javaagent.extension.ignore.IgnoredTypesConfigurer; +import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; +import java.util.List; + +@AutoService(IgnoredTypesConfigurer.class) +public class UserExcludedClassLoadersConfigurer implements IgnoredTypesConfigurer { + + // visible for tests + static final String EXCLUDED_CLASS_LOADERS_CONFIG = "otel.javaagent.exclude-class-loaders"; + + @Override + public void configure(IgnoredTypesBuilder builder, ConfigProperties config) { + List excludedClassLoaders = config.getList(EXCLUDED_CLASS_LOADERS_CONFIG, emptyList()); + for (String excludedClassLoader : excludedClassLoaders) { + excludedClassLoader = excludedClassLoader.trim(); + // remove the trailing * + if (excludedClassLoader.endsWith("*")) { + excludedClassLoader = excludedClassLoader.substring(0, excludedClassLoader.length() - 1); + } + builder.ignoreClassLoader(excludedClassLoader); + } + } +} diff --git a/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/ignore/UserExcludedClassLoadersConfigurerTest.java b/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/ignore/UserExcludedClassLoadersConfigurerTest.java new file mode 100644 index 0000000000..166b702b98 --- /dev/null +++ b/javaagent-tooling/src/test/java/io/opentelemetry/javaagent/tooling/ignore/UserExcludedClassLoadersConfigurerTest.java @@ -0,0 +1,55 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.tooling.ignore; + +import static io.opentelemetry.javaagent.tooling.ignore.UserExcludedClassLoadersConfigurer.EXCLUDED_CLASS_LOADERS_CONFIG; +import static java.util.Arrays.asList; +import static java.util.Collections.emptyList; +import static org.mockito.Mockito.verify; +import static org.mockito.Mockito.verifyNoInteractions; +import static org.mockito.Mockito.when; + +import io.opentelemetry.javaagent.extension.ignore.IgnoredTypesBuilder; +import io.opentelemetry.javaagent.extension.ignore.IgnoredTypesConfigurer; +import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.ExtendWith; +import org.mockito.Mock; +import org.mockito.junit.jupiter.MockitoExtension; + +@ExtendWith(MockitoExtension.class) +class UserExcludedClassLoadersConfigurerTest { + + @Mock ConfigProperties config; + @Mock IgnoredTypesBuilder builder; + + IgnoredTypesConfigurer underTest = new UserExcludedClassLoadersConfigurer(); + + @Test + void shouldAddNothingToBuilderWhenPropertyIsEmpty() { + // when + underTest.configure(builder, config); + + // then + verifyNoInteractions(builder); + } + + @Test + void shouldIgnoreClassesAndPackages() { + // given + when(config.getList(EXCLUDED_CLASS_LOADERS_CONFIG, emptyList())) + .thenReturn( + asList("com.example.IgnoredClass", "com.example.ignored.*", "com.another_ignore")); + + // when + underTest.configure(builder, config); + + // then + verify(builder).ignoreClassLoader("com.example.IgnoredClass"); + verify(builder).ignoreClassLoader("com.example.ignored."); + verify(builder).ignoreClassLoader("com.another_ignore"); + } +}