Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
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 JAVA_COMMON_SERVICE_PEER_MAPPING = "java.common.service_peer_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 @@ -114,17 +108,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 @@ -240,15 +223,7 @@ private String resolvePropertyKey(String name) {
translatedPath.append(translateName(segments[i]));
}

String translated = translatedPath.toString();

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

// Standard mapping
return "otel.instrumentation." + translated;
return "otel.instrumentation." + translatedPath;
}

private String pathWithName(String name) {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,6 @@

package io.opentelemetry.instrumentation.config.bridge;

import static io.opentelemetry.api.incubator.config.DeclarativeConfigProperties.empty;
import static java.util.Collections.emptyList;
import static java.util.Collections.emptyMap;
import static java.util.Objects.requireNonNull;
Expand Down Expand Up @@ -171,7 +170,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 @@ -76,15 +76,6 @@ void testTranslateName_withExperimentalInMiddle() {
.isTrue();
}

@Test
void testAgentPrefix() {
DeclarativeConfigProperties config = createConfig("otel.javaagent.experimental.indy", "true");

assertThat(config.getStructured("java").getStructured("agent").getBoolean("indy/development"))
.isNotNull()
.isTrue();
}

@Test
void testJmxPrefix() {
DeclarativeConfigProperties config = createConfig("otel.jmx.enabled", "true");
Expand Down Expand Up @@ -243,61 +234,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 @@ -5,12 +5,10 @@

package io.opentelemetry.instrumentation.config.bridge;

import static java.util.Objects.requireNonNull;
import static org.assertj.core.api.Assertions.assertThat;

import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfiguration;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalInstrumentationModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel;
import io.opentelemetry.sdk.internal.SdkConfigProvider;
import java.time.Duration;
Expand All @@ -23,22 +21,10 @@
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(DeclarativeConfiguration.toConfigProperties(emptyModel));
emptyBridge =
new DeclarativeConfigPropertiesBridgeBuilder()
.buildFromInstrumentationConfig(
requireNonNull(emptyConfigProvider.getInstrumentationConfig()));
}

private static ConfigProperties create(DeclarativeConfigPropertiesBridgeBuilder builder) {
Expand All @@ -58,9 +44,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
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.extension.AgentListener;
import io.opentelemetry.javaagent.tooling.config.AgentConfig;
import io.opentelemetry.javaagent.extension.instrumentation.internal.AgentDistributionConfig;
import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk;
import java.lang.reflect.Method;

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

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import io.opentelemetry.instrumentation.runtimemetrics.java17.RuntimeMetrics;
import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.RuntimeMetricsConfigUtil;
import io.opentelemetry.javaagent.extension.AgentListener;
import io.opentelemetry.javaagent.tooling.config.AgentConfig;
import io.opentelemetry.javaagent.extension.instrumentation.internal.AgentDistributionConfig;
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());
AgentDistributionConfig.get().isInstrumentationDefaultEnabled());
if (runtimeMetrics != null) {
Runtime.getRuntime()
.addShutdownHook(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ private RuntimeMetricsConfigUtil() {}

@Nullable
public static RuntimeMetrics configure(
RuntimeMetricsBuilder builder, OpenTelemetry openTelemetry, String instrumentationMode) {
RuntimeMetricsBuilder builder, OpenTelemetry openTelemetry, boolean defaultEnabled) {
/*
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
Expand All @@ -33,7 +33,7 @@ public static RuntimeMetrics configure(
.getBoolean("enabled", false)) {
// default configuration
} else if (DeclarativeConfigUtil.getInstrumentationConfig(openTelemetry, "runtime_telemetry")
.getBoolean("enabled", instrumentationMode.equals("default"))) {
.getBoolean("enabled", defaultEnabled)) {
// This only uses metrics gathered by JMX
builder.disableAllFeatures();
} else {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@
import io.opentelemetry.instrumentation.runtimemetrics.java8.RuntimeMetrics;
import io.opentelemetry.instrumentation.runtimemetrics.java8.internal.RuntimeMetricsConfigUtil;
import io.opentelemetry.javaagent.extension.AgentListener;
import io.opentelemetry.javaagent.tooling.config.AgentConfig;
import io.opentelemetry.javaagent.extension.instrumentation.internal.AgentDistributionConfig;
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());
AgentDistributionConfig.get().isInstrumentationDefaultEnabled());
if (runtimeMetrics != null) {
Runtime.getRuntime()
.addShutdownHook(
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,10 +21,10 @@ private RuntimeMetricsConfigUtil() {}

@Nullable
public static RuntimeMetrics configure(
RuntimeMetricsBuilder builder, OpenTelemetry openTelemetry, String instrumentationMode) {
RuntimeMetricsBuilder builder, OpenTelemetry openTelemetry, boolean defaultEnabled) {
DeclarativeConfigProperties config =
DeclarativeConfigUtil.getInstrumentationConfig(openTelemetry, "runtime_telemetry");
if (!config.getBoolean("enabled", instrumentationMode.equals("default"))) {
if (!config.getBoolean("enabled", defaultEnabled)) {
// nothing is enabled
return null;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,11 @@

package io.opentelemetry.instrumentation.spring.autoconfigure.internal;

import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException;
import static java.util.Collections.emptyList;

import java.util.Arrays;
import java.util.List;
import org.springframework.boot.context.properties.bind.Binder;
import org.springframework.core.env.Environment;

/**
Expand All @@ -18,7 +22,7 @@ private EarlyConfig() {}
public static boolean otelEnabled(Environment environment) {
boolean disabled =
environment.getProperty(
getPropertyName(environment, "otel.sdk.disabled", "otel.disabled"),
isDeclarativeConfig(environment) ? "otel.disabled" : "otel.sdk.disabled",
Boolean.class,
false);
return !disabled;
Expand All @@ -28,48 +32,51 @@ public static boolean isDeclarativeConfig(Environment environment) {
return environment.getProperty("otel.file_format", String.class) != null;
}

public static boolean isDefaultEnabled(Environment environment) {
public static boolean isInstrumentationEnabled(
Environment environment, String name, boolean enabledByDefault) {
if (isDeclarativeConfig(environment)) {
String mode =
environment.getProperty(
"otel.instrumentation/development.java.spring_starter.instrumentation_mode",
String.class,
"default");
String snakeCase = name.replace('-', '_');

switch (mode) {
case "none":
return false;
case "default":
return true;
default:
throw new ConfigurationException("Unknown instrumentation mode: " + mode);
List<String> disabled =
bindList(environment, "otel.distribution.spring_starter.instrumentation.disabled");
if (disabled.contains(snakeCase)) {
return false;
}

List<String> enabled =
bindList(environment, "otel.distribution.spring_starter.instrumentation.enabled");
if (enabled.contains(snakeCase)) {
return true;
}

if (!enabledByDefault) {
return false;
}
} else {
return environment.getProperty(
"otel.instrumentation.common.default-enabled", Boolean.class, true);
"otel.distribution.spring_starter.instrumentation.default_enabled", Boolean.class, true);
}
}

public static boolean isInstrumentationEnabled(
Environment environment, String name, boolean defaultValue) {
String property =
getPropertyName(
environment,
String.format("otel.instrumentation.%s.enabled", name),
String.format(
"otel.instrumentation/development.java.%s.enabled", name.replace('-', '_')));
Boolean explicit = environment.getProperty(property, Boolean.class);
Boolean explicit =
environment.getProperty(
String.format("otel.instrumentation.%s.enabled", name), Boolean.class);
if (explicit != null) {
return explicit;
}
if (!defaultValue) {
if (!enabledByDefault) {
return false;
}
return isDefaultEnabled(environment);
return environment.getProperty(
"otel.instrumentation.common.default-enabled", Boolean.class, true);
}

private static String getPropertyName(
Environment environment, String propertyBased, String declarative) {
return isDeclarativeConfig(environment) ? declarative : propertyBased;
// Environment.getProperty(key, List.class) does not handle indexed properties (e.g.
// enabled[0]=spring_web); Binder handles both indexed and comma-separated list formats
private static List<String> bindList(Environment environment, String key) {
// Binder requires canonical property names (lowercase with hyphens, no underscores)
String canonicalKey = key.replace('_', '-');
return Binder.get(environment)
.bind(canonicalKey, String[].class)
.map(Arrays::asList)
.orElse(emptyList());
}
}
Loading
Loading