Skip to content

Commit 3c573ea

Browse files
zeitlingertrask
andauthored
use Distribution node (#15822)
Signed-off-by: Gregor Zeitlinger <gregor.zeitlinger@grafana.com> Co-authored-by: Trask Stalnaker <trask.stalnaker@gmail.com>
1 parent bc533f6 commit 3c573ea

33 files changed

Lines changed: 590 additions & 319 deletions

File tree

declarative-config-bridge/src/main/java/io/opentelemetry/instrumentation/config/bridge/ConfigPropertiesBackedDeclarativeConfigProperties.java

Lines changed: 1 addition & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -30,12 +30,6 @@ public final class ConfigPropertiesBackedDeclarativeConfigProperties
3030

3131
private static final String JAVA_COMMON_SERVICE_PEER_MAPPING = "java.common.service_peer_mapping";
3232

33-
private static final String AGENT_INSTRUMENTATION_MODE = "java.agent.instrumentation_mode";
34-
private static final String SPRING_STARTER_INSTRUMENTATION_MODE =
35-
"java.spring_starter.instrumentation_mode";
36-
private static final String COMMON_DEFAULT_ENABLED =
37-
"otel.instrumentation.common.default-enabled";
38-
3933
private static final Map<String, String> SPECIAL_MAPPINGS;
4034

4135
static {
@@ -114,17 +108,6 @@ private ConfigPropertiesBackedDeclarativeConfigProperties(
114108
@Nullable
115109
@Override
116110
public String getString(String name) {
117-
String fullPath = pathWithName(name);
118-
119-
if (fullPath.equals(AGENT_INSTRUMENTATION_MODE)
120-
|| fullPath.equals(SPRING_STARTER_INSTRUMENTATION_MODE)) {
121-
Boolean value = configProperties.getBoolean(COMMON_DEFAULT_ENABLED);
122-
if (value != null) {
123-
return value ? "default" : "none";
124-
}
125-
return null;
126-
}
127-
128111
return configProperties.getString(resolvePropertyKey(name));
129112
}
130113

@@ -240,15 +223,7 @@ private String resolvePropertyKey(String name) {
240223
translatedPath.append(translateName(segments[i]));
241224
}
242225

243-
String translated = translatedPath.toString();
244-
245-
// Handle agent prefix: java.agent.* → otel.javaagent.*
246-
if (translated.startsWith("agent.")) {
247-
return "otel.java" + translated;
248-
}
249-
250-
// Standard mapping
251-
return "otel.instrumentation." + translated;
226+
return "otel.instrumentation." + translatedPath;
252227
}
253228

254229
private String pathWithName(String name) {

declarative-config-bridge/src/main/java/io/opentelemetry/instrumentation/config/bridge/DeclarativeConfigPropertiesBridge.java

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,6 @@
55

66
package io.opentelemetry.instrumentation.config.bridge;
77

8-
import static io.opentelemetry.api.incubator.config.DeclarativeConfigProperties.empty;
98
import static java.util.Collections.emptyList;
109
import static java.util.Collections.emptyMap;
1110
import static java.util.Objects.requireNonNull;
@@ -171,7 +170,7 @@ private <T> T getPropertyValue(
171170
DeclarativeConfigProperties target = baseNode;
172171
if (segments.length > 1) {
173172
for (int i = 0; i < segments.length - 1; i++) {
174-
target = target.getStructured(segments[i], empty());
173+
target = target.get(segments[i]);
175174
}
176175
}
177176
String lastPart = segments[segments.length - 1];

declarative-config-bridge/src/test/java/io/opentelemetry/instrumentation/config/bridge/ConfigPropertiesBackedDeclarativeConfigPropertiesTest.java

Lines changed: 0 additions & 64 deletions
Original file line numberDiff line numberDiff line change
@@ -76,15 +76,6 @@ void testTranslateName_withExperimentalInMiddle() {
7676
.isTrue();
7777
}
7878

79-
@Test
80-
void testAgentPrefix() {
81-
DeclarativeConfigProperties config = createConfig("otel.javaagent.experimental.indy", "true");
82-
83-
assertThat(config.getStructured("java").getStructured("agent").getBoolean("indy/development"))
84-
.isNotNull()
85-
.isTrue();
86-
}
87-
8879
@Test
8980
void testJmxPrefix() {
9081
DeclarativeConfigProperties config = createConfig("otel.jmx.enabled", "true");
@@ -243,61 +234,6 @@ void testWithoutJavaPrefix_doesNotMatch() {
243234
.isNull();
244235
}
245236

246-
@Test
247-
void testAgentInstrumentationMode_getString_booleanTrue() {
248-
DeclarativeConfigProperties config =
249-
createConfig("otel.instrumentation.common.default-enabled", "true");
250-
251-
assertThat(
252-
config.getStructured("java").getStructured("agent").getString("instrumentation_mode"))
253-
.isEqualTo("default");
254-
}
255-
256-
@Test
257-
void testAgentInstrumentationMode_getString_booleanFalse() {
258-
DeclarativeConfigProperties config =
259-
createConfig("otel.instrumentation.common.default-enabled", "false");
260-
261-
assertThat(
262-
config.getStructured("java").getStructured("agent").getString("instrumentation_mode"))
263-
.isEqualTo("none");
264-
}
265-
266-
@Test
267-
void testSpringStarterInstrumentationMode_getString_booleanTrue() {
268-
DeclarativeConfigProperties config =
269-
createConfig("otel.instrumentation.common.default-enabled", "true");
270-
271-
assertThat(
272-
config
273-
.getStructured("java")
274-
.getStructured("spring_starter")
275-
.getString("instrumentation_mode"))
276-
.isEqualTo("default");
277-
}
278-
279-
@Test
280-
void testSpringStarterInstrumentationMode_getString_booleanFalse() {
281-
DeclarativeConfigProperties config =
282-
createConfig("otel.instrumentation.common.default-enabled", "false");
283-
284-
assertThat(
285-
config
286-
.getStructured("java")
287-
.getStructured("spring_starter")
288-
.getString("instrumentation_mode"))
289-
.isEqualTo("none");
290-
}
291-
292-
@Test
293-
void testAgentInstrumentationMode_notSet() {
294-
DeclarativeConfigProperties config = createConfig("some.other.property", "value");
295-
296-
assertThat(
297-
config.getStructured("java").getStructured("agent").getString("instrumentation_mode"))
298-
.isNull();
299-
}
300-
301237
private static DeclarativeConfigProperties createConfig(String key, String value) {
302238
Map<String, String> properties = new HashMap<>();
303239
properties.put(key, value);

declarative-config-bridge/src/test/java/io/opentelemetry/instrumentation/config/bridge/DeclarativeConfigPropertiesBridgeTest.java

Lines changed: 0 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -5,12 +5,10 @@
55

66
package io.opentelemetry.instrumentation.config.bridge;
77

8-
import static java.util.Objects.requireNonNull;
98
import static org.assertj.core.api.Assertions.assertThat;
109

1110
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
1211
import io.opentelemetry.sdk.extension.incubator.fileconfig.DeclarativeConfiguration;
13-
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalInstrumentationModel;
1412
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel;
1513
import io.opentelemetry.sdk.internal.SdkConfigProvider;
1614
import java.time.Duration;
@@ -23,22 +21,10 @@
2321
class DeclarativeConfigPropertiesBridgeTest {
2422

2523
private ConfigProperties bridge;
26-
private ConfigProperties emptyBridge;
2724

2825
@BeforeEach
2926
void setup() {
3027
bridge = create(new DeclarativeConfigPropertiesBridgeBuilder());
31-
32-
OpenTelemetryConfigurationModel emptyModel =
33-
new OpenTelemetryConfigurationModel()
34-
.withAdditionalProperty(
35-
"instrumentation/development", new ExperimentalInstrumentationModel());
36-
SdkConfigProvider emptyConfigProvider =
37-
SdkConfigProvider.create(DeclarativeConfiguration.toConfigProperties(emptyModel));
38-
emptyBridge =
39-
new DeclarativeConfigPropertiesBridgeBuilder()
40-
.buildFromInstrumentationConfig(
41-
requireNonNull(emptyConfigProvider.getInstrumentationConfig()));
4228
}
4329

4430
private static ConfigProperties create(DeclarativeConfigPropertiesBridgeBuilder builder) {
@@ -58,9 +44,6 @@ void getProperties() {
5844
// asking for properties which don't exist or inaccessible shouldn't result in an error
5945
assertThat(bridge.getString("file_format")).isNull();
6046
assertThat(bridge.getString("file_format", "foo")).isEqualTo("foo");
61-
assertThat(emptyBridge.getBoolean("otel.instrumentation.common.default-enabled")).isNull();
62-
assertThat(emptyBridge.getBoolean("otel.instrumentation.common.default-enabled", true))
63-
.isTrue();
6447

6548
// common cases
6649
assertThat(bridge.getBoolean("otel.instrumentation.runtime-telemetry.enabled")).isFalse();

instrumentation/oshi/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/oshi/OshiMetricsInstaller.java

Lines changed: 3 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -6,9 +6,8 @@
66
package io.opentelemetry.javaagent.instrumentation.oshi;
77

88
import com.google.auto.service.AutoService;
9-
import io.opentelemetry.instrumentation.api.incubator.config.internal.DeclarativeConfigUtil;
109
import io.opentelemetry.javaagent.extension.AgentListener;
11-
import io.opentelemetry.javaagent.tooling.config.AgentConfig;
10+
import io.opentelemetry.javaagent.extension.instrumentation.internal.AgentDistributionConfig;
1211
import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk;
1312
import java.lang.reflect.Method;
1413

@@ -21,11 +20,8 @@ public class OshiMetricsInstaller implements AgentListener {
2120

2221
@Override
2322
public void afterAgent(AutoConfiguredOpenTelemetrySdk autoConfiguredSdk) {
24-
boolean enabled =
25-
DeclarativeConfigUtil.getInstrumentationConfig(
26-
autoConfiguredSdk.getOpenTelemetrySdk(), "oshi")
27-
.getBoolean("enabled", AgentConfig.instrumentationMode().equals("default"));
28-
if (!enabled) {
23+
AgentDistributionConfig config = AgentDistributionConfig.get();
24+
if (!config.isInstrumentationEnabled("oshi")) {
2925
return;
3026
}
3127

instrumentation/runtime-telemetry/runtime-telemetry-java17/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/runtimemetrics/java17/Java17RuntimeMetricsInstaller.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
import io.opentelemetry.instrumentation.runtimemetrics.java17.RuntimeMetrics;
1111
import io.opentelemetry.instrumentation.runtimemetrics.java17.internal.RuntimeMetricsConfigUtil;
1212
import io.opentelemetry.javaagent.extension.AgentListener;
13-
import io.opentelemetry.javaagent.tooling.config.AgentConfig;
13+
import io.opentelemetry.javaagent.extension.instrumentation.internal.AgentDistributionConfig;
1414
import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk;
1515

1616
/** An {@link AgentListener} that enables runtime metrics during agent startup. */
@@ -23,7 +23,7 @@ public void afterAgent(AutoConfiguredOpenTelemetrySdk autoConfiguredSdk) {
2323
RuntimeMetricsConfigUtil.configure(
2424
RuntimeMetrics.builder(GlobalOpenTelemetry.get()),
2525
GlobalOpenTelemetry.get(),
26-
AgentConfig.instrumentationMode());
26+
AgentDistributionConfig.get().isInstrumentationDefaultEnabled());
2727
if (runtimeMetrics != null) {
2828
Runtime.getRuntime()
2929
.addShutdownHook(

instrumentation/runtime-telemetry/runtime-telemetry-java17/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java17/internal/RuntimeMetricsConfigUtil.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ private RuntimeMetricsConfigUtil() {}
2020

2121
@Nullable
2222
public static RuntimeMetrics configure(
23-
RuntimeMetricsBuilder builder, OpenTelemetry openTelemetry, String instrumentationMode) {
23+
RuntimeMetricsBuilder builder, OpenTelemetry openTelemetry, boolean defaultEnabled) {
2424
/*
2525
By default, don't use any JFR metrics. May change this once semantic conventions are updated.
2626
If enabled, default to only the metrics not already covered by runtime-telemetry-java8
@@ -33,7 +33,7 @@ public static RuntimeMetrics configure(
3333
.getBoolean("enabled", false)) {
3434
// default configuration
3535
} else if (DeclarativeConfigUtil.getInstrumentationConfig(openTelemetry, "runtime_telemetry")
36-
.getBoolean("enabled", instrumentationMode.equals("default"))) {
36+
.getBoolean("enabled", defaultEnabled)) {
3737
// This only uses metrics gathered by JMX
3838
builder.disableAllFeatures();
3939
} else {

instrumentation/runtime-telemetry/runtime-telemetry-java8/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/runtimemetrics/java8/Java8RuntimeMetricsInstaller.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,7 @@
1010
import io.opentelemetry.instrumentation.runtimemetrics.java8.RuntimeMetrics;
1111
import io.opentelemetry.instrumentation.runtimemetrics.java8.internal.RuntimeMetricsConfigUtil;
1212
import io.opentelemetry.javaagent.extension.AgentListener;
13-
import io.opentelemetry.javaagent.tooling.config.AgentConfig;
13+
import io.opentelemetry.javaagent.extension.instrumentation.internal.AgentDistributionConfig;
1414
import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk;
1515

1616
/** An {@link AgentListener} that enables runtime metrics during agent startup. */
@@ -27,7 +27,7 @@ public void afterAgent(AutoConfiguredOpenTelemetrySdk autoConfiguredSdk) {
2727
RuntimeMetricsConfigUtil.configure(
2828
RuntimeMetrics.builder(GlobalOpenTelemetry.get()),
2929
GlobalOpenTelemetry.get(),
30-
AgentConfig.instrumentationMode());
30+
AgentDistributionConfig.get().isInstrumentationDefaultEnabled());
3131
if (runtimeMetrics != null) {
3232
Runtime.getRuntime()
3333
.addShutdownHook(

instrumentation/runtime-telemetry/runtime-telemetry-java8/library/src/main/java/io/opentelemetry/instrumentation/runtimemetrics/java8/internal/RuntimeMetricsConfigUtil.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,10 +21,10 @@ private RuntimeMetricsConfigUtil() {}
2121

2222
@Nullable
2323
public static RuntimeMetrics configure(
24-
RuntimeMetricsBuilder builder, OpenTelemetry openTelemetry, String instrumentationMode) {
24+
RuntimeMetricsBuilder builder, OpenTelemetry openTelemetry, boolean defaultEnabled) {
2525
DeclarativeConfigProperties config =
2626
DeclarativeConfigUtil.getInstrumentationConfig(openTelemetry, "runtime_telemetry");
27-
if (!config.getBoolean("enabled", instrumentationMode.equals("default"))) {
27+
if (!config.getBoolean("enabled", defaultEnabled)) {
2828
// nothing is enabled
2929
return null;
3030
}

instrumentation/spring/spring-boot-autoconfigure/src/main/java/io/opentelemetry/instrumentation/spring/autoconfigure/internal/EarlyConfig.java

Lines changed: 39 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -5,7 +5,11 @@
55

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

8-
import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException;
8+
import static java.util.Collections.emptyList;
9+
10+
import java.util.Arrays;
11+
import java.util.List;
12+
import org.springframework.boot.context.properties.bind.Binder;
913
import org.springframework.core.env.Environment;
1014

1115
/**
@@ -18,7 +22,7 @@ private EarlyConfig() {}
1822
public static boolean otelEnabled(Environment environment) {
1923
boolean disabled =
2024
environment.getProperty(
21-
getPropertyName(environment, "otel.sdk.disabled", "otel.disabled"),
25+
isDeclarativeConfig(environment) ? "otel.disabled" : "otel.sdk.disabled",
2226
Boolean.class,
2327
false);
2428
return !disabled;
@@ -28,48 +32,51 @@ public static boolean isDeclarativeConfig(Environment environment) {
2832
return environment.getProperty("otel.file_format", String.class) != null;
2933
}
3034

31-
public static boolean isDefaultEnabled(Environment environment) {
35+
public static boolean isInstrumentationEnabled(
36+
Environment environment, String name, boolean enabledByDefault) {
3237
if (isDeclarativeConfig(environment)) {
33-
String mode =
34-
environment.getProperty(
35-
"otel.instrumentation/development.java.spring_starter.instrumentation_mode",
36-
String.class,
37-
"default");
38+
String snakeCase = name.replace('-', '_');
3839

39-
switch (mode) {
40-
case "none":
41-
return false;
42-
case "default":
43-
return true;
44-
default:
45-
throw new ConfigurationException("Unknown instrumentation mode: " + mode);
40+
List<String> disabled =
41+
bindList(environment, "otel.distribution.spring_starter.instrumentation.disabled");
42+
if (disabled.contains(snakeCase)) {
43+
return false;
44+
}
45+
46+
List<String> enabled =
47+
bindList(environment, "otel.distribution.spring_starter.instrumentation.enabled");
48+
if (enabled.contains(snakeCase)) {
49+
return true;
50+
}
51+
52+
if (!enabledByDefault) {
53+
return false;
4654
}
47-
} else {
4855
return environment.getProperty(
49-
"otel.instrumentation.common.default-enabled", Boolean.class, true);
56+
"otel.distribution.spring_starter.instrumentation.default_enabled", Boolean.class, true);
5057
}
51-
}
5258

53-
public static boolean isInstrumentationEnabled(
54-
Environment environment, String name, boolean defaultValue) {
55-
String property =
56-
getPropertyName(
57-
environment,
58-
String.format("otel.instrumentation.%s.enabled", name),
59-
String.format(
60-
"otel.instrumentation/development.java.%s.enabled", name.replace('-', '_')));
61-
Boolean explicit = environment.getProperty(property, Boolean.class);
59+
Boolean explicit =
60+
environment.getProperty(
61+
String.format("otel.instrumentation.%s.enabled", name), Boolean.class);
6262
if (explicit != null) {
6363
return explicit;
6464
}
65-
if (!defaultValue) {
65+
if (!enabledByDefault) {
6666
return false;
6767
}
68-
return isDefaultEnabled(environment);
68+
return environment.getProperty(
69+
"otel.instrumentation.common.default-enabled", Boolean.class, true);
6970
}
7071

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

0 commit comments

Comments
 (0)