Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
44 commits
Select commit Hold shift + click to select a range
1a8f787
add InstrumentationMode enum
zeitlinger Jan 6, 2026
a8f86d6
add InstrumentationMode enum
zeitlinger Jan 6, 2026
c1c20db
add module_configuration
zeitlinger Jan 9, 2026
b38aff3
add module_configuration
zeitlinger Jan 9, 2026
42b9deb
spring
zeitlinger Jan 9, 2026
c63eba0
spring
zeitlinger Jan 9, 2026
1cae14b
revert first try
zeitlinger Jan 9, 2026
9dbe2e8
distro node
zeitlinger Jan 9, 2026
546b8f7
distro node
zeitlinger Jan 9, 2026
2935e91
distro node
zeitlinger Jan 9, 2026
4294195
distro node
zeitlinger Jan 9, 2026
eecb79d
distro node
zeitlinger Jan 9, 2026
af763bf
distro node
zeitlinger Jan 9, 2026
34a8975
distro node
zeitlinger Jan 9, 2026
3344d77
add EnabledInstrumentations
zeitlinger Jan 10, 2026
18e6f25
add EnabledInstrumentations
zeitlinger Jan 10, 2026
807b49f
add EnabledInstrumentations
zeitlinger Jan 10, 2026
912aed5
add EnabledInstrumentations
zeitlinger Jan 10, 2026
16290a8
add EnabledInstrumentations
zeitlinger Jan 10, 2026
5a08004
use distro node
zeitlinger Jan 10, 2026
9cb0900
use distro node
zeitlinger Jan 10, 2026
d66455b
use distro node
zeitlinger Jan 10, 2026
b757e53
AgentDistributionConfig
zeitlinger Jan 10, 2026
0b42fa4
AgentDistributionConfig
zeitlinger Jan 10, 2026
50f770c
AgentDistributionConfig
zeitlinger Jan 10, 2026
3a9bfbd
fix
zeitlinger Jan 12, 2026
a664a58
fix
zeitlinger Jan 12, 2026
b4a6e28
fix
zeitlinger Jan 12, 2026
4f544e5
fix
zeitlinger Jan 12, 2026
da73470
fix
zeitlinger Jan 12, 2026
1b6bc6f
thread details should not move to distribution setting
zeitlinger Jan 12, 2026
f1518fb
fix thread details
zeitlinger Jan 12, 2026
63c56c9
split off AgentEnabledInstrumentations
zeitlinger Jan 12, 2026
4075d43
otel.javaagent.experimental.force-synchronous-agent-listeners is an e…
zeitlinger Jan 12, 2026
0c27cec
Revert "otel.javaagent.experimental.force-synchronous-agent-listeners…
zeitlinger Jan 12, 2026
8330e44
fix
zeitlinger Jan 12, 2026
5333c2f
format
zeitlinger Jan 13, 2026
af1da49
rebase
zeitlinger Jan 13, 2026
5dbf29f
cleanup
zeitlinger Jan 13, 2026
f756ba0
cleanup
zeitlinger Jan 13, 2026
8f21a2a
cleanup
zeitlinger Jan 13, 2026
f5a7b7e
fix
zeitlinger Jan 13, 2026
d6d9687
fix
zeitlinger Jan 13, 2026
4ffc8d5
move AgentDistributionConfig to extension API
zeitlinger Jan 14, 2026
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -30,12 +30,6 @@ public final class ConfigPropertiesBackedDeclarativeConfigProperties

private static final String GENERAL_PEER_SERVICE_MAPPING = "general.peer.service_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<String, String> SPECIAL_MAPPINGS;

static {
Expand Down Expand Up @@ -115,17 +109,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));
}

