Skip to content

Commit f542b30

Browse files
use DeclarativeConfigUtil for library config usage (#15656)
Co-authored-by: Abhilash Garapati <abhilashgarapati12@gmail.com>
1 parent 0c04d38 commit f542b30

File tree

17 files changed

+411
-181
lines changed

17 files changed

+411
-181
lines changed

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

Lines changed: 7 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -73,10 +73,17 @@ public final class ConfigPropertiesBackedDeclarativeConfigProperties
7373
SPECIAL_MAPPINGS.put(
7474
"java.common.gen_ai.capture_message_content",
7575
"otel.instrumentation.genai.capture-message-content");
76+
// top-level common configs
77+
SPECIAL_MAPPINGS.put(
78+
"java.common.span_suppression_strategy/development",
79+
"otel.instrumentation.experimental.span-suppression-strategy");
7680
// renaming to match instrumentation module name
7781
SPECIAL_MAPPINGS.put(
7882
"java.opentelemetry_extension_annotations.exclude_methods",
7983
"otel.instrumentation.opentelemetry-annotations.exclude-methods");
84+
// renaming to avoid top level config
85+
SPECIAL_MAPPINGS.put(
86+
"java.servlet.javascript_snippet/development", "otel.experimental.javascript-snippet");
8087
}
8188

8289
private final ConfigProperties configProperties;

instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/instrumenter/InstrumenterBuilder.java

Lines changed: 49 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -5,11 +5,14 @@
55

66
package io.opentelemetry.instrumentation.api.instrumenter;
77

8+
import static io.opentelemetry.api.incubator.config.DeclarativeConfigProperties.empty;
89
import static java.util.Objects.requireNonNull;
910
import static java.util.logging.Level.WARNING;
1011

