Idea: deprecate `Config`, add agent-only `InstrumentationConfig` (#6264)

* Idea: deprecate Config, add agent-only InstrumentationConfig

* fix

* fix camel test

* fix external-annotation tests
This commit is contained in:
Mateusz Rzeszutek 2022-07-08 16:20:49 +02:00 committed by GitHub
parent c699a6c508
commit e7887ac929
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
73 changed files with 585 additions and 183 deletions

View File

@ -7,6 +7,7 @@ package io.opentelemetry.instrumentation.api.config;
import io.opentelemetry.instrumentation.api.internal.DeprecatedConfigPropertyWarning;
// TODO: move to javaagent-extension-api internal package
public final class ExperimentalConfig {
private static final ExperimentalConfig instance = new ExperimentalConfig(Config.get());

View File

@ -14,6 +14,7 @@ import java.util.logging.Logger;
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
* any time.
*/
// TODO: move to javaagent-extension-api internal package
public final class DeprecatedConfigPropertyWarning {
private static final Logger logger =

View File

@ -26,6 +26,7 @@ import javax.annotation.Nullable;
* runtime so retrieving the property once and storing its result in a static final field allows JIT
* to do its magic and remove some code branches.
*/
// TODO: deprecate
@AutoValue
public abstract class Config {
private static final Logger logger = Logger.getLogger(Config.class.getName());

View File

@ -15,7 +15,7 @@ import io.opentelemetry.api.trace.TracerBuilder;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.propagation.TextMapGetter;
import io.opentelemetry.context.propagation.TextMapSetter;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.instrumentation.api.internal.ConfigPropertiesUtil;
import io.opentelemetry.instrumentation.api.internal.EmbeddedInstrumentationProperties;
import io.opentelemetry.instrumentation.api.internal.SpanKey;
import io.opentelemetry.instrumentation.api.internal.SpanKeyProvider;
@ -36,7 +36,9 @@ import javax.annotation.Nullable;
public final class InstrumenterBuilder<REQUEST, RESPONSE> {
private static final SpanSuppressionStrategy spanSuppressionStrategy =
SpanSuppressionStrategy.fromConfig(Config.get());
SpanSuppressionStrategy.fromConfig(
ConfigPropertiesUtil.getString(
"otel.instrumentation.experimental.span-suppression-strategy"));
final OpenTelemetry openTelemetry;
final String instrumentationName;

View File

@ -8,7 +8,6 @@ package io.opentelemetry.instrumentation.api.instrumenter;
import static java.util.Collections.singleton;
import io.opentelemetry.api.trace.SpanKind;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.instrumentation.api.instrumenter.SpanSuppressor.BySpanKey;
import io.opentelemetry.instrumentation.api.instrumenter.SpanSuppressor.DelegateBySpanKind;
import io.opentelemetry.instrumentation.api.instrumenter.SpanSuppressor.Noop;
@ -18,6 +17,7 @@ import java.util.EnumMap;
import java.util.Locale;
import java.util.Map;
import java.util.Set;
import javax.annotation.Nullable;
enum SpanSuppressionStrategy {
/** Do not suppress spans at all. */
@ -74,9 +74,10 @@ enum SpanSuppressionStrategy {
abstract SpanSuppressor create(Set<SpanKey> spanKeys);
static SpanSuppressionStrategy fromConfig(Config config) {
String value =
config.getString("otel.instrumentation.experimental.span-suppression-strategy", "semconv");
static SpanSuppressionStrategy fromConfig(@Nullable String value) {
if (value == null) {
value = "semconv";
}
switch (value.toLowerCase(Locale.ROOT)) {
case "none":
return NONE;

View File

@ -0,0 +1,36 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.instrumentation.api.internal;
import java.util.Locale;
import javax.annotation.Nullable;
/**
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
* any time.
*/
public final class ConfigPropertiesUtil {
public static boolean getBoolean(String propertyName, boolean defaultValue) {
String strValue = getString(propertyName);
return strValue == null ? defaultValue : Boolean.parseBoolean(strValue);
}
@Nullable
public static String getString(String propertyName) {
String value = System.getProperty(propertyName);
if (value != null) {
return value;
}
return System.getenv(toEnvVarName(propertyName));
}
private static String toEnvVarName(String propertyName) {
return propertyName.toUpperCase(Locale.ROOT).replace('-', '_').replace('.', '_');
}
private ConfigPropertiesUtil() {}
}

View File

@ -10,7 +10,6 @@ import static java.util.logging.Level.SEVERE;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.ContextKey;
import io.opentelemetry.instrumentation.api.config.Config;
import java.util.Iterator;
import java.util.List;
import java.util.concurrent.CopyOnWriteArrayList;
@ -33,13 +32,13 @@ public final class ContextPropagationDebug {
private static final boolean FAIL_ON_CONTEXT_LEAK;
static {
Config config = Config.get();
boolean agentDebugEnabled = config.getBoolean("otel.javaagent.debug", false);
boolean agentDebugEnabled = ConfigPropertiesUtil.getBoolean("otel.javaagent.debug", false);
THREAD_PROPAGATION_DEBUGGER =
config.getBoolean(
ConfigPropertiesUtil.getBoolean(
"otel.javaagent.experimental.thread-propagation-debugger.enabled", agentDebugEnabled);
FAIL_ON_CONTEXT_LEAK = config.getBoolean("otel.javaagent.testing.fail-on-context-leak", false);
FAIL_ON_CONTEXT_LEAK =
ConfigPropertiesUtil.getBoolean("otel.javaagent.testing.fail-on-context-leak", false);
}
// context to which debug locations were added

View File

@ -6,7 +6,6 @@
package io.opentelemetry.instrumentation.api.internal;
import io.opentelemetry.api.trace.SpanKind;
import io.opentelemetry.instrumentation.api.config.Config;
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import java.util.concurrent.Executors;
@ -28,15 +27,17 @@ public final class SupportabilityMetrics {
private final ConcurrentMap<String, AtomicLong> counters = new ConcurrentHashMap<>();
private static final SupportabilityMetrics INSTANCE =
new SupportabilityMetrics(Config.get(), logger::fine).start();
new SupportabilityMetrics(
ConfigPropertiesUtil.getBoolean("otel.javaagent.debug", false), logger::fine)
.start();
public static SupportabilityMetrics instance() {
return INSTANCE;
}
// visible for testing
SupportabilityMetrics(Config config, Consumer<String> reporter) {
agentDebugEnabled = config.getBoolean("otel.javaagent.debug", false);
SupportabilityMetrics(boolean agentDebugEnabled, Consumer<String> reporter) {
this.agentDebugEnabled = agentDebugEnabled;
this.reporter = reporter;
}

View File

@ -16,7 +16,6 @@ import static org.junit.jupiter.api.Assertions.assertTrue;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.SpanKind;
import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.instrumentation.api.internal.SpanKey;
import java.util.HashSet;
import java.util.Set;
@ -36,11 +35,7 @@ class SpanSuppressionStrategyTest {
@ParameterizedTest
@ArgumentsSource(ConfigArgs.class)
void shouldParseConfig(String value, SpanSuppressionStrategy expectedStrategy) {
Config config =
Config.builder()
.addProperty("otel.instrumentation.experimental.span-suppression-strategy", value)
.build();
assertEquals(expectedStrategy, SpanSuppressionStrategy.fromConfig(config));
assertEquals(expectedStrategy, SpanSuppressionStrategy.fromConfig(value));
}
static final class ConfigArgs implements ArgumentsProvider {

View File

@ -8,7 +8,6 @@ package io.opentelemetry.instrumentation.api.internal;
import static org.assertj.core.api.Assertions.assertThat;
import io.opentelemetry.api.trace.SpanKind;
import io.opentelemetry.instrumentation.api.config.Config;
import java.util.ArrayList;
import java.util.List;
import org.junit.jupiter.api.Test;
@ -17,8 +16,7 @@ class SupportabilityMetricsTest {
@Test
void disabled() {
List<String> reports = new ArrayList<>();
SupportabilityMetrics metrics =
new SupportabilityMetrics(configWithJavaagentDebug(false), reports::add);
SupportabilityMetrics metrics = new SupportabilityMetrics(false, reports::add);
metrics.recordSuppressedSpan(SpanKind.CLIENT, "favoriteInstrumentation");
metrics.recordSuppressedSpan(SpanKind.SERVER, "favoriteInstrumentation");
@ -36,8 +34,7 @@ class SupportabilityMetricsTest {
@Test
void reportsMetrics() {
List<String> reports = new ArrayList<>();
SupportabilityMetrics metrics =
new SupportabilityMetrics(configWithJavaagentDebug(true), reports::add);
SupportabilityMetrics metrics = new SupportabilityMetrics(true, reports::add);
metrics.recordSuppressedSpan(SpanKind.CLIENT, "favoriteInstrumentation");
metrics.recordSuppressedSpan(SpanKind.SERVER, "favoriteInstrumentation");
@ -61,8 +58,7 @@ class SupportabilityMetricsTest {
@Test
void resetsCountsEachReport() {
List<String> reports = new ArrayList<>();
SupportabilityMetrics metrics =
new SupportabilityMetrics(configWithJavaagentDebug(true), reports::add);
SupportabilityMetrics metrics = new SupportabilityMetrics(true, reports::add);
metrics.recordSuppressedSpan(SpanKind.CLIENT, "favoriteInstrumentation");
metrics.incrementCounter("some counter");
@ -75,8 +71,4 @@ class SupportabilityMetricsTest {
"Suppressed Spans by 'favoriteInstrumentation' (CLIENT) : 1",
"Counter 'some counter' : 1");
}
private static Config configWithJavaagentDebug(boolean enabled) {
return Config.builder().addProperty("otel.javaagent.debug", Boolean.toString(enabled)).build();
}
}

View File

@ -5,6 +5,7 @@ plugins {
dependencies {
testImplementation(project(":instrumentation:apache-camel-2.20:javaagent"))
testImplementation(project(":instrumentation-api-semconv"))
testImplementation(project(":javaagent-extension-api"))
testImplementation("org.apache.camel:camel-core:2.20.1")
testImplementation("org.apache.camel:camel-aws:2.20.1")

View File

@ -26,7 +26,7 @@ package io.opentelemetry.javaagent.instrumentation.apachecamel.decorators;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.api.trace.SpanKind;
import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig;
import io.opentelemetry.javaagent.instrumentation.apachecamel.CamelDirection;
import io.opentelemetry.javaagent.instrumentation.apachecamel.SpanDecorator;
import java.util.Collections;
@ -41,7 +41,7 @@ import org.apache.camel.util.URISupport;
class BaseSpanDecorator implements SpanDecorator {
static final boolean CAPTURE_EXPERIMENTAL_SPAN_ATTRIBUTES =
Config.get()
InstrumentationConfig.get()
.getBoolean("otel.instrumentation.apache-camel.experimental-span-attributes", false);
static final String DEFAULT_OPERATION_NAME = "CamelOperation";

View File

@ -13,8 +13,8 @@ import com.amazonaws.handlers.RequestHandler2;
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.Scope;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.instrumentation.awssdk.v1_11.AwsSdkTelemetry;
import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig;
/**
* A {@link RequestHandler2} for use in the agent. Unlike library instrumentation, the agent will
@ -35,7 +35,7 @@ public class TracingRequestHandler extends RequestHandler2 {
public static final RequestHandler2 tracingHandler =
AwsSdkTelemetry.builder(GlobalOpenTelemetry.get())
.setCaptureExperimentalSpanAttributes(
Config.get()
InstrumentationConfig.get()
.getBoolean("otel.instrumentation.aws-sdk.experimental-span-attributes", false))
.build()
.newRequestHandler();

View File

@ -10,7 +10,7 @@ import com.amazonaws.Request;
import com.amazonaws.Response;
import com.amazonaws.handlers.RequestHandler2;
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.instrumentation.api.internal.ConfigPropertiesUtil;
import io.opentelemetry.instrumentation.awssdk.v1_11.AwsSdkTelemetry;
/**
@ -21,8 +21,8 @@ public class TracingRequestHandler extends RequestHandler2 {
private static final RequestHandler2 DELEGATE =
AwsSdkTelemetry.builder(GlobalOpenTelemetry.get())
.setCaptureExperimentalSpanAttributes(
Config.get()
.getBoolean("otel.instrumentation.aws-sdk.experimental-span-attributes", false))
ConfigPropertiesUtil.getBoolean(
"otel.instrumentation.aws-sdk.experimental-span-attributes", false))
.build()
.newRequestHandler();

View File

@ -6,7 +6,7 @@
package io.opentelemetry.instrumentation.awssdk.v2_2.autoconfigure;
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.instrumentation.api.internal.ConfigPropertiesUtil;
import io.opentelemetry.instrumentation.awssdk.v2_2.AwsSdkTelemetry;
import java.io.InputStream;
import java.nio.ByteBuffer;
@ -29,7 +29,8 @@ import software.amazon.awssdk.http.SdkHttpResponse;
public class TracingExecutionInterceptor implements ExecutionInterceptor {
private static final boolean CAPTURE_EXPERIMENTAL_SPAN_ATTRIBUTES =
Config.get().getBoolean("otel.instrumentation.aws-sdk.experimental-span-attributes", false);
ConfigPropertiesUtil.getBoolean(
"otel.instrumentation.aws-sdk.experimental-span-attributes", false);
private final ExecutionInterceptor delegate =
AwsSdkTelemetry.builder(GlobalOpenTelemetry.get())

View File

@ -6,7 +6,6 @@
package io.opentelemetry.javaagent.instrumentation.couchbase.v2_0;
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder;
import io.opentelemetry.instrumentation.api.instrumenter.PeerServiceAttributesExtractor;
@ -15,6 +14,7 @@ import io.opentelemetry.instrumentation.api.instrumenter.SpanNameExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.db.DbClientAttributesExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.db.DbClientSpanNameExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.net.NetClientAttributesExtractor;
import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig;
public final class CouchbaseSingletons {
@ -38,7 +38,7 @@ public final class CouchbaseSingletons {
(context, couchbaseRequest, startAttributes) ->
CouchbaseRequestInfo.init(context, couchbaseRequest));
if (Config.get()
if (InstrumentationConfig.get()
.getBoolean("otel.instrumentation.couchbase.experimental-span-attributes", false)) {
builder.addAttributesExtractor(new ExperimentalAttributesExtractor());
}

View File

@ -11,7 +11,7 @@ import static java.util.logging.Level.FINE;
import static net.bytebuddy.matcher.ElementMatchers.any;
import static net.bytebuddy.matcher.ElementMatchers.named;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig;
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
import java.util.Arrays;
import java.util.Collection;
@ -34,7 +34,7 @@ public abstract class AbstractExecutorInstrumentation implements TypeInstrumenta
"otel.instrumentation.executors.include-all";
private static final boolean INCLUDE_ALL =
Config.get().getBoolean(EXECUTORS_INCLUDE_ALL_PROPERTY_NAME, false);
InstrumentationConfig.get().getBoolean(EXECUTORS_INCLUDE_ALL_PROPERTY_NAME, false);
/**
* Only apply executor instrumentation to allowed executors. To apply to all executors, use
@ -100,7 +100,8 @@ public abstract class AbstractExecutorInstrumentation implements TypeInstrumenta
"scala.concurrent.impl.ExecutionContextImpl",
};
Set<String> combined = new HashSet<>(Arrays.asList(includeExecutors));
combined.addAll(Config.get().getList(EXECUTORS_INCLUDE_PROPERTY_NAME, emptyList()));
combined.addAll(
InstrumentationConfig.get().getList(EXECUTORS_INCLUDE_PROPERTY_NAME, emptyList()));
this.includeExecutors = Collections.unmodifiableSet(combined);
String[] includePrefixes = {"slick.util.AsyncExecutor$"};

View File

@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
import io.opentelemetry.instrumentation.api.config.Config
import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig
import io.opentelemetry.javaagent.instrumentation.extannotations.ExternalAnnotationInstrumentation
import spock.lang.Specification
import spock.lang.Unroll
@ -15,14 +15,8 @@ class IncludeTest extends Specification {
@Unroll
def "test configuration #value"() {
setup:
Config config
if (value) {
config = Config.builder().addProperties([
"otel.instrumentation.external-annotations.include": value
]).build()
} else {
config = Config.builder().build()
}
InstrumentationConfig config = Mock()
config.getString("otel.instrumentation.external-annotations.include") >> value
expect:
ExternalAnnotationInstrumentation.configureAdditionalTraceAnnotations(config) == expected.toSet()

View File

@ -17,9 +17,9 @@ import static net.bytebuddy.matcher.ElementMatchers.not;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.Scope;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.instrumentation.api.util.ClassAndMethod;
import io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge;
import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig;
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
import io.opentelemetry.javaagent.tooling.config.MethodsConfigurationParser;
@ -75,7 +75,8 @@ public class ExternalAnnotationInstrumentation implements TypeInstrumentation {
private final ElementMatcher.Junction<MethodDescription> excludedMethodsMatcher;
public ExternalAnnotationInstrumentation() {
Set<String> additionalTraceAnnotations = configureAdditionalTraceAnnotations(Config.get());
Set<String> additionalTraceAnnotations =
configureAdditionalTraceAnnotations(InstrumentationConfig.get());
if (additionalTraceAnnotations.isEmpty()) {
classLoaderOptimization = none();
@ -109,7 +110,7 @@ public class ExternalAnnotationInstrumentation implements TypeInstrumentation {
ExternalAnnotationInstrumentation.class.getName() + "$ExternalAnnotationAdvice");
}
private static Set<String> configureAdditionalTraceAnnotations(Config config) {
private static Set<String> configureAdditionalTraceAnnotations(InstrumentationConfig config) {
String configString = config.getString(TRACE_ANNOTATIONS_CONFIG);
if (configString == null) {
return Collections.unmodifiableSet(new HashSet<>(DEFAULT_ANNOTATIONS));
@ -142,7 +143,7 @@ public class ExternalAnnotationInstrumentation implements TypeInstrumentation {
Map<String, Set<String>> excludedMethods =
MethodsConfigurationParser.parse(
Config.get().getString(TRACE_ANNOTATED_METHODS_EXCLUDE_CONFIG));
InstrumentationConfig.get().getString(TRACE_ANNOTATED_METHODS_EXCLUDE_CONFIG));
for (Map.Entry<String, Set<String>> entry : excludedMethods.entrySet()) {
String className = entry.getKey();
ElementMatcher.Junction<ByteCodeElement> classMather =

View File

@ -8,15 +8,16 @@ package io.opentelemetry.javaagent.instrumentation.graphql;
import graphql.execution.instrumentation.ChainedInstrumentation;
import graphql.execution.instrumentation.Instrumentation;
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.instrumentation.graphql.GraphQLTelemetry;
import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig;
import java.util.ArrayList;
import java.util.List;
public final class GraphqlSingletons {
private static final boolean QUERY_SANITIZATION_ENABLED =
Config.get().getBoolean("otel.instrumentation.graphql.query-sanitizer.enabled", true);
InstrumentationConfig.get()
.getBoolean("otel.instrumentation.graphql.query-sanitizer.enabled", true);
private static final GraphQLTelemetry TELEMETRY =
GraphQLTelemetry.builder(GlobalOpenTelemetry.get())

View File

@ -9,9 +9,9 @@ import io.grpc.ClientInterceptor;
import io.grpc.Context;
import io.grpc.ServerInterceptor;
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.instrumentation.grpc.v1_6.GrpcTelemetry;
import io.opentelemetry.instrumentation.grpc.v1_6.internal.ContextStorageBridge;
import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig;
// Holds singleton references.
public final class GrpcSingletons {
@ -24,7 +24,8 @@ public final class GrpcSingletons {
static {
boolean experimentalSpanAttributes =
Config.get().getBoolean("otel.instrumentation.grpc.experimental-span-attributes", false);
InstrumentationConfig.get()
.getBoolean("otel.instrumentation.grpc.experimental-span-attributes", false);
GrpcTelemetry telemetry =
GrpcTelemetry.builder(GlobalOpenTelemetry.get())

View File

@ -6,15 +6,15 @@
package io.opentelemetry.javaagent.instrumentation.guava;
import io.opentelemetry.instrumentation.api.annotation.support.async.AsyncOperationEndStrategies;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.instrumentation.guava.GuavaAsyncOperationEndStrategy;
import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig;
public final class InstrumentationHelper {
static {
asyncOperationEndStrategy =
GuavaAsyncOperationEndStrategy.builder()
.setCaptureExperimentalSpanAttributes(
Config.get()
InstrumentationConfig.get()
.getBoolean("otel.instrumentation.guava.experimental-span-attributes", false))
.build();

View File

@ -6,13 +6,14 @@
package io.opentelemetry.javaagent.instrumentation.hibernate;
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder;
import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig;
public final class HibernateInstrumenterFactory {
static final boolean CAPTURE_EXPERIMENTAL_SPAN_ATTRIBUTES =
Config.get().getBoolean("otel.instrumentation.hibernate.experimental-span-attributes", false);
InstrumentationConfig.get()
.getBoolean("otel.instrumentation.hibernate.experimental-span-attributes", false);
public static Instrumenter<HibernateOperation, Void> createInstrumenter(
String instrumentationName) {

View File

@ -6,9 +6,9 @@
package io.opentelemetry.javaagent.instrumentation.hystrix;
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder;
import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig;
public final class HystrixSingletons {
@ -21,7 +21,7 @@ public final class HystrixSingletons {
Instrumenter.builder(
GlobalOpenTelemetry.get(), INSTRUMENTATION_NAME, HystrixRequest::spanName);
if (Config.get()
if (InstrumentationConfig.get()
.getBoolean("otel.instrumentation.hystrix.experimental-span-attributes", false)) {
builder.addAttributesExtractor(new ExperimentalAttributesExtractor());
}

View File

@ -11,8 +11,8 @@ import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.appender.internal.LogBuilder;
import io.opentelemetry.instrumentation.api.appender.internal.Severity;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.javaagent.bootstrap.AgentLogEmitterProvider;
import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig;
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
import java.io.PrintWriter;
import java.io.StringWriter;
@ -26,7 +26,7 @@ public final class JavaUtilLoggingHelper {
private static final Formatter FORMATTER = new AccessibleFormatter();
private static final boolean captureExperimentalAttributes =
Config.get()
InstrumentationConfig.get()
.getBoolean("otel.instrumentation.java-util-logging.experimental-log-attributes", false);
public static void capture(Logger logger, LogRecord logRecord) {

View File

@ -5,12 +5,13 @@
package io.opentelemetry.javaagent.instrumentation.jaxrs;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig;
public final class JaxrsConfig {
public static final boolean CAPTURE_EXPERIMENTAL_SPAN_ATTRIBUTES =
Config.get().getBoolean("otel.instrumentation.jaxrs.experimental-span-attributes", false);
InstrumentationConfig.get()
.getBoolean("otel.instrumentation.jaxrs.experimental-span-attributes", false);
private JaxrsConfig() {}
}

View File

@ -13,9 +13,9 @@ import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.appender.internal.LogBuilder;
import io.opentelemetry.instrumentation.api.appender.internal.Severity;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.instrumentation.api.internal.cache.Cache;
import io.opentelemetry.javaagent.bootstrap.AgentLogEmitterProvider;
import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig;
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
import java.io.PrintWriter;
import java.io.StringWriter;
@ -35,7 +35,7 @@ public final class LoggingEventMapper {
private final List<String> captureMdcAttributes;
private static final boolean captureExperimentalAttributes =
Config.get()
InstrumentationConfig.get()
.getBoolean("otel.instrumentation.jboss-logmanager.experimental-log-attributes", false);
// cached as an optimization
@ -43,7 +43,7 @@ public final class LoggingEventMapper {
private LoggingEventMapper() {
this.captureMdcAttributes =
Config.get()
InstrumentationConfig.get()
.getList(
"otel.instrumentation.jboss-logmanager.experimental.capture-mdc-attributes",
emptyList());

View File

@ -10,10 +10,10 @@ import static java.util.logging.Level.WARNING;
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.instrumentation.api.instrumenter.SpanKindExtractor;
import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig;
import java.net.URI;
import java.net.URISyntaxException;
import java.util.logging.Logger;
@ -24,7 +24,8 @@ import javax.servlet.jsp.HttpJspPage;
public class HttpJspPageInstrumentationSingletons {
private static final boolean CAPTURE_EXPERIMENTAL_SPAN_ATTRIBUTES =
Config.get().getBoolean("otel.instrumentation.jsp.experimental-span-attributes", false);
InstrumentationConfig.get()
.getBoolean("otel.instrumentation.jsp.experimental-span-attributes", false);
private static final Instrumenter<HttpServletRequest, Void> INSTRUMENTER;

View File

@ -8,17 +8,18 @@ package io.opentelemetry.javaagent.instrumentation.jsp;
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.instrumentation.api.instrumenter.SpanKindExtractor;
import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig;
import javax.annotation.Nullable;
import org.apache.jasper.JspCompilationContext;
import org.apache.jasper.compiler.Compiler;
public class JspCompilationContextInstrumentationSingletons {
private static final boolean CAPTURE_EXPERIMENTAL_SPAN_ATTRIBUTES =
Config.get().getBoolean("otel.instrumentation.jsp.experimental-span-attributes", false);
InstrumentationConfig.get()
.getBoolean("otel.instrumentation.jsp.experimental-span-attributes", false);
private static final Instrumenter<JspCompilationContext, Void> INSTRUMENTER;

View File

@ -61,7 +61,7 @@ public class KafkaProducerInstrumentation implements TypeInstrumentation {
context = producerInstrumenter().start(parentContext, record);
scope = context.makeCurrent();
if (KafkaPropagation.shouldPropagate(apiVersions)) {
if (KafkaSingletons.isPropagationEnabled() && KafkaPropagation.shouldPropagate(apiVersions)) {
record = KafkaPropagation.propagateContext(context, record);
}

View File

@ -8,6 +8,7 @@ package io.opentelemetry.javaagent.instrumentation.kafkaclients;
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.instrumentation.kafka.internal.KafkaInstrumenterFactory;
import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.ConsumerRecords;
import org.apache.kafka.clients.producer.ProducerRecord;
@ -15,18 +16,30 @@ import org.apache.kafka.clients.producer.ProducerRecord;
public final class KafkaSingletons {
private static final String INSTRUMENTATION_NAME = "io.opentelemetry.kafka-clients-0.11";
private static final boolean PROPAGATION_ENABLED =
InstrumentationConfig.get()
.getBoolean("otel.instrumentation.kafka.client-propagation.enabled", true);
private static final Instrumenter<ProducerRecord<?, ?>, Void> PRODUCER_INSTRUMENTER;
private static final Instrumenter<ConsumerRecords<?, ?>, Void> CONSUMER_RECEIVE_INSTRUMENTER;
private static final Instrumenter<ConsumerRecord<?, ?>, Void> CONSUMER_PROCESS_INSTRUMENTER;
static {
KafkaInstrumenterFactory instrumenterFactory =
new KafkaInstrumenterFactory(GlobalOpenTelemetry.get(), INSTRUMENTATION_NAME);
new KafkaInstrumenterFactory(GlobalOpenTelemetry.get(), INSTRUMENTATION_NAME)
.setCaptureExperimentalSpanAttributes(
InstrumentationConfig.get()
.getBoolean("otel.instrumentation.kafka.experimental-span-attributes", false))
.setPropagationEnabled(PROPAGATION_ENABLED);
PRODUCER_INSTRUMENTER = instrumenterFactory.createProducerInstrumenter();
CONSUMER_RECEIVE_INSTRUMENTER = instrumenterFactory.createConsumerReceiveInstrumenter();
CONSUMER_PROCESS_INSTRUMENTER = instrumenterFactory.createConsumerProcessInstrumenter();
}
public static boolean isPropagationEnabled() {
return PROPAGATION_ENABLED;
}
public static Instrumenter<ProducerRecord<?, ?>, Void> producerInstrumenter() {
return PRODUCER_INSTRUMENTER;
}

View File

@ -19,8 +19,5 @@ dependencies {
tasks {
withType<Test>().configureEach {
usesService(gradle.sharedServices.registrations["testcontainersBuildService"].service)
// TODO run tests both with and without experimental span attributes
jvmArgs("-Dotel.instrumentation.kafka.experimental-span-attributes=true")
}
}

View File

@ -23,6 +23,8 @@ public final class KafkaTelemetryBuilder {
new ArrayList<>();
private final List<AttributesExtractor<ConsumerRecord<?, ?>, Void>> consumerAttributesExtractors =
new ArrayList<>();
private boolean captureExperimentalSpanAttributes = false;
private boolean propagationEnabled = true;
KafkaTelemetryBuilder(OpenTelemetry openTelemetry) {
this.openTelemetry = Objects.requireNonNull(openTelemetry);
@ -40,9 +42,31 @@ public final class KafkaTelemetryBuilder {
return this;
}
/**
* Sets whether experimental attributes should be set to spans. These attributes may be changed or
* removed in the future, so only enable this if you know you do not require attributes filled by
* this instrumentation to be stable across versions.
*/
public KafkaTelemetryBuilder setCaptureExperimentalSpanAttributes(
boolean captureExperimentalSpanAttributes) {
this.captureExperimentalSpanAttributes = captureExperimentalSpanAttributes;
return this;
}
/**
* Sets whether the producer context should be propagated from the producer span to the consumer
* span. Enabled by default.
*/
public KafkaTelemetryBuilder setPropagationEnabled(boolean propagationEnabled) {
this.propagationEnabled = propagationEnabled;
return this;
}
public KafkaTelemetry build() {
KafkaInstrumenterFactory instrumenterFactory =
new KafkaInstrumenterFactory(openTelemetry, INSTRUMENTATION_NAME);
new KafkaInstrumenterFactory(openTelemetry, INSTRUMENTATION_NAME)
.setCaptureExperimentalSpanAttributes(captureExperimentalSpanAttributes)
.setPropagationEnabled(propagationEnabled);
return new KafkaTelemetry(
openTelemetry,

View File

@ -34,5 +34,7 @@ public class TracingConsumerInterceptor<K, V> implements ConsumerInterceptor<K,
public void close() {}
@Override
public void configure(Map<String, ?> configs) {}
public void configure(Map<String, ?> configs) {
// TODO: support experimental attributes config
}
}

View File

@ -33,5 +33,7 @@ public class TracingProducerInterceptor<K, V> implements ProducerInterceptor<K,
public void close() {}
@Override
public void configure(Map<String, ?> map) {}
public void configure(Map<String, ?> map) {
// TODO: support experimental attributes config
}
}

View File

@ -87,8 +87,6 @@ class InterceptorsTest extends KafkaClientBaseTest implements LibraryTestTrait {
"$SemanticAttributes.MESSAGING_OPERATION" "receive"
"$SemanticAttributes.MESSAGING_MESSAGE_PAYLOAD_SIZE_BYTES" Long
"$SemanticAttributes.MESSAGING_KAFKA_PARTITION" { it >= 0 }
"kafka.offset" Long
"kafka.record.queue_time_ms" { it >= 0 }
}
}
}

View File

@ -20,7 +20,10 @@ class WrappersTest extends KafkaClientBaseTest implements LibraryTestTrait {
@Unroll
def "test wrappers"() throws Exception {
KafkaTelemetry telemetry = KafkaTelemetry.create(getOpenTelemetry())
KafkaTelemetry telemetry = KafkaTelemetry.builder(getOpenTelemetry())
// TODO run tests both with and without experimental span attributes
.setCaptureExperimentalSpanAttributes(true)
.build()
when:
String greeting = "Hello Kafka!"

View File

@ -10,7 +10,6 @@ import static io.opentelemetry.api.common.AttributeKey.longKey;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
import javax.annotation.Nullable;
import org.apache.kafka.clients.consumer.ConsumerRecord;
@ -27,13 +26,6 @@ public final class KafkaConsumerExperimentalAttributesExtractor
private static final AttributeKey<Long> KAFKA_RECORD_QUEUE_TIME_MS =
longKey("kafka.record.queue_time_ms");
private static final boolean ENABLED =
Config.get().getBoolean("otel.instrumentation.kafka.experimental-span-attributes", false);
public static boolean isEnabled() {
return ENABLED;
}
@Override
public void onStart(
AttributesBuilder attributes, Context parentContext, ConsumerRecord<?, ?> consumerRecord) {

View File

@ -30,6 +30,8 @@ public final class KafkaInstrumenterFactory {
private final OpenTelemetry openTelemetry;
private final String instrumentationName;
private ErrorCauseExtractor errorCauseExtractor = ErrorCauseExtractor.jdk();
private boolean captureExperimentalSpanAttributes = false;
private boolean propagationEnabled = true;
public KafkaInstrumenterFactory(OpenTelemetry openTelemetry, String instrumentationName) {
this.openTelemetry = openTelemetry;
@ -41,6 +43,17 @@ public final class KafkaInstrumenterFactory {
return this;
}
public KafkaInstrumenterFactory setCaptureExperimentalSpanAttributes(
boolean captureExperimentalSpanAttributes) {
this.captureExperimentalSpanAttributes = captureExperimentalSpanAttributes;
return this;
}
public KafkaInstrumenterFactory setPropagationEnabled(boolean propagationEnabled) {
this.propagationEnabled = propagationEnabled;
return this;
}
public Instrumenter<ProducerRecord<?, ?>, Void> createProducerInstrumenter() {
return createProducerInstrumenter(Collections.emptyList());
}
@ -95,11 +108,11 @@ public final class KafkaInstrumenterFactory {
.addAttributesExtractor(new KafkaConsumerAdditionalAttributesExtractor())
.addAttributesExtractors(extractors)
.setErrorCauseExtractor(errorCauseExtractor);
if (KafkaConsumerExperimentalAttributesExtractor.isEnabled()) {
if (captureExperimentalSpanAttributes) {
builder.addAttributesExtractor(new KafkaConsumerExperimentalAttributesExtractor());
}
if (!KafkaPropagation.isPropagationEnabled()) {
if (!propagationEnabled) {
return builder.newInstrumenter(SpanKindExtractor.alwaysConsumer());
} else if (ExperimentalConfig.get().messagingReceiveInstrumentationEnabled()) {
builder.addSpanLinksExtractor(

View File

@ -7,7 +7,6 @@ package io.opentelemetry.instrumentation.kafka.internal;
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.config.Config;
import org.apache.kafka.clients.ApiVersions;
import org.apache.kafka.clients.producer.ProducerRecord;
import org.apache.kafka.common.record.RecordBatch;
@ -20,13 +19,6 @@ public final class KafkaPropagation {
private static final KafkaHeadersSetter SETTER = KafkaHeadersSetter.INSTANCE;
private static final boolean CLIENT_PROPAGATION_ENABLED =
Config.get().getBoolean("otel.instrumentation.kafka.client-propagation.enabled", true);
public static boolean isPropagationEnabled() {
return CLIENT_PROPAGATION_ENABLED;
}
// Do not inject headers for batch versions below 2
// This is how similar check is being done in Kafka client itself:
// https://github.com/apache/kafka/blob/05fcfde8f69b0349216553f711fdfc3f0259c601/clients/src/main/java/org/apache/kafka/common/record/MemoryRecordsBuilder.java#L411-L412
@ -35,8 +27,7 @@ public final class KafkaPropagation {
// headers attempt to read messages that were produced by clients > 0.11 and the magic
// value of the broker(s) is >= 2
public static boolean shouldPropagate(ApiVersions apiVersions) {
return apiVersions.maxUsableProduceMagic() >= RecordBatch.MAGIC_VALUE_V2
&& isPropagationEnabled();
return apiVersions.maxUsableProduceMagic() >= RecordBatch.MAGIC_VALUE_V2;
}
public static <K, V> ProducerRecord<K, V> propagateContext(

View File

@ -8,6 +8,7 @@ package io.opentelemetry.javaagent.instrumentation.kafkastreams;
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.instrumentation.kafka.internal.KafkaInstrumenterFactory;
import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig;
import org.apache.kafka.clients.consumer.ConsumerRecord;
public final class KafkaStreamsSingletons {
@ -16,6 +17,12 @@ public final class KafkaStreamsSingletons {
private static final Instrumenter<ConsumerRecord<?, ?>, Void> INSTRUMENTER =
new KafkaInstrumenterFactory(GlobalOpenTelemetry.get(), INSTRUMENTATION_NAME)
.setCaptureExperimentalSpanAttributes(
InstrumentationConfig.get()
.getBoolean("otel.instrumentation.kafka.experimental-span-attributes", false))
.setPropagationEnabled(
InstrumentationConfig.get()
.getBoolean("otel.instrumentation.kafka.client-propagation.enabled", true))
.createConsumerProcessInstrumenter();
public static Instrumenter<ConsumerRecord<?, ?>, Void> instrumenter() {

View File

@ -11,20 +11,20 @@ import io.kubernetes.client.openapi.ApiResponse;
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.propagation.ContextPropagators;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder;
import io.opentelemetry.instrumentation.api.instrumenter.SpanNameExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpClientAttributesExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.http.HttpSpanStatusExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.net.NetClientAttributesExtractor;
import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig;
import okhttp3.Request;
public class KubernetesClientSingletons {
private static final Instrumenter<Request, ApiResponse<?>> INSTRUMENTER;
private static final boolean CAPTURE_EXPERIMENTAL_SPAN_ATTRIBUTES =
Config.get()
InstrumentationConfig.get()
.getBoolean("otel.instrumentation.kubernetes-client.experimental-span-attributes", false);
private static final ContextPropagators CONTEXT_PROPAGATORS;

View File

@ -16,7 +16,7 @@ import com.lambdaworks.redis.protocol.ProtocolKeyword;
import com.lambdaworks.redis.protocol.RedisCommand;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig;
import java.util.EnumSet;
import java.util.Set;
import java.util.concurrent.CancellationException;
@ -24,7 +24,8 @@ import java.util.concurrent.CancellationException;
public final class InstrumentationPoints {
private static final boolean CAPTURE_EXPERIMENTAL_SPAN_ATTRIBUTES =
Config.get().getBoolean("otel.instrumentation.lettuce.experimental-span-attributes", false);
InstrumentationConfig.get()
.getBoolean("otel.instrumentation.lettuce.experimental-span-attributes", false);
private static final Set<CommandType> NON_INSTRUMENTING_COMMANDS = EnumSet.of(SHUTDOWN, DEBUG);

View File

@ -10,7 +10,7 @@ import static io.opentelemetry.javaagent.instrumentation.lettuce.v5_0.LettuceSin
import io.lettuce.core.protocol.RedisCommand;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig;
import java.util.concurrent.CancellationException;
import java.util.function.BiFunction;
@ -27,7 +27,8 @@ public class EndCommandAsyncBiFunction<T, U extends Throwable, R>
implements BiFunction<T, Throwable, R> {
private static final boolean CAPTURE_EXPERIMENTAL_SPAN_ATTRIBUTES =
Config.get().getBoolean("otel.instrumentation.lettuce.experimental-span-attributes", false);
InstrumentationConfig.get()
.getBoolean("otel.instrumentation.lettuce.experimental-span-attributes", false);
private final Context context;
private final RedisCommand<?, ?, ?> command;

View File

@ -10,7 +10,7 @@ import static io.opentelemetry.javaagent.instrumentation.lettuce.v5_0.LettuceSin
import io.lettuce.core.RedisURI;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig;
import java.util.concurrent.CancellationException;
import java.util.function.BiFunction;
@ -27,7 +27,8 @@ public class EndConnectAsyncBiFunction<T, U extends Throwable, R>
implements BiFunction<T, Throwable, R> {
private static final boolean CAPTURE_EXPERIMENTAL_SPAN_ATTRIBUTES =
Config.get().getBoolean("otel.instrumentation.lettuce.experimental-span-attributes", false);
InstrumentationConfig.get()
.getBoolean("otel.instrumentation.lettuce.experimental-span-attributes", false);
private final Context context;
private final RedisURI redisUri;

View File

@ -10,7 +10,7 @@ import static io.opentelemetry.javaagent.instrumentation.lettuce.v5_0.LettuceSin
import io.lettuce.core.protocol.RedisCommand;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig;
import java.util.function.Consumer;
import java.util.logging.Logger;
import org.reactivestreams.Subscription;
@ -21,7 +21,8 @@ import reactor.core.publisher.SignalType;
public class LettuceFluxTerminationRunnable implements Consumer<Signal<?>>, Runnable {
private static final boolean CAPTURE_EXPERIMENTAL_SPAN_ATTRIBUTES =
Config.get().getBoolean("otel.instrumentation.lettuce.experimental-span-attributes", false);
InstrumentationConfig.get()
.getBoolean("otel.instrumentation.lettuce.experimental-span-attributes", false);
private Context context;
private int numResults;

View File

@ -13,9 +13,9 @@ import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.appender.internal.LogBuilder;
import io.opentelemetry.instrumentation.api.appender.internal.Severity;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.instrumentation.api.internal.cache.Cache;
import io.opentelemetry.javaagent.bootstrap.AgentLogEmitterProvider;
import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig;
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
import java.io.PrintWriter;
import java.io.StringWriter;
@ -37,7 +37,7 @@ public final class LogEventMapper {
private static final int TRACE_INT = 5000;
private static final boolean captureExperimentalAttributes =
Config.get()
InstrumentationConfig.get()
.getBoolean("otel.instrumentation.log4j-appender.experimental-log-attributes", false);
private final Map<String, AttributeKey<String>> captureMdcAttributes;
@ -47,7 +47,7 @@ public final class LogEventMapper {
private LogEventMapper() {
List<String> captureMdcAttributes =
Config.get()
InstrumentationConfig.get()
.getList(
"otel.instrumentation.log4j-appender.experimental.capture-mdc-attributes",
emptyList());

View File

@ -9,7 +9,7 @@ import static java.util.Collections.emptyList;
import static java.util.Collections.singletonList;
import com.google.auto.service.AutoService;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig;
import io.opentelemetry.javaagent.extension.instrumentation.InstrumentationModule;
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
import io.opentelemetry.javaagent.tooling.config.MethodsConfigurationParser;
@ -18,15 +18,6 @@ import java.util.Map;
import java.util.Set;
import java.util.stream.Collectors;
/**
* TraceConfig Instrumentation does not extend Default.
*
* <p>Instead it directly implements Instrumenter#instrument() and adds one default Instrumenter for
* every configured class+method-list.
*
* <p>If this becomes a more common use case the building logic should be abstracted out into a
* super class.
*/
@AutoService(InstrumentationModule.class)
public class MethodInstrumentationModule extends InstrumentationModule {
@ -38,7 +29,8 @@ public class MethodInstrumentationModule extends InstrumentationModule {
super("methods");
Map<String, Set<String>> classMethodsToTrace =
MethodsConfigurationParser.parse(Config.get().getString(TRACE_METHODS_CONFIG));
MethodsConfigurationParser.parse(
InstrumentationConfig.get().getString(TRACE_METHODS_CONFIG));
typeInstrumentations =
classMethodsToTrace.entrySet().stream()

View File

@ -7,7 +7,7 @@ package io.opentelemetry.javaagent.instrumentation.micrometer.v1_5;
import io.micrometer.core.instrument.MeterRegistry;
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig;
import io.opentelemetry.micrometer1shim.OpenTelemetryMeterRegistry;
public final class MicrometerSingletons {
@ -15,7 +15,7 @@ public final class MicrometerSingletons {
private static final MeterRegistry METER_REGISTRY;
static {
Config config = Config.get();
InstrumentationConfig config = InstrumentationConfig.get();
METER_REGISTRY =
OpenTelemetryMeterRegistry.builder(GlobalOpenTelemetry.get())
.setPrometheusMode(

View File

@ -19,9 +19,9 @@ import static net.bytebuddy.matcher.ElementMatchers.whereAny;
import io.opentelemetry.context.Context;
import io.opentelemetry.context.Scope;
import io.opentelemetry.instrumentation.api.annotation.support.async.AsyncOperationEndSupport;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge;
import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig;
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
import io.opentelemetry.javaagent.tooling.config.MethodsConfigurationParser;
@ -93,7 +93,7 @@ public class WithSpanInstrumentation implements TypeInstrumentation {
Map<String, Set<String>> excludedMethods =
MethodsConfigurationParser.parse(
Config.get().getString(TRACE_ANNOTATED_METHODS_EXCLUDE_CONFIG));
InstrumentationConfig.get().getString(TRACE_ANNOTATED_METHODS_EXCLUDE_CONFIG));
for (Map.Entry<String, Set<String>> entry : excludedMethods.entrySet()) {
String className = entry.getKey();
ElementMatcher.Junction<ByteCodeElement> classMather =

View File

@ -6,9 +6,9 @@
package io.opentelemetry.javaagent.instrumentation.oshi;
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.instrumentation.oshi.ProcessMetrics;
import io.opentelemetry.instrumentation.oshi.SystemMetrics;
import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig;
import java.util.concurrent.atomic.AtomicBoolean;
public final class MetricsRegistration {
@ -20,7 +20,7 @@ public final class MetricsRegistration {
SystemMetrics.registerObservers(GlobalOpenTelemetry.get());
// ProcessMetrics don't follow the spec
if (Config.get()
if (InstrumentationConfig.get()
.getBoolean("otel.instrumentation.oshi.experimental-metrics.enabled", false)) {
ProcessMetrics.registerObservers(GlobalOpenTelemetry.get());
}

View File

@ -11,7 +11,7 @@ import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig;
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
import java.util.Map;
@ -19,7 +19,8 @@ public class RabbitInstrumenterHelper {
static final AttributeKey<String> RABBITMQ_COMMAND = AttributeKey.stringKey("rabbitmq.command");
private static final boolean CAPTURE_EXPERIMENTAL_SPAN_ATTRIBUTES =
Config.get().getBoolean("otel.instrumentation.rabbitmq.experimental-span-attributes", false);
InstrumentationConfig.get()
.getBoolean("otel.instrumentation.rabbitmq.experimental-span-attributes", false);
private static final RabbitInstrumenterHelper INSTRUMENTER_HELPER =
new RabbitInstrumenterHelper();

View File

@ -10,19 +10,20 @@ import static io.opentelemetry.api.trace.SpanKind.PRODUCER;
import com.rabbitmq.client.GetResponse;
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.instrumentation.api.instrumenter.SpanKindExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.messaging.MessageOperation;
import io.opentelemetry.instrumentation.api.instrumenter.messaging.MessagingAttributesExtractor;
import io.opentelemetry.instrumentation.api.instrumenter.net.NetClientAttributesExtractor;
import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig;
import java.util.ArrayList;
import java.util.List;
public class RabbitSingletons {
private static final boolean CAPTURE_EXPERIMENTAL_SPAN_ATTRIBUTES =
Config.get().getBoolean("otel.instrumentation.rabbitmq.experimental-span-attributes", false);
InstrumentationConfig.get()
.getBoolean("otel.instrumentation.rabbitmq.experimental-span-attributes", false);
private static final String instrumentationName = "io.opentelemetry.rabbitmq-2.7";
private static final Instrumenter<ChannelAndMethod, Void> channelInstrumenter;
private static final Instrumenter<ReceiveRequest, GetResponse> receiveInstrumenter;

View File

@ -9,8 +9,8 @@ import static net.bytebuddy.matcher.ElementMatchers.isTypeInitializer;
import static net.bytebuddy.matcher.ElementMatchers.named;
import static net.bytebuddy.matcher.ElementMatchers.namedOneOf;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.instrumentation.reactor.ContextPropagationOperator;
import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig;
import io.opentelemetry.javaagent.extension.instrumentation.TypeInstrumentation;
import io.opentelemetry.javaagent.extension.instrumentation.TypeTransformer;
import net.bytebuddy.asm.Advice;
@ -41,7 +41,7 @@ public class HooksInstrumentation implements TypeInstrumentation {
public static void postStaticInitializer() {
ContextPropagationOperator.builder()
.setCaptureExperimentalSpanAttributes(
Config.get()
InstrumentationConfig.get()
.getBoolean("otel.instrumentation.reactor.experimental-span-attributes", false))
.build()
.registerOnEachOperator();

View File

@ -6,8 +6,8 @@
package io.opentelemetry.javaagent.instrumentation.rocketmq;
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.instrumentation.rocketmq.RocketMqTelemetry;
import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig;
import org.apache.rocketmq.client.hook.ConsumeMessageHook;
import org.apache.rocketmq.client.hook.SendMessageHook;
@ -15,9 +15,10 @@ public final class RocketMqClientHooks {
private static final RocketMqTelemetry TELEMETRY =
RocketMqTelemetry.builder(GlobalOpenTelemetry.get())
.setPropagationEnabled(
Config.get().getBoolean("otel.instrumentation.rocketmq-client.propagation", true))
InstrumentationConfig.get()
.getBoolean("otel.instrumentation.rocketmq-client.propagation", true))
.setCaptureExperimentalSpanAttributes(
Config.get()
InstrumentationConfig.get()
.getBoolean(
"otel.instrumentation.rocketmq-client.experimental-span-attributes", false))
.build();

View File

@ -5,7 +5,7 @@
package io.opentelemetry.instrumentation.rocketmq
import io.opentelemetry.instrumentation.api.config.Config
import io.opentelemetry.instrumentation.test.LibraryTestTrait
import org.apache.rocketmq.client.consumer.DefaultMQPushConsumer
import org.apache.rocketmq.client.producer.DefaultMQProducer
@ -15,20 +15,14 @@ class RocketMqClientTest extends AbstractRocketMqClientTest implements LibraryTe
@Override
void configureMQProducer(DefaultMQProducer producer) {
producer.getDefaultMQProducerImpl().registerSendMessageHook(RocketMqTelemetry.builder(openTelemetry)
.setCaptureExperimentalSpanAttributes(
Config.get()
.getBoolean(
"otel.instrumentation.rocketmq-client.experimental-span-attributes", true))
.setCaptureExperimentalSpanAttributes(true)
.build().newTracingSendMessageHook())
}
@Override
void configureMQPushConsumer(DefaultMQPushConsumer consumer) {
consumer.getDefaultMQPushConsumerImpl().registerConsumeMessageHook(RocketMqTelemetry.builder(openTelemetry)
.setCaptureExperimentalSpanAttributes(
Config.get()
.getBoolean(
"otel.instrumentation.rocketmq-client.experimental-span-attributes", true))
.setCaptureExperimentalSpanAttributes(true)
.build().newTracingConsumeMessageHook())
}
}

View File

@ -5,8 +5,8 @@
package io.opentelemetry.javaagent.instrumentation.rxjava.v2_0;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.instrumentation.rxjava.v2_0.TracingAssembly;
import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig;
import java.util.concurrent.atomic.AtomicBoolean;
public final class TracingAssemblyActivation {
@ -23,7 +23,7 @@ public final class TracingAssemblyActivation {
if (activated.get(clz).compareAndSet(false, true)) {
TracingAssembly.builder()
.setCaptureExperimentalSpanAttributes(
Config.get()
InstrumentationConfig.get()
.getBoolean("otel.instrumentation.rxjava.experimental-span-attributes", false))
.build()
.enable();

View File

@ -5,8 +5,8 @@
package io.opentelemetry.javaagent.instrumentation.rxjava.v3_0;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.instrumentation.rxjava.v3_0.TracingAssembly;
import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig;
import java.util.concurrent.atomic.AtomicBoolean;
public final class TracingAssemblyActivation {
@ -23,7 +23,7 @@ public final class TracingAssemblyActivation {
if (activated.get(clz).compareAndSet(false, true)) {
TracingAssembly.builder()
.setCaptureExperimentalSpanAttributes(
Config.get()
InstrumentationConfig.get()
.getBoolean("otel.instrumentation.rxjava.experimental-span-attributes", false))
.build()
.enable();

View File

@ -5,8 +5,8 @@
package io.opentelemetry.javaagent.instrumentation.rxjava.v3_1_1;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.instrumentation.rxjava.v3_1_1.TracingAssembly;
import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig;
import java.util.concurrent.atomic.AtomicBoolean;
public final class TracingAssemblyActivation {
@ -23,7 +23,7 @@ public final class TracingAssemblyActivation {
if (activated.get(clz).compareAndSet(false, true)) {
TracingAssembly.builder()
.setCaptureExperimentalSpanAttributes(
Config.get()
InstrumentationConfig.get()
.getBoolean("otel.instrumentation.rxjava.experimental-span-attributes", false))
.build()
.enable();

View File

@ -10,8 +10,8 @@ import static io.opentelemetry.api.common.AttributeKey.longKey;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig;
import io.opentelemetry.semconv.trace.attributes.SemanticAttributes;
import java.security.Principal;
import javax.annotation.Nullable;
@ -20,7 +20,8 @@ public class ServletAdditionalAttributesExtractor<REQUEST, RESPONSE>
implements AttributesExtractor<
ServletRequestContext<REQUEST>, ServletResponseContext<RESPONSE>> {
private static final boolean CAPTURE_EXPERIMENTAL_SPAN_ATTRIBUTES =
Config.get().getBoolean("otel.instrumentation.servlet.experimental-span-attributes", false);
InstrumentationConfig.get()
.getBoolean("otel.instrumentation.servlet.experimental-span-attributes", false);
private static final AttributeKey<Long> SERVLET_TIMEOUT = longKey("servlet.timeout");
private final ServletAccessor<REQUEST, RESPONSE> accessor;

View File

@ -10,8 +10,8 @@ import static java.util.Collections.emptyList;
import io.opentelemetry.api.common.AttributeKey;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig;
import java.util.List;
import java.util.Locale;
import java.util.concurrent.ConcurrentHashMap;
@ -23,7 +23,7 @@ public class ServletRequestParametersExtractor<REQUEST, RESPONSE>
implements AttributesExtractor<
ServletRequestContext<REQUEST>, ServletResponseContext<RESPONSE>> {
private static final List<String> CAPTURE_REQUEST_PARAMETERS =
Config.get()
InstrumentationConfig.get()
.getList(
"otel.instrumentation.servlet.experimental.capture-request-parameters", emptyList());

View File

@ -5,7 +5,7 @@
package io.opentelemetry.javaagent.instrumentation.spring.batch;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig;
public final class SpringBatchInstrumentationConfig {
@ -13,9 +13,10 @@ public final class SpringBatchInstrumentationConfig {
// the item level instrumentation is very chatty so it's disabled by default
private static final boolean ITEM_TRACING_ENABLED =
Config.get().getBoolean("otel.instrumentation.spring-batch.item.enabled", false);
InstrumentationConfig.get()
.getBoolean("otel.instrumentation.spring-batch.item.enabled", false);
private static final boolean CREATE_ROOT_SPAN_FOR_CHUNK =
Config.get()
InstrumentationConfig.get()
.getBoolean("otel.instrumentation.spring-batch.experimental.chunk.new-trace", false);
public static String instrumentationName() {

View File

@ -8,15 +8,15 @@ package io.opentelemetry.javaagent.instrumentation.spring.integration;
import static java.util.Collections.singletonList;
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.instrumentation.spring.integration.SpringIntegrationTelemetry;
import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig;
import java.util.List;
import org.springframework.messaging.support.ChannelInterceptor;
public final class SpringIntegrationSingletons {
private static final List<String> PATTERNS =
Config.get()
InstrumentationConfig.get()
.getList(
"otel.instrumentation.spring-integration.global-channel-interceptor-patterns",
singletonList("*"));

View File

@ -8,6 +8,7 @@ package io.opentelemetry.javaagent.instrumentation.spring.kafka;
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.instrumentation.kafka.internal.KafkaInstrumenterFactory;
import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.ConsumerRecords;
@ -21,6 +22,12 @@ public final class SpringKafkaSingletons {
static {
KafkaInstrumenterFactory factory =
new KafkaInstrumenterFactory(GlobalOpenTelemetry.get(), INSTRUMENTATION_NAME)
.setCaptureExperimentalSpanAttributes(
InstrumentationConfig.get()
.getBoolean("otel.instrumentation.kafka.experimental-span-attributes", false))
.setPropagationEnabled(
InstrumentationConfig.get()
.getBoolean("otel.instrumentation.kafka.client-propagation.enabled", true))
.setErrorCauseExtractor(SpringKafkaErrorCauseExtractor.INSTANCE);
BATCH_PROCESS_INSTRUMENTER = factory.createBatchProcessInstrumenter();
PROCESS_INSTRUMENTER = factory.createConsumerProcessInstrumenter();

View File

@ -5,12 +5,12 @@
package io.opentelemetry.javaagent.instrumentation.spring.webflux;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig;
public class SpringWebfluxConfig {
private static final boolean CAPTURE_EXPERIMENTAL_SPAN_ATTRIBUTES =
Config.get()
InstrumentationConfig.get()
.getBoolean("otel.instrumentation.spring-webflux.experimental-span-attributes", false);
public static boolean captureExperimentalSpanAttributes() {

View File

@ -7,9 +7,9 @@ package io.opentelemetry.javaagent.instrumentation.springwebmvc;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.instrumentation.api.instrumenter.AttributesExtractor;
import io.opentelemetry.instrumentation.api.util.ClassNames;
import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig;
import javax.annotation.Nullable;
import org.springframework.web.servlet.ModelAndView;
import org.springframework.web.servlet.View;
@ -17,7 +17,7 @@ import org.springframework.web.servlet.View;
public class ModelAndViewAttributesExtractor implements AttributesExtractor<ModelAndView, Void> {
private static final boolean CAPTURE_EXPERIMENTAL_SPAN_ATTRIBUTES =
Config.get()
InstrumentationConfig.get()
.getBoolean("otel.instrumentation.spring-webmvc.experimental-span-attributes", false);
@Override

View File

@ -9,14 +9,14 @@ import static io.opentelemetry.javaagent.instrumentation.spymemcached.Spymemcach
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.context.Context;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig;
import java.util.concurrent.CancellationException;
import java.util.concurrent.ExecutionException;
public abstract class CompletionListener<T> {
private static final boolean CAPTURE_EXPERIMENTAL_SPAN_ATTRIBUTES =
Config.get()
InstrumentationConfig.get()
.getBoolean("otel.instrumentation.spymemcached.experimental-span-attributes", false);
private static final String DB_COMMAND_CANCELLED = "spymemcached.command.cancelled";

View File

@ -8,15 +8,16 @@ package io.opentelemetry.javaagent.instrumentation.twilio;
import static io.opentelemetry.instrumentation.api.instrumenter.SpanKindExtractor.alwaysClient;
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.instrumentation.api.instrumenter.InstrumenterBuilder;
import io.opentelemetry.instrumentation.api.util.SpanNames;
import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig;
public class TwilioSingletons {
private static final boolean CAPTURE_EXPERIMENTAL_SPAN_ATTRIBUTES =
Config.get().getBoolean("otel.instrumentation.twilio.experimental-span-attributes", false);
InstrumentationConfig.get()
.getBoolean("otel.instrumentation.twilio.experimental-span-attributes", false);
private static final Instrumenter<String, Object> INSTRUMENTER;

View File

@ -8,6 +8,7 @@ package io.opentelemetry.javaagent.instrumentation.vertx.kafka.v3_6;
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.instrumentation.api.instrumenter.Instrumenter;
import io.opentelemetry.instrumentation.kafka.internal.KafkaInstrumenterFactory;
import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig;
import org.apache.kafka.clients.consumer.ConsumerRecord;
import org.apache.kafka.clients.consumer.ConsumerRecords;
@ -20,7 +21,13 @@ public final class VertxKafkaSingletons {
static {
KafkaInstrumenterFactory factory =
new KafkaInstrumenterFactory(GlobalOpenTelemetry.get(), INSTRUMENTATION_NAME);
new KafkaInstrumenterFactory(GlobalOpenTelemetry.get(), INSTRUMENTATION_NAME)
.setCaptureExperimentalSpanAttributes(
InstrumentationConfig.get()
.getBoolean("otel.instrumentation.kafka.experimental-span-attributes", false))
.setPropagationEnabled(
InstrumentationConfig.get()
.getBoolean("otel.instrumentation.kafka.client-propagation.enabled", true));
BATCH_PROCESS_INSTRUMENTER = factory.createBatchProcessInstrumenter();
PROCESS_INSTRUMENTER = factory.createConsumerProcessInstrumenter();
}

View File

@ -0,0 +1,60 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.bootstrap.internal;
import java.time.Duration;
import java.util.List;
import java.util.Map;
import javax.annotation.Nullable;
final class EmptyInstrumentationConfig extends InstrumentationConfig {
@Nullable
@Override
public String getString(String name) {
return null;
}
@Override
public String getString(String name, String defaultValue) {
return defaultValue;
}
@Override
public boolean getBoolean(String name, boolean defaultValue) {
return defaultValue;
}
@Override
public int getInt(String name, int defaultValue) {
return defaultValue;
}
@Override
public long getLong(String name, long defaultValue) {
return defaultValue;
}
@Override
public double getDouble(String name, double defaultValue) {
return defaultValue;
}
@Override
public Duration getDuration(String name, Duration defaultValue) {
return defaultValue;
}
@Override
public List<String> getList(String name, List<String> defaultValue) {
return defaultValue;
}
@Override
public Map<String, String> getMap(String name, Map<String, String> defaultValue) {
return defaultValue;
}
}

View File

@ -0,0 +1,132 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.bootstrap.internal;
import static java.util.Objects.requireNonNull;
import io.opentelemetry.instrumentation.api.config.Config;
import java.time.Duration;
import java.util.List;
import java.util.Map;
import java.util.logging.Logger;
import javax.annotation.Nullable;
/**
* Represents the global instrumentation configuration consisting of system properties, environment
* variables, contents of the agent configuration file and properties defined by the {@code
* ConfigPropertySource} SPI implementations.
*
* <p>In case any {@code get*()} method variant gets called for the same property more than once
* (e.g. each time an advice class executes) it is suggested to cache the result instead of
* repeatedly calling {@link Config}. Instrumentation configuration does not change during the
* runtime so retrieving the property once and storing its result in a static final field allows JIT
* to do its magic and remove some code branches.
*
* <p>This class is internal and is hence not for public use. Its APIs are unstable and can change
* at any time.
*/
public abstract class InstrumentationConfig {
private static final Logger logger = Logger.getLogger(InstrumentationConfig.class.getName());
private static final InstrumentationConfig DEFAULT = new EmptyInstrumentationConfig();
// lazy initialized, so that javaagent can set it
private static volatile InstrumentationConfig instance = DEFAULT;
/**
* Sets the instrumentation configuration singleton. This method is only supposed to be called
* once, during the agent initialization, just before {@link InstrumentationConfig#get()} is used
* for the first time.
*
* <p>This method is internal and is hence not for public use. Its API is unstable and can change
* at any time.
*/
public static void internalInitializeConfig(InstrumentationConfig config) {
if (instance != DEFAULT) {
logger.warning("InstrumentationConfig#instance was already set earlier");
return;
}
instance = requireNonNull(config);
}
/** Returns the global instrumentation configuration. */
public static InstrumentationConfig get() {
return instance;
}
/**
* Returns a string-valued configuration property or {@code null} if a property with name {@code
* name} has not been configured.
*/
@Nullable
public abstract String getString(String name);
/**
* Returns a string-valued configuration property or {@code defaultValue} if a property with name
* {@code name} has not been configured.
*/
public abstract String getString(String name, String defaultValue);
/**
* Returns a boolean-valued configuration property or {@code defaultValue} if a property with name
* {@code name} has not been configured.
*/
public abstract boolean getBoolean(String name, boolean defaultValue);
/**
* Returns an integer-valued configuration property or {@code defaultValue} if a property with
* name {@code name} has not been configured or when parsing has failed.
*/
public abstract int getInt(String name, int defaultValue);
/**
* Returns a long-valued configuration property or {@code defaultValue} if a property with name
* {@code name} has not been configured or when parsing has failed.
*/
public abstract long getLong(String name, long defaultValue);
/**
* Returns a double-valued configuration property or {@code defaultValue} if a property with name
* {@code name} has not been configured or when parsing has failed.
*/
public abstract double getDouble(String name, double defaultValue);
/**
* Returns a duration-valued configuration property or {@code defaultValue} if a property with
* name {@code name} has not been configured or when parsing has failed.
*
* <p>Durations can be of the form "{number}{unit}", where unit is one of:
*
* <ul>
* <li>ms
* <li>s
* <li>m
* <li>h
* <li>d
* </ul>
*
* <p>If no unit is specified, milliseconds is the assumed duration unit.
*
* <p>Examples: 10s, 20ms, 5000
*/
public abstract Duration getDuration(String name, Duration defaultValue);
/**
* Returns a list-valued configuration property or {@code defaultValue} if a property with name
* {@code name} has not been configured. The format of the original value must be comma-separated,
* e.g. {@code one,two,three}. The returned list is unmodifiable.
*/
public abstract List<String> getList(String name, List<String> defaultValue);
/**
* Returns a map-valued configuration property or {@code defaultValue} if a property with name
* {@code name} has not been configured or when parsing has failed. The format of the original
* value must be comma-separated for each key, with an '=' separating the key and value, e.g.
* {@code key=value,anotherKey=anotherValue}. The returned map is unmodifiable.
*/
public abstract Map<String, String> getMap(String name, Map<String, String> defaultValue);
}

View File

@ -26,18 +26,21 @@ import io.opentelemetry.javaagent.bootstrap.BootstrapPackagePrefixesHolder;
import io.opentelemetry.javaagent.bootstrap.ClassFileTransformerHolder;
import io.opentelemetry.javaagent.bootstrap.DefineClassHelper;
import io.opentelemetry.javaagent.bootstrap.InstrumentedTaskClasses;
import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig;
import io.opentelemetry.javaagent.extension.AgentListener;
import io.opentelemetry.javaagent.extension.ignore.IgnoredTypesConfigurer;
import io.opentelemetry.javaagent.tooling.asyncannotationsupport.WeakRefAsyncOperationEndStrategies;
import io.opentelemetry.javaagent.tooling.bootstrap.BootstrapPackagesBuilderImpl;
import io.opentelemetry.javaagent.tooling.bootstrap.BootstrapPackagesConfigurer;
import io.opentelemetry.javaagent.tooling.config.AgentConfig;
import io.opentelemetry.javaagent.tooling.config.ConfigPropertiesBridge;
import io.opentelemetry.javaagent.tooling.ignore.IgnoredClassLoadersMatcher;
import io.opentelemetry.javaagent.tooling.ignore.IgnoredTypesBuilderImpl;
import io.opentelemetry.javaagent.tooling.ignore.IgnoredTypesMatcher;
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.spi.ConfigProperties;
import java.lang.instrument.Instrumentation;
import java.util.ArrayList;
import java.util.Collections;
@ -116,6 +119,10 @@ public class AgentInstaller {
}
if (autoConfiguredSdk != null) {
InstrumentationConfig.internalInitializeConfig(
new ConfigPropertiesBridge(autoConfiguredSdk.getConfig()));
copyNecessaryConfigToSystemProperties(autoConfiguredSdk.getConfig());
for (BeforeAgentListener agentListener : loadOrdered(BeforeAgentListener.class)) {
agentListener.beforeAgent(autoConfiguredSdk);
}
@ -177,6 +184,13 @@ public class AgentInstaller {
}
}
private static void copyNecessaryConfigToSystemProperties(ConfigProperties config) {
String value = config.getString("otel.instrumentation.experimental.span-suppression-strategy");
if (value != null) {
System.setProperty("otel.instrumentation.experimental.span-suppression-strategy", value);
}
}
private static void setupUnsafe(Instrumentation inst) {
try {
UnsafeInitializer.initialize(inst, AgentInstaller.class.getClassLoader());

View File

@ -0,0 +1,111 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.javaagent.tooling.config;
import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException;
import java.time.Duration;
import java.util.List;
import java.util.Locale;
import java.util.Map;
import javax.annotation.Nullable;
public final class ConfigPropertiesBridge extends InstrumentationConfig {
private final ConfigProperties configProperties;
public ConfigPropertiesBridge(ConfigProperties configProperties) {
this.configProperties = configProperties;
}
@Nullable
@Override
public String getString(String name) {
try {
return configProperties.getString(normalize(name));
} catch (ConfigurationException ignored) {
return null;
}
}
@Override
public String getString(String name, String defaultValue) {
try {
return configProperties.getString(normalize(name), defaultValue);
} catch (ConfigurationException ignored) {
return defaultValue;
}
}
@Override
public boolean getBoolean(String name, boolean defaultValue) {
try {
return configProperties.getBoolean(normalize(name), defaultValue);
} catch (ConfigurationException ignored) {
return defaultValue;
}
}
@Override
public int getInt(String name, int defaultValue) {
try {
return configProperties.getInt(normalize(name), defaultValue);
} catch (ConfigurationException ignored) {
return defaultValue;
}
}
@Override
public long getLong(String name, long defaultValue) {
try {
return configProperties.getLong(normalize(name), defaultValue);
} catch (ConfigurationException ignored) {
return defaultValue;
}
}
@Override
public double getDouble(String name, double defaultValue) {
try {
return configProperties.getDouble(normalize(name), defaultValue);
} catch (ConfigurationException ignored) {
return defaultValue;
}
}
@Override
public Duration getDuration(String name, Duration defaultValue) {
try {
return configProperties.getDuration(normalize(name), defaultValue);
} catch (ConfigurationException ignored) {
return defaultValue;
}
}
@Override
public List<String> getList(String name, List<String> defaultValue) {
try {
return configProperties.getList(normalize(name), defaultValue);
} catch (ConfigurationException ignored) {
return defaultValue;
}
}
@Override
public Map<String, String> getMap(String name, Map<String, String> defaultValue) {
try {
return configProperties.getMap(normalize(name), defaultValue);
} catch (ConfigurationException ignored) {
return defaultValue;
}
}
// TODO: remove after https://github.com/open-telemetry/opentelemetry-java/issues/4562 is fixed
private static String normalize(String key) {
return key.toLowerCase(Locale.ROOT).replace('-', '.');
}
}