diff --git a/instrumentation/jmx-metrics/javaagent/src/main/java/io/opentelemetry/instrumentation/javaagent/jmx/JmxMetricInsightInstaller.java b/instrumentation/jmx-metrics/javaagent/src/main/java/io/opentelemetry/instrumentation/javaagent/jmx/JmxMetricInsightInstaller.java index 39d32e69e4a8..2c2d989ba9f7 100644 --- a/instrumentation/jmx-metrics/javaagent/src/main/java/io/opentelemetry/instrumentation/javaagent/jmx/JmxMetricInsightInstaller.java +++ b/instrumentation/jmx-metrics/javaagent/src/main/java/io/opentelemetry/instrumentation/javaagent/jmx/JmxMetricInsightInstaller.java @@ -15,7 +15,6 @@ import io.opentelemetry.instrumentation.jmx.yaml.RuleParser; import io.opentelemetry.javaagent.extension.AgentListener; import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk; -import io.opentelemetry.sdk.autoconfigure.internal.AutoConfigureUtil; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import java.io.InputStream; import java.nio.file.Files; @@ -29,7 +28,7 @@ public class JmxMetricInsightInstaller implements AgentListener { @Override public void afterAgent(AutoConfiguredOpenTelemetrySdk autoConfiguredSdk) { - ConfigProperties config = AutoConfigureUtil.getConfig(autoConfiguredSdk); + ConfigProperties config = AgentListener.resolveConfigProperties(autoConfiguredSdk); if (config.getBoolean("otel.jmx.enabled", true)) { JmxMetricInsight service = 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 5a5b04443d2e..923f95dea061 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 @@ -8,7 +8,6 @@ import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.extension.AgentListener; import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk; -import io.opentelemetry.sdk.autoconfigure.internal.AutoConfigureUtil; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import java.lang.reflect.Method; @@ -21,7 +20,7 @@ public class OshiMetricsInstaller implements AgentListener { @Override public void afterAgent(AutoConfiguredOpenTelemetrySdk autoConfiguredSdk) { - ConfigProperties config = AutoConfigureUtil.getConfig(autoConfiguredSdk); + ConfigProperties config = AgentListener.resolveConfigProperties(autoConfiguredSdk); boolean defaultEnabled = config.getBoolean("otel.instrumentation.common.default-enabled", true); if (!config.getBoolean("otel.instrumentation.oshi.enabled", defaultEnabled)) { diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java17/javaagent/src/main/java/io/opentelemetry/instrumentation/javaagent/runtimemetrics/java17/Java17RuntimeMetricsInstaller.java b/instrumentation/runtime-telemetry/runtime-telemetry-java17/javaagent/src/main/java/io/opentelemetry/instrumentation/javaagent/runtimemetrics/java17/Java17RuntimeMetricsInstaller.java index a01e4885c209..ec4fab1528af 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java17/javaagent/src/main/java/io/opentelemetry/instrumentation/javaagent/runtimemetrics/java17/Java17RuntimeMetricsInstaller.java +++ b/instrumentation/runtime-telemetry/runtime-telemetry-java17/javaagent/src/main/java/io/opentelemetry/instrumentation/javaagent/runtimemetrics/java17/Java17RuntimeMetricsInstaller.java @@ -12,7 +12,6 @@ import io.opentelemetry.instrumentation.runtimemetrics.java17.RuntimeMetricsBuilder; import io.opentelemetry.javaagent.extension.AgentListener; import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk; -import io.opentelemetry.sdk.autoconfigure.internal.AutoConfigureUtil; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; /** An {@link AgentListener} that enables runtime metrics during agent startup. */ @@ -21,7 +20,7 @@ public class Java17RuntimeMetricsInstaller implements AgentListener { @Override public void afterAgent(AutoConfiguredOpenTelemetrySdk autoConfiguredSdk) { - ConfigProperties config = AutoConfigureUtil.getConfig(autoConfiguredSdk); + ConfigProperties config = AgentListener.resolveConfigProperties(autoConfiguredSdk); OpenTelemetry openTelemetry = GlobalOpenTelemetry.get(); RuntimeMetricsBuilder builder = null; diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java8/javaagent/src/main/java/io/opentelemetry/instrumentation/javaagent/runtimemetrics/java8/JarAnalyzerInstaller.java b/instrumentation/runtime-telemetry/runtime-telemetry-java8/javaagent/src/main/java/io/opentelemetry/instrumentation/javaagent/runtimemetrics/java8/JarAnalyzerInstaller.java index ec12fa81c2f1..f16b00cb2903 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java8/javaagent/src/main/java/io/opentelemetry/instrumentation/javaagent/runtimemetrics/java8/JarAnalyzerInstaller.java +++ b/instrumentation/runtime-telemetry/runtime-telemetry-java8/javaagent/src/main/java/io/opentelemetry/instrumentation/javaagent/runtimemetrics/java8/JarAnalyzerInstaller.java @@ -7,9 +7,9 @@ import com.google.auto.service.AutoService; import io.opentelemetry.javaagent.bootstrap.InstrumentationHolder; +import io.opentelemetry.javaagent.extension.AgentListener; import io.opentelemetry.javaagent.tooling.BeforeAgentListener; import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk; -import io.opentelemetry.sdk.autoconfigure.internal.AutoConfigureUtil; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import java.lang.instrument.Instrumentation; @@ -19,7 +19,8 @@ public class JarAnalyzerInstaller implements BeforeAgentListener { @Override public void beforeAgent(AutoConfiguredOpenTelemetrySdk autoConfiguredOpenTelemetrySdk) { - ConfigProperties config = AutoConfigureUtil.getConfig(autoConfiguredOpenTelemetrySdk); + ConfigProperties config = AgentListener.resolveConfigProperties(autoConfiguredOpenTelemetrySdk); + boolean enabled = config.getBoolean("otel.instrumentation.runtime-telemetry.package-emitter.enabled", false); if (!enabled) { diff --git a/instrumentation/runtime-telemetry/runtime-telemetry-java8/javaagent/src/main/java/io/opentelemetry/instrumentation/javaagent/runtimemetrics/java8/Java8RuntimeMetricsInstaller.java b/instrumentation/runtime-telemetry/runtime-telemetry-java8/javaagent/src/main/java/io/opentelemetry/instrumentation/javaagent/runtimemetrics/java8/Java8RuntimeMetricsInstaller.java index 57ca0396ee99..b93bfa57e835 100644 --- a/instrumentation/runtime-telemetry/runtime-telemetry-java8/javaagent/src/main/java/io/opentelemetry/instrumentation/javaagent/runtimemetrics/java8/Java8RuntimeMetricsInstaller.java +++ b/instrumentation/runtime-telemetry/runtime-telemetry-java8/javaagent/src/main/java/io/opentelemetry/instrumentation/javaagent/runtimemetrics/java8/Java8RuntimeMetricsInstaller.java @@ -19,7 +19,6 @@ import io.opentelemetry.instrumentation.runtimemetrics.java8.internal.JmxRuntimeMetricsUtil; import io.opentelemetry.javaagent.extension.AgentListener; import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk; -import io.opentelemetry.sdk.autoconfigure.internal.AutoConfigureUtil; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import java.util.ArrayList; import java.util.List; @@ -30,7 +29,7 @@ public class Java8RuntimeMetricsInstaller implements AgentListener { @Override public void afterAgent(AutoConfiguredOpenTelemetrySdk autoConfiguredSdk) { - ConfigProperties config = AutoConfigureUtil.getConfig(autoConfiguredSdk); + ConfigProperties config = AgentListener.resolveConfigProperties(autoConfiguredSdk); boolean defaultEnabled = config.getBoolean("otel.instrumentation.common.default-enabled", true); if (!config.getBoolean("otel.instrumentation.runtime-telemetry.enabled", defaultEnabled) diff --git a/javaagent-extension-api/build.gradle.kts b/javaagent-extension-api/build.gradle.kts index a63bd79094b2..96852314dcb8 100644 --- a/javaagent-extension-api/build.gradle.kts +++ b/javaagent-extension-api/build.gradle.kts @@ -17,6 +17,8 @@ dependencies { // autoconfigure is unstable, do not expose as api implementation("io.opentelemetry:opentelemetry-sdk-extension-autoconfigure") + testImplementation("io.opentelemetry:opentelemetry-sdk-extension-incubator") + // Used by byte-buddy but not brought in as a transitive dependency. compileOnly("com.google.code.findbugs:annotations") } diff --git a/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/extension/AgentListener.java b/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/extension/AgentListener.java index 4cbcbfb8970b..8b5abbf5222b 100644 --- a/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/extension/AgentListener.java +++ b/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/extension/AgentListener.java @@ -6,7 +6,10 @@ package io.opentelemetry.javaagent.extension; import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk; +import io.opentelemetry.sdk.autoconfigure.internal.AutoConfigureUtil; +import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.Ordered; +import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; import java.lang.instrument.Instrumentation; import net.bytebuddy.agent.builder.AgentBuilder; @@ -25,4 +28,22 @@ public interface AgentListener extends Ordered { * on an {@link Instrumentation}. */ void afterAgent(AutoConfiguredOpenTelemetrySdk autoConfiguredOpenTelemetrySdk); + + /** Resolve {@link ConfigProperties} from the {@code autoConfiguredOpenTelemetrySdk}. */ + static ConfigProperties resolveConfigProperties( + AutoConfiguredOpenTelemetrySdk autoConfiguredOpenTelemetrySdk) { + ConfigProperties sdkConfigProperties = + AutoConfigureUtil.getConfig(autoConfiguredOpenTelemetrySdk); + if (sdkConfigProperties != null) { + return sdkConfigProperties; + } + StructuredConfigProperties structuredConfigProperties = + AutoConfigureUtil.getStructuredConfig(autoConfiguredOpenTelemetrySdk); + if (structuredConfigProperties != null) { + return new StructuredConfigPropertiesBridge(structuredConfigProperties); + } + // Should never happen + throw new IllegalStateException( + "AutoConfiguredOpenTelemetrySdk does not have ConfigProperties or StructuredConfigProperties. This is likely a programming error in opentelemetry-java"); + } } diff --git a/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/extension/StructuredConfigPropertiesBridge.java b/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/extension/StructuredConfigPropertiesBridge.java new file mode 100644 index 000000000000..5c07bcc0a565 --- /dev/null +++ b/javaagent-extension-api/src/main/java/io/opentelemetry/javaagent/extension/StructuredConfigPropertiesBridge.java @@ -0,0 +1,153 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.extension; + +import static io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties.empty; + +import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; +import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; +import java.time.Duration; +import java.util.Collections; +import java.util.HashMap; +import java.util.List; +import java.util.Map; +import java.util.function.BiFunction; +import javax.annotation.Nullable; + +/** + * A {@link ConfigProperties} which resolves properties based on {@link StructuredConfigProperties}. + * + *

Only properties starting with "otel.instrumentation." are resolved. Others return null (or + * default value if provided). + * + *

To resolve: + * + *

+ * + *

For example, given the following YAML, asking for {@code + * ConfigProperties#getString("otel.instrumentation.common.string_key")} yields "value": + * + *

+ *   instrumentation:
+ *     java:
+ *       common:
+ *         string_key: value
+ * 
+ */ +final class StructuredConfigPropertiesBridge implements ConfigProperties { + + private static final String OTEL_INSTRUMENTATION_PREFIX = "otel.instrumentation."; + + // The node at .instrumentation.java + private final StructuredConfigProperties instrumentationJavaNode; + + StructuredConfigPropertiesBridge(StructuredConfigProperties rootStructuredConfigProperties) { + instrumentationJavaNode = + rootStructuredConfigProperties + .getStructured("instrumentation", empty()) + .getStructured("java", empty()); + } + + @Nullable + @Override + public String getString(String propertyName) { + return getPropertyValue(propertyName, StructuredConfigProperties::getString); + } + + @Nullable + @Override + public Boolean getBoolean(String propertyName) { + return getPropertyValue(propertyName, StructuredConfigProperties::getBoolean); + } + + @Nullable + @Override + public Integer getInt(String propertyName) { + return getPropertyValue(propertyName, StructuredConfigProperties::getInt); + } + + @Nullable + @Override + public Long getLong(String propertyName) { + return getPropertyValue(propertyName, StructuredConfigProperties::getLong); + } + + @Nullable + @Override + public Double getDouble(String propertyName) { + return getPropertyValue(propertyName, StructuredConfigProperties::getDouble); + } + + @Nullable + @Override + public Duration getDuration(String propertyName) { + Long millis = getPropertyValue(propertyName, StructuredConfigProperties::getLong); + if (millis == null) { + return null; + } + return Duration.ofMillis(millis); + } + + @Override + public List getList(String propertyName) { + List propertyValue = + getPropertyValue( + propertyName, + (properties, lastPart) -> properties.getScalarList(lastPart, String.class)); + return propertyValue == null ? Collections.emptyList() : propertyValue; + } + + @Override + public Map getMap(String propertyName) { + StructuredConfigProperties propertyValue = + getPropertyValue(propertyName, StructuredConfigProperties::getStructured); + if (propertyValue == null) { + return Collections.emptyMap(); + } + Map result = new HashMap<>(); + propertyValue + .getPropertyKeys() + .forEach( + key -> { + String value = propertyValue.getString(key); + if (value == null) { + return; + } + result.put(key, value); + }); + return Collections.unmodifiableMap(result); + } + + @Nullable + private T getPropertyValue( + String property, BiFunction extractor) { + if (!property.startsWith(OTEL_INSTRUMENTATION_PREFIX)) { + return null; + } + String suffix = property.substring(OTEL_INSTRUMENTATION_PREFIX.length()); + // Split the remainder of the property on ".", and walk to the N-1 entry + String[] segments = suffix.split("\\."); + if (segments.length == 0) { + return null; + } + StructuredConfigProperties target = instrumentationJavaNode; + if (segments.length > 1) { + for (int i = 0; i < segments.length - 1; i++) { + target = target.getStructured(segments[i], empty()); + } + } + String lastPart = segments[segments.length - 1]; + return extractor.apply(target, lastPart); + } +} diff --git a/javaagent-extension-api/src/test/java/io/opentelemetry/javaagent/extension/StructuredConfigPropertiesBridgeTest.java b/javaagent-extension-api/src/test/java/io/opentelemetry/javaagent/extension/StructuredConfigPropertiesBridgeTest.java new file mode 100644 index 000000000000..304faac6b9fb --- /dev/null +++ b/javaagent-extension-api/src/test/java/io/opentelemetry/javaagent/extension/StructuredConfigPropertiesBridgeTest.java @@ -0,0 +1,120 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.javaagent.extension; + +import static org.assertj.core.api.Assertions.assertThat; + +import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; +import io.opentelemetry.sdk.autoconfigure.spi.internal.StructuredConfigProperties; +import io.opentelemetry.sdk.extension.incubator.fileconfig.FileConfiguration; +import java.io.ByteArrayInputStream; +import java.nio.charset.StandardCharsets; +import java.time.Duration; +import java.util.Arrays; +import java.util.HashMap; +import java.util.Map; +import org.junit.jupiter.api.Test; + +class StructuredConfigPropertiesBridgeTest { + + private static final String YAML = + "file_format: 0.3\n" + + "instrumentation:\n" + + " java:\n" + + " common:\n" + + " default-enabled: true\n" + + " runtime-telemetry:\n" + + " enabled: false\n" + + " example-instrumentation:\n" + + " string_key: value\n" + + " bool_key: true\n" + + " int_key: 1\n" + + " double_key: 1.1\n" + + " list_key:\n" + + " - value1\n" + + " - value2\n" + + " - true\n" + + " map_key:\n" + + " string_key1: value1\n" + + " string_key2: value2\n" + + " bool_key: true\n"; + + private final StructuredConfigProperties structuredConfigProperties = + FileConfiguration.toConfigProperties( + new ByteArrayInputStream(YAML.getBytes(StandardCharsets.UTF_8))); + private final ConfigProperties bridge = + new StructuredConfigPropertiesBridge(structuredConfigProperties); + private final ConfigProperties emptyBridge = + new StructuredConfigPropertiesBridge( + FileConfiguration.toConfigProperties( + new ByteArrayInputStream("file_format: 0.3\n".getBytes(StandardCharsets.UTF_8)))); + + @Test + void getProperties() { + // only properties starting with "otel.instrumentation." are resolved + // 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.common.default-enabled")).isTrue(); + assertThat(bridge.getBoolean("otel.instrumentation.runtime-telemetry.enabled")).isFalse(); + + // check all the types + Map expectedMap = new HashMap<>(); + expectedMap.put("string_key1", "value1"); + expectedMap.put("string_key2", "value2"); + assertThat(bridge.getString("otel.instrumentation.example-instrumentation.string_key")) + .isEqualTo("value"); + assertThat(bridge.getBoolean("otel.instrumentation.example-instrumentation.bool_key")).isTrue(); + assertThat(bridge.getInt("otel.instrumentation.example-instrumentation.int_key")).isEqualTo(1); + assertThat(bridge.getLong("otel.instrumentation.example-instrumentation.int_key")) + .isEqualTo(1L); + assertThat(bridge.getDuration("otel.instrumentation.example-instrumentation.int_key")) + .isEqualTo(Duration.ofMillis(1)); + assertThat(bridge.getDouble("otel.instrumentation.example-instrumentation.double_key")) + .isEqualTo(1.1); + assertThat(bridge.getList("otel.instrumentation.example-instrumentation.list_key")) + .isEqualTo(Arrays.asList("value1", "value2")); + assertThat(bridge.getMap("otel.instrumentation.example-instrumentation.map_key")) + .isEqualTo(expectedMap); + + // asking for properties with the wrong type returns null + assertThat(bridge.getBoolean("otel.instrumentation.example-instrumentation.string_key")) + .isNull(); + assertThat(bridge.getString("otel.instrumentation.example-instrumentation.bool_key")).isNull(); + assertThat(bridge.getString("otel.instrumentation.example-instrumentation.int_key")).isNull(); + assertThat(bridge.getString("otel.instrumentation.example-instrumentation.double_key")) + .isNull(); + assertThat(bridge.getString("otel.instrumentation.example-instrumentation.list_key")).isNull(); + assertThat(bridge.getString("otel.instrumentation.example-instrumentation.map_key")).isNull(); + + // check all the types + assertThat(bridge.getString("otel.instrumentation.other-instrumentation.string_key", "value")) + .isEqualTo("value"); + assertThat(bridge.getBoolean("otel.instrumentation.other-instrumentation.bool_key", true)) + .isTrue(); + assertThat(bridge.getInt("otel.instrumentation.other-instrumentation.int_key", 1)).isEqualTo(1); + assertThat(bridge.getLong("otel.instrumentation.other-instrumentation.int_key", 1L)) + .isEqualTo(1L); + assertThat( + bridge.getDuration( + "otel.instrumentation.other-instrumentation.int_key", Duration.ofMillis(1))) + .isEqualTo(Duration.ofMillis(1)); + assertThat(bridge.getDouble("otel.instrumentation.other-instrumentation.double_key", 1.1)) + .isEqualTo(1.1); + assertThat( + bridge.getList( + "otel.instrumentation.other-instrumentation.list_key", + Arrays.asList("value1", "value2"))) + .isEqualTo(Arrays.asList("value1", "value2")); + assertThat(bridge.getMap("otel.instrumentation.other-instrumentation.map_key", expectedMap)) + .isEqualTo(expectedMap); + } +} 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 54c6938c96d9..5d1f279e63f2 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 @@ -42,7 +42,6 @@ import io.opentelemetry.javaagent.tooling.util.Trie; import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk; import io.opentelemetry.sdk.autoconfigure.SdkAutoconfigureAccess; -import io.opentelemetry.sdk.autoconfigure.internal.AutoConfigureUtil; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import java.lang.instrument.Instrumentation; import java.util.ArrayList; @@ -121,7 +120,7 @@ private static void installBytebuddyAgent( AutoConfiguredOpenTelemetrySdk autoConfiguredSdk = installOpenTelemetrySdk(extensionClassLoader); - ConfigProperties sdkConfig = AutoConfigureUtil.getConfig(autoConfiguredSdk); + ConfigProperties sdkConfig = AgentListener.resolveConfigProperties(autoConfiguredSdk); AgentInstrumentationConfig.internalInitializeConfig(new ConfigPropertiesBridge(sdkConfig)); copyNecessaryConfigToSystemProperties(sdkConfig); @@ -196,7 +195,7 @@ private static void installBytebuddyAgent( addHttpServerResponseCustomizers(extensionClassLoader); - runAfterAgentListeners(agentListeners, autoConfiguredSdk); + runAfterAgentListeners(agentListeners, autoConfiguredSdk, sdkConfig); } private static void copyNecessaryConfigToSystemProperties(ConfigProperties config) { @@ -268,7 +267,9 @@ public void customize( } private static void runAfterAgentListeners( - Iterable agentListeners, AutoConfiguredOpenTelemetrySdk autoConfiguredSdk) { + Iterable agentListeners, + AutoConfiguredOpenTelemetrySdk autoConfiguredSdk, + ConfigProperties sdkConfigProperties) { // java.util.logging.LogManager maintains a final static LogManager, which is created during // class initialization. Some AgentListener implementations may use JRE bootstrap classes // which touch this class (e.g. JFR classes or some MBeans). @@ -286,8 +287,7 @@ private static void runAfterAgentListeners( // the application is already setting the global LogManager and AgentListener won't be able // to touch it due to class loader locking. boolean shouldForceSynchronousAgentListenersCalls = - AutoConfigureUtil.getConfig(autoConfiguredSdk) - .getBoolean(FORCE_SYNCHRONOUS_AGENT_LISTENERS_CONFIG, false); + sdkConfigProperties.getBoolean(FORCE_SYNCHRONOUS_AGENT_LISTENERS_CONFIG, false); boolean javaBefore9 = isJavaBefore9(); if (!shouldForceSynchronousAgentListenersCalls && javaBefore9 && isAppUsingCustomLogManager()) { logger.fine("Custom JUL LogManager detected: delaying AgentListener#afterAgent() calls"); diff --git a/javaagent-tooling/src/test/resources/config.yaml b/javaagent-tooling/src/test/resources/config.yaml new file mode 100644 index 000000000000..02642e40fe24 --- /dev/null +++ b/javaagent-tooling/src/test/resources/config.yaml @@ -0,0 +1,20 @@ +instrumentation: + java: + common: + default-enabled: true + runtime-telemetry: + enabled: false + external-annotations: + enabled: true + example-instrumentation: + string_key: value + bool_key: true + int_key: 1 + double_key: 1.1 + list_key: + - value1 + - value2 + map_key: + string_key1: value1 + string_key2: value2 + bool_key: true