Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add an SPI for customizing Config just before it's set #6010

Merged
merged 3 commits into from
May 16, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -192,4 +192,12 @@ private <T> T getTypedProperty(String name, ConfigValueParser<T> parser) {
private String getRawProperty(String name, String defaultValue) {
return getAllProperties().getOrDefault(NamingConvention.DOT.normalize(name), defaultValue);
}

/**
* Returns a new {@link ConfigBuilder} instance populated with the properties of this {@link
* Config}.
*/
public ConfigBuilder toBuilder() {
return new ConfigBuilder(getAllProperties());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,15 @@
/** A builder of a {@link Config}. */
public final class ConfigBuilder {

private final Map<String, String> allProperties = new HashMap<>();
private final Map<String, String> allProperties;

/** Constructs a new {@link ConfigBuilder}. */
ConfigBuilder() {}
ConfigBuilder() {
allProperties = new HashMap<>();
}

ConfigBuilder(Map<String, String> propertiesToCopy) {
allProperties = new HashMap<>(propertiesToCopy);
}

/** Adds a single property to the config. */
public ConfigBuilder addProperty(String name, @Nullable String value) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.javaagent.extension.config;

import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.javaagent.extension.Ordered;
import java.util.Collections;
import java.util.Map;

/**
* A service provider that allows to override default OTel javaagent configuration, and customize
* the config just before it is set as the global.
*
* <p>This is a service provider interface that requires implementations to be registered in a
* provider-configuration file stored in the {@code META-INF/services} resource directory.
*/
public interface ConfigCustomizer extends Ordered {

/**
* Returns properties with their default values. Properties returned by implementations of this
* interface will be used after the following methods fail to find a non-empty property value:
* system properties, environment variables, properties configuration file.
*
* <p>Key of the map is the propertyName (same as system property name, e.g. {@code
* otel.traces.exporter}), value is the property value.
*/
default Map<String, String> defaultProperties() {
return Collections.emptyMap();
}

/** Allows to change the javaagent configuration just before it is first used. */
default Config customize(Config config) {
return config;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -16,12 +16,19 @@
*
* <p>This is a service provider interface that requires implementations to be registered in a
* provider-configuration file stored in the {@code META-INF/services} resource directory.
*
* @deprecated Use {@link ConfigCustomizer} instead.
*/
@Deprecated
public interface ConfigPropertySource extends Ordered {

/**
* Returns all properties whose default values are overridden by this property source. Key of the
* map is the propertyName (same as system property name, e.g. {@code otel.traces.exporter}),
* value is the property value.
*
* @deprecated Use {@link ConfigCustomizer#defaultProperties()} instead.
*/
@Deprecated
Map<String, String> getProperties();
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,13 +9,14 @@
import static java.util.logging.Level.SEVERE;

import io.opentelemetry.instrumentation.api.config.Config;
import io.opentelemetry.javaagent.extension.config.ConfigPropertySource;
import io.opentelemetry.javaagent.extension.config.ConfigCustomizer;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStreamReader;
import java.nio.charset.StandardCharsets;
import java.util.List;
import java.util.Properties;
import java.util.logging.Logger;

Expand All @@ -27,7 +28,12 @@ public final class ConfigInitializer {
static final String CONFIGURATION_FILE_ENV_VAR = "OTEL_JAVAAGENT_CONFIGURATION_FILE";

public static void initialize() {
Config.internalInitializeConfig(create(loadSpiConfiguration(), loadConfigurationFile()));
List<ConfigCustomizer> customizers = loadOrdered(ConfigCustomizer.class);
Config config = create(loadSpiConfiguration(customizers), loadConfigurationFile());
for (ConfigCustomizer customizer : customizers) {
config = customizer.customize(config);
}
Config.internalInitializeConfig(config);
}

// visible for testing
Expand All @@ -41,11 +47,16 @@ static Config create(Properties spiConfiguration, Properties configurationFile)
}

/** Retrieves all default configuration overloads using SPI and initializes Config. */
private static Properties loadSpiConfiguration() {
@SuppressWarnings("deprecation") // loads the old config SPI
private static Properties loadSpiConfiguration(List<ConfigCustomizer> customizers) {
Properties propertiesFromSpi = new Properties();
for (ConfigPropertySource propertySource : loadOrdered(ConfigPropertySource.class)) {
for (io.opentelemetry.javaagent.extension.config.ConfigPropertySource propertySource :
loadOrdered(io.opentelemetry.javaagent.extension.config.ConfigPropertySource.class)) {
propertiesFromSpi.putAll(propertySource.getProperties());
}
for (ConfigCustomizer customizer : customizers) {
propertiesFromSpi.putAll(customizer.defaultProperties());
}
return propertiesFromSpi;
}

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,14 +6,15 @@
package io.opentelemetry.javaagent.testing.exporter;

import com.google.auto.service.AutoService;
import io.opentelemetry.javaagent.extension.config.ConfigPropertySource;
import io.opentelemetry.javaagent.extension.config.ConfigCustomizer;
import java.util.HashMap;
import java.util.Map;

@AutoService(ConfigPropertySource.class)
public class AgentTestingExporterPropertySource implements ConfigPropertySource {
@AutoService(ConfigCustomizer.class)
public class AgentTestingExporterPropertySource implements ConfigCustomizer {

@Override
public Map<String, String> getProperties() {
public Map<String, String> defaultProperties() {
Map<String, String> properties = new HashMap<>();
properties.put("otel.logs.exporter", "none");
properties.put("otel.metrics.exporter", "none");
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,15 +6,15 @@
package io.opentelemetry.javaagent.testing.http;

import com.google.auto.service.AutoService;
import io.opentelemetry.javaagent.extension.config.ConfigPropertySource;
import io.opentelemetry.javaagent.extension.config.ConfigCustomizer;
import java.util.HashMap;
import java.util.Map;

@AutoService(ConfigPropertySource.class)
public class CapturedHttpHeadersTestConfigSource implements ConfigPropertySource {
@AutoService(ConfigCustomizer.class)
public class CapturedHttpHeadersTestConfigSource implements ConfigCustomizer {

@Override
public Map<String, String> getProperties() {
public Map<String, String> defaultProperties() {
Map<String, String> testConfig = new HashMap<>();
testConfig.put("otel.instrumentation.http.capture-headers.client.request", "X-Test-Request");
testConfig.put("otel.instrumentation.http.capture-headers.client.response", "X-Test-Response");
Expand Down