1112
import com.google.errorprone.annotations.CanIgnoreReturnValue;
1213
import io.opentelemetry.api.OpenTelemetry;
14+
import io.opentelemetry.api.incubator.ExtendedOpenTelemetry;
15+
import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties;
1316
import io.opentelemetry.api.metrics.Meter;
1417
import io.opentelemetry.api.metrics.MeterBuilder;
1518
import io.opentelemetry.api.trace.SpanKind;
@@ -48,11 +51,7 @@
4851
public final class InstrumenterBuilder<REQUEST, RESPONSE> {
4952

5053
private static final Logger logger = Logger.getLogger(InstrumenterBuilder.class.getName());
51-
52-
private static final SpanSuppressionStrategy spanSuppressionStrategy =
53-
SpanSuppressionStrategy.fromConfig(
54-
ConfigPropertiesUtil.getString(
55-
"otel.instrumentation.experimental.span-suppression-strategy"));
54+
private static final boolean supportsDeclarativeConfig = supportsDeclarativeConfig();
5655

5756
final OpenTelemetry openTelemetry;
5857
final String instrumentationName;
@@ -76,6 +75,20 @@ public final class InstrumenterBuilder<REQUEST, RESPONSE> {
7675
boolean propagateOperationListenersToOnEnd = false;
7776
boolean enabled = true;
7877

78+
private static boolean supportsDeclarativeConfig() {
79+
try {
80+
Class.forName("io.opentelemetry.api.incubator.ExtendedOpenTelemetry");
81+
return true;
82+
} catch (ClassNotFoundException e) {
83+
// The incubator module is not available.
84+
// This only happens in OpenTelemetry API instrumentation tests, where an older version of
85+
// OpenTelemetry API is used that does not have ExtendedOpenTelemetry.
86+
// Having the incubator module without ExtendedOpenTelemetry class should still return false
87+
// for those tests to avoid a ClassNotFoundException.
88+
return false;
89+
}
90+
}
91+
7992
static {
8093
Experimental.internalAddOperationListenerAttributesExtractor(
8194
(builder, operationListenerAttributesExtractor) ->
@@ -374,7 +387,28 @@ private String getSchemaUrl() {
374387

375388
SpanSuppressor buildSpanSuppressor() {
376389
return new SpanSuppressors.ByContextKey(
377-
spanSuppressionStrategy.create(getSpanKeysFromAttributesExtractors()));
390+
SpanSuppressionStrategy.fromConfig(getSpanSuppressionStrategy())
391+
.create(getSpanKeysFromAttributesExtractors()));
392+
}
393+
394+
@Nullable
395+
private String getSpanSuppressionStrategy() {
396+
// we cannot use DeclarativeConfigUtil here because it's not available in instrumentation-api
397+
if (maybeDeclarativeConfig(openTelemetry)) {
398+
DeclarativeConfigProperties instrumentationConfig =
399+
((ExtendedOpenTelemetry) openTelemetry).getConfigProvider().getInstrumentationConfig();
400+
if (instrumentationConfig == null) {
401+
return null;
402+
}
403+
404+
return instrumentationConfig
405+
.getStructured("java", empty())
406+
.getStructured("common", empty())
407+
.getString("span_suppression_strategy/development");
408+
} else {
409+
return ConfigPropertiesUtil.getString(
410+
"otel.instrumentation.experimental.span-suppression-strategy");
411+
}
378412
}
379413

380414
private Set<SpanKey> getSpanKeysFromAttributesExtractors() {
@@ -454,6 +488,15 @@ public void setSpanStatusExtractorCustomizer(
454488
}
455489
}
456490

491+
/**
492+
* Returns true if the current classpath supports declarative config and the instance may support
493+
* declarative config (the agent implements ExtendedOpenTelemetry even when declarative config
494+
* isn't used).
495+
*/
496+
private static boolean maybeDeclarativeConfig(OpenTelemetry openTelemetry) {
497+
return supportsDeclarativeConfig && openTelemetry instanceof ExtendedOpenTelemetry;
498+
}
499+
457500
private interface InstrumenterConstructor<RQ, RS> {
458501
Instrumenter<RQ, RS> create(InstrumenterBuilder<RQ, RS> builder);
459502

instrumentation-api/src/main/java/io/opentelemetry/instrumentation/api/internal/ConfigPropertiesUtil.java

Lines changed: 50 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,11 +17,38 @@
1717
*/
1818
public final class ConfigPropertiesUtil {
1919

20+
/**
21+
* Returns the boolean value of the given property name from system properties and environment
22+
* variables.
23+
*
24+
* <p>It's recommended to use {@link io.opentelemetry.api.incubator.config.ConfigProvider} instead
25+
* to support Declarative Config.
26+
*/
2027
public static boolean getBoolean(String propertyName, boolean defaultValue) {
28+
Boolean value = getBoolean(propertyName);
29+
return value == null ? defaultValue : value;
30+
}
31+
32+
/**
33+
* Returns the boolean value of the given property name from system properties and environment
34+
* variables.
35+
*
36+
* <p>It's recommended to use {@link io.opentelemetry.api.incubator.config.ConfigProvider} instead
37+
* to support Declarative Config.
38+
*/
39+
@Nullable
40+
public static Boolean getBoolean(String propertyName) {
2141
String strValue = getString(propertyName);
22-
return strValue == null ? defaultValue : Boolean.parseBoolean(strValue);
42+
return strValue == null ? null : Boolean.parseBoolean(strValue);
2343
}
2444

45+
/**
46+
* Returns the int value of the given property name from system properties and environment
47+
* variables.
48+
*
49+
* <p>It's recommended to use {@link io.opentelemetry.api.incubator.config.ConfigProvider} instead
50+
* to support Declarative Config.
51+
*/
2552
public static int getInt(String propertyName, int defaultValue) {
2653
String strValue = getString(propertyName);
2754
if (strValue == null) {
@@ -34,6 +61,13 @@ public static int getInt(String propertyName, int defaultValue) {
3461
}
3562
}
3663

64+
/**
65+
* Returns the string value of the given property name from system properties and environment
66+
* variables.
67+
*
68+
* <p>It's recommended to use {@link io.opentelemetry.api.incubator.config.ConfigProvider} instead
69+
* to support Declarative Config.
70+
*/
3771
@Nullable
3872
public static String getString(String propertyName) {
3973
String value = System.getProperty(propertyName);
@@ -43,11 +77,26 @@ public static String getString(String propertyName) {
4377
return System.getenv(toEnvVarName(propertyName));
4478
}
4579

80+
/**
81+
* Returns the string value of the given property name from system properties and environment
82+
* variables, or the default value if not found.
83+
*
84+
* <p>It's recommended to use {@link io.opentelemetry.api.incubator.config.ConfigProvider} instead
85+
* to support Declarative Config.
86+
*/
4687
public static String getString(String propertyName, String defaultValue) {
4788
String strValue = getString(propertyName);
4889
return strValue == null ? defaultValue : strValue;
4990
}
5091

92+
/**
93+
* Returns the list of strings value of the given property name from system properties and
94+
* environment variables, or the default value if not found. The property value is expected to be
95+
* a comma-separated list.
96+
*
97+
* <p>It's recommended to use {@link io.opentelemetry.api.incubator.config.ConfigProvider} instead
98+
* to support Declarative Config.
99+
*/
51100
public static List<String> getList(String propertyName, List<String> defaultValue) {
52101
String value = getString(propertyName);
53102
if (value == null) {

instrumentation/aws-sdk/aws-sdk-1.11/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v1_11/autoconfigure/TracingRequestHandler.java

Lines changed: 32 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,9 @@
1212
import com.amazonaws.Response;
1313
import com.amazonaws.handlers.RequestHandler2;
1414
import io.opentelemetry.api.GlobalOpenTelemetry;
15+
import io.opentelemetry.api.OpenTelemetry;
16+
import io.opentelemetry.instrumentation.api.incubator.config.internal.DeclarativeConfigUtil;
17+
import io.opentelemetry.instrumentation.api.incubator.config.internal.ExtendedDeclarativeConfigProperties;
1518
import io.opentelemetry.instrumentation.api.internal.ConfigPropertiesUtil;
1619
import io.opentelemetry.instrumentation.awssdk.v1_11.AwsSdkTelemetry;
1720

@@ -20,19 +23,35 @@
2023
*/
2124
public class TracingRequestHandler extends RequestHandler2 {
2225

23-
private static final RequestHandler2 DELEGATE =
24-
AwsSdkTelemetry.builder(GlobalOpenTelemetry.get())
25-
.setCaptureExperimentalSpanAttributes(
26-
ConfigPropertiesUtil.getBoolean(
27-
"otel.instrumentation.aws-sdk.experimental-span-attributes", false))
28-
.setMessagingReceiveTelemetryEnabled(
29-
ConfigPropertiesUtil.getBoolean(
30-
"otel.instrumentation.messaging.experimental.receive-telemetry.enabled", false))
31-
.setCapturedHeaders(
32-
ConfigPropertiesUtil.getList(
33-
"otel.instrumentation.messaging.experimental.capture-headers", emptyList()))
34-
.build()
35-
.newRequestHandler();
26+
private static final RequestHandler2 DELEGATE = buildDelegate(GlobalOpenTelemetry.get());
27+
28+
private static RequestHandler2 buildDelegate(OpenTelemetry openTelemetry) {
29+
ExtendedDeclarativeConfigProperties messaging =
30+
DeclarativeConfigUtil.getInstrumentationConfig(openTelemetry, "common").get("messaging");
31+
return AwsSdkTelemetry.builder(openTelemetry)
32+
.setCaptureExperimentalSpanAttributes(
33+
DeclarativeConfigUtil.getInstrumentationConfig(openTelemetry, "aws_sdk")
34+
.getBoolean(
35+
"experimental_span_attributes/development",
36+
ConfigPropertiesUtil.getBoolean(
37+
"otel.instrumentation.aws-sdk.experimental-span-attributes", false)))
38+
.setMessagingReceiveTelemetryEnabled(
39+
messaging
40+
.get("receive_telemetry/development")
41+
.getBoolean(
42+
"enabled",
43+
ConfigPropertiesUtil.getBoolean(
44+
"otel.instrumentation.messaging.experimental.receive-telemetry.enabled",
45+
false)))
46+
.setCapturedHeaders(
47+
messaging.getScalarList(
48+
"capture_headers/development",
49+
String.class,
50+
ConfigPropertiesUtil.getList(
51+
"otel.instrumentation.messaging.experimental.capture-headers", emptyList())))
52+
.build()
53+
.newRequestHandler();
54+
}
3655

3756
@Override
3857
public void beforeRequest(Request<?> request) {

instrumentation/aws-sdk/aws-sdk-2.2/javaagent/src/main/java/io/opentelemetry/javaagent/instrumentation/awssdk/v2_2/AwsSdkSingletons.java

Lines changed: 2 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -6,36 +6,15 @@
66
package io.opentelemetry.javaagent.instrumentation.awssdk.v2_2;
77

88
import io.opentelemetry.instrumentation.awssdk.v2_2.AwsSdkTelemetry;
9-
import io.opentelemetry.instrumentation.awssdk.v2_2.internal.AbstractAwsSdkTelemetryFactory;
10-
import io.opentelemetry.javaagent.bootstrap.internal.AgentInstrumentationConfig;
11-
import io.opentelemetry.javaagent.bootstrap.internal.ExperimentalConfig;
12-
import java.util.List;
9+
import io.opentelemetry.instrumentation.awssdk.v2_2.internal.AwsSdkTelemetryFactory;
1310

1411
public final class AwsSdkSingletons {
1512

16-
private static final AwsSdkTelemetry TELEMETRY = new AwsSdkTelemetryFactory().telemetry();
13+
private static final AwsSdkTelemetry TELEMETRY = AwsSdkTelemetryFactory.telemetry();
1714

1815
public static AwsSdkTelemetry telemetry() {
1916
return TELEMETRY;
2017
}
2118

22-
private static class AwsSdkTelemetryFactory extends AbstractAwsSdkTelemetryFactory {
23-
24-
@Override
25-
protected List<String> getCapturedHeaders() {
26-
return ExperimentalConfig.get().getMessagingHeaders();
27-
}
28-
29-
@Override
30-
protected boolean messagingReceiveTelemetryEnabled() {
31-
return ExperimentalConfig.get().messagingReceiveInstrumentationEnabled();
32-
}
33-
34-
@Override
35-
protected boolean getBoolean(String name, boolean defaultValue) {
36-
return AgentInstrumentationConfig.get().getBoolean(name, defaultValue);
37-
}
38-
}
39-
4019
private AwsSdkSingletons() {}
4120
}

instrumentation/aws-sdk/aws-sdk-2.2/library-autoconfigure/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/autoconfigure/AwsSdkSingletons.java

Lines changed: 2 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -5,40 +5,16 @@
55

66
package io.opentelemetry.instrumentation.awssdk.v2_2.autoconfigure;
77

8-
import static java.util.Collections.emptyList;
9-
10-
import io.opentelemetry.instrumentation.api.internal.ConfigPropertiesUtil;
118
import io.opentelemetry.instrumentation.awssdk.v2_2.AwsSdkTelemetry;
12-
import io.opentelemetry.instrumentation.awssdk.v2_2.internal.AbstractAwsSdkTelemetryFactory;
13-
import java.util.List;
9+
import io.opentelemetry.instrumentation.awssdk.v2_2.internal.AwsSdkTelemetryFactory;
1410

1511
public final class AwsSdkSingletons {
1612

17-
private static final AwsSdkTelemetry TELEMETRY = new AwsSdkTelemetryFactory().telemetry();
13+
private static final AwsSdkTelemetry TELEMETRY = AwsSdkTelemetryFactory.legacyLibraryTelemetry();
1814

1915
public static AwsSdkTelemetry telemetry() {
2016
return TELEMETRY;
2117
}
2218

23-
private static class AwsSdkTelemetryFactory extends AbstractAwsSdkTelemetryFactory {
24-
25-
@Override
26-
protected List<String> getCapturedHeaders() {
27-
return ConfigPropertiesUtil.getList(
28-
"otel.instrumentation.messaging.experimental.capture-headers", emptyList());
29-
}
30-
31-
@Override
32-
protected boolean messagingReceiveTelemetryEnabled() {
33-
return ConfigPropertiesUtil.getBoolean(
34-
"otel.instrumentation.messaging.experimental.receive-telemetry.enabled", false);
35-
}
36-
37-
@Override
38-
protected boolean getBoolean(String name, boolean defaultValue) {
39-
return ConfigPropertiesUtil.getBoolean(name, defaultValue);
40-
}
41-
}
42-
4319
private AwsSdkSingletons() {}
4420
}

instrumentation/aws-sdk/aws-sdk-2.2/library/src/main/java/io/opentelemetry/instrumentation/awssdk/v2_2/internal/AbstractAwsSdkTelemetryFactory.java

Lines changed: 0 additions & 51 deletions
This file was deleted.

0 commit comments

Comments
 (0)