Support declarative configuration (#12265)
This commit is contained in:
parent
d8eddfc726
commit
780cdf4a93
|
|
@ -15,7 +15,6 @@ import io.opentelemetry.instrumentation.jmx.engine.MetricConfiguration;
|
|||
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 =
|
||||
|
|
|
|||
|
|
@ -8,7 +8,6 @@ package io.opentelemetry.javaagent.instrumentation.oshi;
|
|||
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)) {
|
||||
|
|
|
|||
|
|
@ -12,7 +12,6 @@ import io.opentelemetry.instrumentation.runtimemetrics.java17.RuntimeMetrics;
|
|||
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;
|
||||
|
|
|
|||
|
|
@ -7,9 +7,9 @@ package io.opentelemetry.instrumentation.javaagent.runtimemetrics.java8;
|
|||
|
||||
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) {
|
||||
|
|
|
|||
|
|
@ -19,7 +19,6 @@ import io.opentelemetry.instrumentation.runtimemetrics.java8.internal.Experiment
|
|||
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)
|
||||
|
|
|
|||
|
|
@ -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")
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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");
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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}.
|
||||
*
|
||||
* <p>Only properties starting with "otel.instrumentation." are resolved. Others return null (or
|
||||
* default value if provided).
|
||||
*
|
||||
* <p>To resolve:
|
||||
*
|
||||
* <ul>
|
||||
* <li>"otel.instrumentation" refers to the ".instrumentation.java" node
|
||||
* <li>The portion of the property after "otel.instrumentation." is split into segments based on
|
||||
* ".".
|
||||
* <li>For each N-1 segment, we walk down the tree to find the relevant leaf {@link
|
||||
* StructuredConfigProperties}.
|
||||
* <li>We extract the property from the resolved {@link StructuredConfigProperties} using the last
|
||||
* segment as the property key.
|
||||
* </ul>
|
||||
*
|
||||
* <p>For example, given the following YAML, asking for {@code
|
||||
* ConfigProperties#getString("otel.instrumentation.common.string_key")} yields "value":
|
||||
*
|
||||
* <pre>
|
||||
* instrumentation:
|
||||
* java:
|
||||
* common:
|
||||
* string_key: value
|
||||
* </pre>
|
||||
*/
|
||||
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<String> getList(String propertyName) {
|
||||
List<String> propertyValue =
|
||||
getPropertyValue(
|
||||
propertyName,
|
||||
(properties, lastPart) -> properties.getScalarList(lastPart, String.class));
|
||||
return propertyValue == null ? Collections.emptyList() : propertyValue;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Map<String, String> getMap(String propertyName) {
|
||||
StructuredConfigProperties propertyValue =
|
||||
getPropertyValue(propertyName, StructuredConfigProperties::getStructured);
|
||||
if (propertyValue == null) {
|
||||
return Collections.emptyMap();
|
||||
}
|
||||
Map<String, String> 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> T getPropertyValue(
|
||||
String property, BiFunction<StructuredConfigProperties, String, T> 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);
|
||||
}
|
||||
}
|
||||
|
|
@ -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<String, String> 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);
|
||||
}
|
||||
}
|
||||
|
|
@ -42,7 +42,6 @@ import io.opentelemetry.javaagent.tooling.muzzle.AgentTooling;
|
|||
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 @@ public class AgentInstaller {
|
|||
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 @@ public class AgentInstaller {
|
|||
|
||||
addHttpServerResponseCustomizers(extensionClassLoader);
|
||||
|
||||
runAfterAgentListeners(agentListeners, autoConfiguredSdk);
|
||||
runAfterAgentListeners(agentListeners, autoConfiguredSdk, sdkConfig);
|
||||
}
|
||||
|
||||
private static void copyNecessaryConfigToSystemProperties(ConfigProperties config) {
|
||||
|
|
@ -268,7 +267,9 @@ public class AgentInstaller {
|
|||
}
|
||||
|
||||
private static void runAfterAgentListeners(
|
||||
Iterable<AgentListener> agentListeners, AutoConfiguredOpenTelemetrySdk autoConfiguredSdk) {
|
||||
Iterable<AgentListener> 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 @@ public class AgentInstaller {
|
|||
// 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");
|
||||
|
|
|
|||
|
|
@ -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
|
||||
Loading…
Reference in New Issue