Skip to content

Commit

Permalink
use ConfigPropertiesBridge for spring starter
Browse files Browse the repository at this point in the history
  • Loading branch information
zeitlinger committed Jun 21, 2024
1 parent ef893e6 commit d40519b
Show file tree
Hide file tree
Showing 26 changed files with 530 additions and 240 deletions.
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

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

import java.util.function.Consumer;
import java.util.function.Supplier;

/**
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
* any time.
*/
public final class CommonConfigSetter {
private CommonConfigSetter() {}

public static <T> void set(Supplier<T> supplier, Consumer<T> consumer) {
T t = supplier.get();
if (t != null) {
consumer.accept(t);
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

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

import static java.util.Collections.emptyMap;

import io.opentelemetry.instrumentation.api.incubator.log.LoggingContextConstants;
import io.opentelemetry.instrumentation.api.incubator.semconv.net.PeerServiceResolver;
import io.opentelemetry.instrumentation.api.internal.HttpConstants;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;

/**
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
* any time.
*/
public final class CoreCommonConfig {

private final PeerServiceResolver peerServiceResolver;
private final List<String> clientRequestHeaders;
private final List<String> clientResponseHeaders;
private final List<String> serverRequestHeaders;
private final List<String> serverResponseHeaders;
private final Set<String> knownHttpRequestMethods;
private final EnduserConfig enduserConfig;
private final boolean statementSanitizationEnabled;
private final boolean emitExperimentalHttpClientTelemetry;
private final boolean emitExperimentalHttpServerTelemetry;
private final String loggingTraceIdKey;
private final String loggingSpanIdKey;
private final String loggingTraceFlagsKey;

public CoreCommonConfig(CoreInstrumentationConfig config) {
peerServiceResolver =
PeerServiceResolver.create(
config.getMap("otel.instrumentation.common.peer-service-mapping", emptyMap()));

clientRequestHeaders =
config.getList("otel.instrumentation.http.client.capture-request-headers");
clientResponseHeaders =
config.getList("otel.instrumentation.http.client.capture-response-headers");
serverRequestHeaders =
config.getList("otel.instrumentation.http.server.capture-request-headers");
serverResponseHeaders =
config.getList("otel.instrumentation.http.server.capture-response-headers");
knownHttpRequestMethods =
new HashSet<>(
config.getList(
"otel.instrumentation.http.known-methods",
new ArrayList<>(HttpConstants.KNOWN_METHODS)));
statementSanitizationEnabled =
config.getBoolean("otel.instrumentation.common.db-statement-sanitizer.enabled", true);
emitExperimentalHttpClientTelemetry =
config.getBoolean("otel.instrumentation.http.client.emit-experimental-telemetry", false);
emitExperimentalHttpServerTelemetry =
config.getBoolean("otel.instrumentation.http.server.emit-experimental-telemetry", false);
enduserConfig = new EnduserConfig(config);
loggingTraceIdKey =
config.getString(
"otel.instrumentation.common.logging.trace-id", LoggingContextConstants.TRACE_ID);
loggingSpanIdKey =
config.getString(
"otel.instrumentation.common.logging.span-id", LoggingContextConstants.SPAN_ID);
loggingTraceFlagsKey =
config.getString(
"otel.instrumentation.common.logging.trace-flags", LoggingContextConstants.TRACE_FLAGS);
}

public PeerServiceResolver getPeerServiceResolver() {
return peerServiceResolver;
}

public List<String> getClientRequestHeaders() {
return clientRequestHeaders;
}

public List<String> getClientResponseHeaders() {
return clientResponseHeaders;
}

public List<String> getServerRequestHeaders() {
return serverRequestHeaders;
}

public List<String> getServerResponseHeaders() {
return serverResponseHeaders;
}

public Set<String> getKnownHttpRequestMethods() {
return knownHttpRequestMethods;
}

public EnduserConfig getEnduserConfig() {
return enduserConfig;
}

public boolean isStatementSanitizationEnabled() {
return statementSanitizationEnabled;
}

public boolean shouldEmitExperimentalHttpClientTelemetry() {
return emitExperimentalHttpClientTelemetry;
}

public boolean shouldEmitExperimentalHttpServerTelemetry() {
return emitExperimentalHttpServerTelemetry;
}

public String getTraceIdKey() {
return loggingTraceIdKey;
}

public String getSpanIdKey() {
return loggingSpanIdKey;
}

public String getTraceFlagsKey() {
return loggingTraceFlagsKey;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,110 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

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

import static java.util.Collections.emptyList;

import java.time.Duration;
import java.util.List;
import java.util.Map;
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 CoreInstrumentationConfig}. 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 interface CoreInstrumentationConfig {

/**
* Returns a string-valued configuration property or {@code null} if a property with name {@code
* name} has not been configured.
*/
@Nullable
String getString(String name);

/**
* Returns a string-valued configuration property or {@code defaultValue} if a property with name
* {@code name} has not been configured.
*/
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.
*/
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.
*/
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.
*/
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.
*/
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
*/
Duration getDuration(String name, Duration defaultValue);

/**
* This is the same as calling {@code getList(String, List)} with the defaultValue equal to the
* emptyList()/
*/
default List<String> getList(String name) {
return getList(name, emptyList());
}

/**
* 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.
*/
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.
*/
Map<String, String> getMap(String name, Map<String, String> defaultValue);
}
Original file line number Diff line number Diff line change
Expand Up @@ -3,7 +3,7 @@
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.javaagent.bootstrap.internal;
package io.opentelemetry.instrumentation.api.incubator.internal.config;

import java.util.Objects;

Expand Down Expand Up @@ -39,7 +39,7 @@ public class EnduserConfig {
private final boolean roleEnabled;
private final boolean scopeEnabled;

EnduserConfig(InstrumentationConfig instrumentationConfig) {
EnduserConfig(CoreInstrumentationConfig instrumentationConfig) {
Objects.requireNonNull(instrumentationConfig, "instrumentationConfig must not be null");

/*
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,40 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.instrumentation.api.incubator.internal.instrumenter;

import com.google.errorprone.annotations.CanIgnoreReturnValue;
import io.opentelemetry.instrumentation.api.incubator.builder.AbstractHttpClientTelemetryBuilder;
import io.opentelemetry.instrumentation.api.incubator.internal.config.CoreCommonConfig;
import java.util.function.Consumer;
import java.util.function.Supplier;

/**
* This class is internal and is hence not for public use. Its APIs are unstable and can change at
* any time.
*/
public class HttpClientInstrumenterBuilder {
private HttpClientInstrumenterBuilder() {}

@CanIgnoreReturnValue
public static <T extends AbstractHttpClientTelemetryBuilder<?, ?, ?>> T configure(
CoreCommonConfig config, T builder) {
set(config::getKnownHttpRequestMethods, builder::setKnownMethods);
set(config::getClientRequestHeaders, builder::setCapturedRequestHeaders);
set(config::getClientResponseHeaders, builder::setCapturedResponseHeaders);
set(config::getPeerServiceResolver, builder::setPeerServiceResolver);
set(
config::shouldEmitExperimentalHttpClientTelemetry,
builder::setEmitExperimentalHttpClientMetrics);
return builder;
}

private static <T> void set(Supplier<T> supplier, Consumer<T> consumer) {
T t = supplier.get();
if (t != null) {
consumer.accept(t);
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@ plugins {

dependencies {
testImplementation(project(":instrumentation-api"))
testImplementation(project(":instrumentation-api-incubator"))
testImplementation(project(":javaagent-extension-api"))
testImplementation(project(":javaagent-tooling"))
testImplementation(project(":instrumentation:external-annotations:javaagent"))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,7 @@
import static org.assertj.core.api.Assertions.assertThat;
import static org.mockito.Mockito.when;

import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig;
import io.opentelemetry.instrumentation.api.incubator.internal.config.CoreInstrumentationConfig;
import java.util.Arrays;
import java.util.Collections;
import java.util.HashSet;
Expand All @@ -25,7 +25,7 @@
@ExtendWith(MockitoExtension.class)
class IncludeTest {

@Mock InstrumentationConfig config;
@Mock CoreInstrumentationConfig config;

@ParameterizedTest
@MethodSource("provideArguments")
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@

import io.opentelemetry.context.Context;
import io.opentelemetry.context.Scope;
import io.opentelemetry.instrumentation.api.incubator.internal.config.CoreInstrumentationConfig;
import io.opentelemetry.instrumentation.api.incubator.semconv.util.ClassAndMethod;
import io.opentelemetry.javaagent.bootstrap.Java8BytecodeBridge;
import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig;
Expand Down Expand Up @@ -113,7 +114,7 @@ public void transform(TypeTransformer transformer) {
}

// visible for testing
static Set<String> configureAdditionalTraceAnnotations(InstrumentationConfig config) {
static Set<String> configureAdditionalTraceAnnotations(CoreInstrumentationConfig config) {
String configString = config.getString(TRACE_ANNOTATIONS_CONFIG);
if (configString == null) {
return Collections.unmodifiableSet(new HashSet<>(DEFAULT_ANNOTATIONS));
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -9,6 +9,7 @@

import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.logs.LogRecordBuilder;
import io.opentelemetry.instrumentation.api.incubator.internal.config.CoreInstrumentationConfig;
import io.opentelemetry.instrumentation.log4j.appender.v2_17.internal.ContextDataAccessor;
import io.opentelemetry.instrumentation.log4j.appender.v2_17.internal.LogEventMapper;
import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig;
Expand All @@ -30,7 +31,7 @@ public final class Log4jHelper {
private static final boolean captureExperimentalAttributes;

static {
InstrumentationConfig config = InstrumentationConfig.get();
CoreInstrumentationConfig config = InstrumentationConfig.get();

captureExperimentalAttributes =
config.getBoolean("otel.instrumentation.log4j-appender.experimental-log-attributes", false);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import static java.util.Collections.emptyList;

import io.opentelemetry.instrumentation.api.incubator.internal.config.CoreInstrumentationConfig;
import io.opentelemetry.instrumentation.logback.appender.v1_0.internal.LoggingEventMapper;
import io.opentelemetry.javaagent.bootstrap.internal.InstrumentationConfig;
import java.util.List;
Expand All @@ -16,7 +17,7 @@ public final class LogbackSingletons {
private static final LoggingEventMapper mapper;

static {
InstrumentationConfig config = InstrumentationConfig.get();
CoreInstrumentationConfig config = InstrumentationConfig.get();

boolean captureExperimentalAttributes =
config.getBoolean(
Expand Down
Loading

0 comments on commit d40519b

Please sign in to comment.