Expand Down Expand Up @@ -243,9 +226,10 @@ private String resolvePropertyKey(String name) {

String translated = translatedPath.toString();

// Handle agent prefix: java.agent.* → otel.javaagent.*
if (translated.startsWith("agent.")) {
return "otel.java" + translated;
// Handle agent prefix: java.javaagent.* → otel.javaagent.*
// is only called from OpenTelemetryInstaller
if (translated.startsWith("javaagent.")) {
return "otel." + translated;
}

// Standard mapping
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,6 @@

package io.opentelemetry.instrumentation.config.bridge;

import static io.opentelemetry.api.incubator.config.DeclarativeConfigProperties.empty;

import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import java.time.Duration;
Expand Down Expand Up @@ -169,7 +167,7 @@ private <T> 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];
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -79,7 +79,9 @@ void testTranslateName_withExperimentalInMiddle() {
void testAgentPrefix() {
DeclarativeConfigProperties config = createConfig("otel.javaagent.experimental.indy", "true");

assertThat(config.getStructured("java").getStructured("agent").getBoolean("indy/development"))
// only called from OpenTelemetryInstaller
assertThat(
config.getStructured("java").getStructured("javaagent").getBoolean("indy/development"))
.isNotNull()
.isTrue();
}
Expand Down Expand Up @@ -238,61 +240,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<String, String> properties = new HashMap<>();
properties.put(key, value);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,34 +10,21 @@
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfiguration;
import io.opentelemetry.sdk.extension.incubator.fileconfig.SdkConfigProvider;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalInstrumentationModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel;
import java.time.Duration;
import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Objects;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;

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(emptyModel);
emptyBridge =
new DeclarativeConfigPropertiesBridgeBuilder()
.buildFromInstrumentationConfig(
Objects.requireNonNull(emptyConfigProvider.getInstrumentationConfig()));
}

private static ConfigProperties create(DeclarativeConfigPropertiesBridgeBuilder builder) {
Expand All @@ -56,9 +43,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();
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,54 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.api.incubator.config;

import javax.annotation.Nullable;

/** Provides information about which instrumentations are enabled. */
public interface EnabledInstrumentations {
/**
* Returns whether the given instrumentation is enabled.
*
* @param instrumentationName the name of the instrumentation
* @return {@code Boolean.TRUE} if the instrumentation is enabled, {@code Boolean.FALSE} if it is
* disabled, or {@code null} if the default setting should be used
*/
@Nullable
Boolean getEnabled(String instrumentationName);

/**
* Returns whether instrumentations are enabled by default.
*
* @return {@code true} if instrumentations are enabled by default, {@code false} otherwise
*/
boolean isDefaultEnabled();

/**
* Returns whether the given instrumentation is explicitly enabled (i.e., not relying on the
* default setting).
*
* @param instrumentationName the name of the instrumentation
* @return {@code true} if the instrumentation is explicitly enabled, {@code false} otherwise
*/
default boolean isEnabledExplicitly(String instrumentationName) {
return Boolean.TRUE.equals(getEnabled(instrumentationName));
}

/**
* Returns whether the given instrumentation is enabled, falling back to the default setting if
* not explicitly configured.
*
* @param instrumentationName the name of the instrumentation
* @return {@code true} if the instrumentation is enabled, {@code false} otherwise
*/
default boolean isEnabled(String instrumentationName) {
Boolean enabled = getEnabled(instrumentationName);
if (enabled != null) {
return enabled;
}
return isDefaultEnabled();
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -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.bootstrap.internal.AgentEnabledInstrumentations;
import io.opentelemetry.javaagent.extension.AgentListener;
import io.opentelemetry.javaagent.tooling.config.AgentConfig;
import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk;
import java.lang.reflect.Method;

Expand All @@ -21,11 +20,7 @@ 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) {
if (!AgentEnabledInstrumentations.get().isEnabled("oshi")) {
return;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.instrumentation.runtimemetrics.java17.RuntimeMetrics;
import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.RuntimeMetricsConfigUtil;
import io.opentelemetry.javaagent.bootstrap.internal.AgentEnabledInstrumentations;
import io.opentelemetry.javaagent.extension.AgentListener;
import io.opentelemetry.javaagent.tooling.config.AgentConfig;
import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk;

/** An {@link AgentListener} that enables runtime metrics during agent startup. */
Expand All @@ -23,7 +23,7 @@ public void afterAgent(AutoConfiguredOpenTelemetrySdk autoConfiguredSdk) {
RuntimeMetricsConfigUtil.configure(
RuntimeMetrics.builder(GlobalOpenTelemetry.get()),
GlobalOpenTelemetry.get(),
AgentConfig.instrumentationMode());
AgentEnabledInstrumentations.get());
if (runtimeMetrics != null) {
Runtime.getRuntime()
.addShutdownHook(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
package io.opentelemetry.instrumentation.runtimemetrics.java17.internal;

import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.instrumentation.api.incubator.config.EnabledInstrumentations;
import io.opentelemetry.instrumentation.api.incubator.config.internal.DeclarativeConfigUtil;
import io.opentelemetry.instrumentation.runtimemetrics.java17.RuntimeMetrics;
import io.opentelemetry.instrumentation.runtimemetrics.java17.RuntimeMetricsBuilder;
Expand All @@ -20,25 +21,26 @@ private RuntimeMetricsConfigUtil() {}

@Nullable
public static RuntimeMetrics configure(
RuntimeMetricsBuilder builder, OpenTelemetry openTelemetry, String instrumentationMode) {
RuntimeMetricsBuilder builder,
OpenTelemetry openTelemetry,
EnabledInstrumentations enabledInstrumentations) {
/*
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
*/
if (DeclarativeConfigUtil.getInstrumentationConfig(openTelemetry, "runtime_telemetry_java17")
.getBoolean("enable_all", false)) {
builder.enableAllFeatures();
} else if (DeclarativeConfigUtil.getInstrumentationConfig(
openTelemetry, "runtime_telemetry_java17")
.getBoolean("enabled", false)) {
} else if (enabledInstrumentations.isEnabledExplicitly("runtime-telemetry-java17")) {
// default configuration
} else if (DeclarativeConfigUtil.getInstrumentationConfig(openTelemetry, "runtime_telemetry")
.getBoolean("enabled", instrumentationMode.equals("default"))) {
// This only uses metrics gathered by JMX
builder.disableAllFeatures();
} else {
// nothing is enabled
return null;
if (enabledInstrumentations.isEnabled("runtime-telemetry")) {
// This only uses metrics gathered by JMX
builder.disableAllFeatures();
} else {
// nothing is enabled
return null;
}
}

if (DeclarativeConfigUtil.getInstrumentationConfig(openTelemetry, "runtime_telemetry")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,8 +9,8 @@
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.instrumentation.runtimemetrics.java8.RuntimeMetrics;
import io.opentelemetry.instrumentation.runtimemetrics.java8.internal.RuntimeMetricsConfigUtil;
import io.opentelemetry.javaagent.bootstrap.internal.AgentEnabledInstrumentations;
import io.opentelemetry.javaagent.extension.AgentListener;
import io.opentelemetry.javaagent.tooling.config.AgentConfig;
import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk;

/** An {@link AgentListener} that enables runtime metrics during agent startup. */
Expand All @@ -27,7 +27,7 @@ public void afterAgent(AutoConfiguredOpenTelemetrySdk autoConfiguredSdk) {
RuntimeMetricsConfigUtil.configure(
RuntimeMetrics.builder(GlobalOpenTelemetry.get()),
GlobalOpenTelemetry.get(),
AgentConfig.instrumentationMode());
AgentEnabledInstrumentations.get());
if (runtimeMetrics != null) {
Runtime.getRuntime()
.addShutdownHook(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -3,5 +3,5 @@ plugins {
}

dependencies {
implementation(project(":instrumentation-api"))
implementation(project(":instrumentation-api-incubator"))
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties;
import io.opentelemetry.instrumentation.api.incubator.config.EnabledInstrumentations;
import io.opentelemetry.instrumentation.api.incubator.config.internal.DeclarativeConfigUtil;
import io.opentelemetry.instrumentation.runtimemetrics.java8.RuntimeMetrics;
import io.opentelemetry.instrumentation.runtimemetrics.java8.RuntimeMetricsBuilder;
Expand All @@ -21,14 +22,18 @@ private RuntimeMetricsConfigUtil() {}

@Nullable
public static RuntimeMetrics configure(
RuntimeMetricsBuilder builder, OpenTelemetry openTelemetry, String instrumentationMode) {
DeclarativeConfigProperties config =
DeclarativeConfigUtil.getInstrumentationConfig(openTelemetry, "runtime_telemetry");
if (!config.getBoolean("enabled", instrumentationMode.equals("default"))) {
RuntimeMetricsBuilder builder,
OpenTelemetry openTelemetry,
EnabledInstrumentations enabledInstrumentations) {

if (!enabledInstrumentations.isEnabled("runtime-telemetry")) {
// nothing is enabled
return null;
}

DeclarativeConfigProperties config =
DeclarativeConfigUtil.getInstrumentationConfig(openTelemetry, "runtime_telemetry");

if (config.getBoolean("emit_experimental_telemetry/development", false)) {
builder.emitExperimentalTelemetry();
}
Expand Down
Loading
Loading