Skip to content
Draft
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 @@ -20,6 +20,7 @@
import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException;
import io.opentelemetry.sdk.autoconfigure.spi.internal.AutoConfigureListener;
import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties;
import io.opentelemetry.sdk.builder.internal.OpenTelemetrySdkBuilderUtil;
import io.opentelemetry.sdk.logs.LogRecordProcessor;
import io.opentelemetry.sdk.logs.SdkLoggerProvider;
import io.opentelemetry.sdk.logs.SdkLoggerProviderBuilder;
Expand Down Expand Up @@ -476,6 +477,10 @@ private AutoConfiguredOpenTelemetrySdk buildImpl() {

try {
OpenTelemetrySdkBuilder sdkBuilder = OpenTelemetrySdk.builder();
if (INCUBATOR_AVAILABLE) {
OpenTelemetrySdkBuilderUtil.setSdkConfigProvider(
sdkBuilder, IncubatingUtil.toSdkConfigProvider(config));
}

// The propagation system is part of the API and functions in the absence of an SDK.
ContextPropagators propagators =
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import io.opentelemetry.api.incubator.config.DeclarativeConfigException;
import io.opentelemetry.common.ComponentLoader;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException;
import io.opentelemetry.sdk.resources.Resource;
import java.io.FileInputStream;
Expand Down Expand Up @@ -139,6 +140,25 @@ static AutoConfiguredOpenTelemetrySdk createWithFactory(String name, Factory fac
}
}

public static Object toSdkConfigProvider(ConfigProperties configProperties) {
try {
Class<?> sdkConfigProviderClass =
Class.forName(
"io.opentelemetry.sdk.extension.incubator.fileconfig.ConfigPropertiesBackedDeclarativeConfigProperties");
Class<?> configPropertiesClass =
Class.forName("io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties");

Method createMethod =
sdkConfigProviderClass.getMethod("createInstrumentationConfig", configPropertiesClass);
return createMethod.invoke(null, configProperties);
} catch (ClassNotFoundException
| NoSuchMethodException
| IllegalAccessException
| InvocationTargetException e) {
throw new IllegalStateException("Error creating SdkConfigProvider from ConfigProperties", e);
}
}

private static ConfigurationException toConfigurationException(
DeclarativeConfigException exception) {
String message = requireNonNull(exception.getMessage());
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
import io.opentelemetry.exporter.logging.LoggingSpanExporter;
import io.opentelemetry.internal.testing.CleanupExtension;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.extension.incubator.ExtendedOpenTelemetrySdk;
import io.opentelemetry.sdk.builder.internal.OpenTelemetrySdkBuilderUtil;
import io.opentelemetry.sdk.extension.incubator.fileconfig.SdkConfigProvider;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel;
import io.opentelemetry.sdk.resources.Resource;
Expand All @@ -28,17 +28,20 @@ class DeclarativeConfigurationSpiTest {

@Test
void configFromSpi() {
ExtendedOpenTelemetrySdk expectedSdk =
ExtendedOpenTelemetrySdk.create(
OpenTelemetrySdk.builder()
.setTracerProvider(
SdkTracerProvider.builder()
.setResource(
Resource.getDefault().toBuilder().put("service.name", "test").build())
.addSpanProcessor(SimpleSpanProcessor.create(LoggingSpanExporter.create()))
.build())
.build(),
SdkConfigProvider.create(new OpenTelemetryConfigurationModel()));
OpenTelemetrySdk expectedSdk =
OpenTelemetrySdkBuilderUtil.setSdkConfigProvider(
OpenTelemetrySdk.builder()
.setTracerProvider(
SdkTracerProvider.builder()
.setResource(
Resource.getDefault().toBuilder()
.put("service.name", "test")
.build())
.addSpanProcessor(
SimpleSpanProcessor.create(LoggingSpanExporter.create()))
.build()),
SdkConfigProvider.create(new OpenTelemetryConfigurationModel()))
.build();
cleanup.addCloseable(expectedSdk);
AutoConfiguredOpenTelemetrySdkBuilder builder = spy(AutoConfiguredOpenTelemetrySdk.builder());
Thread thread = new Thread();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ void globalOpenTelemetry_AutoConfigureEnabled() {
private static OpenTelemetry unobfuscate(OpenTelemetry openTelemetry) {
try {
Field delegateField =
Class.forName("io.opentelemetry.api.GlobalOpenTelemetry$ObfuscatedOpenTelemetry")
Class.forName("io.opentelemetry.api.incubator.internal.ObfuscatedExtendedOpenTelemetry")
.getDeclaredField("delegate");
delegateField.setAccessible(true);
Object delegate = delegateField.get(openTelemetry);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException;
import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties;
import io.opentelemetry.sdk.builder.internal.OpenTelemetrySdkBuilderUtil;
import io.opentelemetry.sdk.extension.incubator.ExtendedOpenTelemetrySdk;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.trace.SdkTracerProvider;
Expand Down Expand Up @@ -122,16 +123,18 @@ void configFile_Valid() {

OpenTelemetrySdk openTelemetrySdk = autoConfiguredOpenTelemetrySdk.getOpenTelemetrySdk();
Resource resource = Resource.getDefault().toBuilder().put("service.name", "test").build();
ExtendedOpenTelemetrySdk expectedSdk =
ExtendedOpenTelemetrySdk.create(
OpenTelemetrySdk.builder()
.setTracerProvider(
SdkTracerProvider.builder()
.setResource(resource)
.addSpanProcessor(SimpleSpanProcessor.create(LoggingSpanExporter.create()))
.build())
.build(),
((ExtendedOpenTelemetrySdk) openTelemetrySdk).getSdkConfigProvider());
OpenTelemetrySdk expectedSdk =
OpenTelemetrySdkBuilderUtil.setSdkConfigProvider(
OpenTelemetrySdk.builder()
.setTracerProvider(
SdkTracerProvider.builder()
.setResource(resource)
.addSpanProcessor(
SimpleSpanProcessor.create(LoggingSpanExporter.create()))
.build()),
((ExtendedOpenTelemetrySdk) openTelemetrySdk).getSdkConfigProvider())
.build();

cleanup.addCloseable(expectedSdk);
assertThat(openTelemetrySdk.toString()).hasToString(expectedSdk.toString());
// AutoConfiguredOpenTelemetrySdk#getResource() is set to a dummy value when configuring from
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,154 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.sdk.extension.incubator.fileconfig;

import static java.util.Collections.emptySet;

import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties;
import io.opentelemetry.common.ComponentLoader;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Set;
import javax.annotation.Nullable;

/**
* Implementation of {@link DeclarativeConfigProperties} backed by {@link ConfigProperties}.
*
* <p>It tracks the navigation path and only resolves to system properties at the leaf node when a
* value is actually requested.
*/
public final class ConfigPropertiesBackedDeclarativeConfigProperties
implements DeclarativeConfigProperties {

private final ConfigProperties configProperties;
private final List<String> path;

public static DeclarativeConfigProperties createInstrumentationConfig(
ConfigProperties configProperties) {
return new ConfigPropertiesBackedDeclarativeConfigProperties(
configProperties, Collections.emptyList());
}

private ConfigPropertiesBackedDeclarativeConfigProperties(
ConfigProperties configProperties, List<String> path) {
this.configProperties = configProperties;
this.path = path;
}

@Nullable
@Override
public String getString(String name) {
return configProperties.getString(resolvePropertyKey(name));
}

@Nullable
@Override
public Boolean getBoolean(String name) {
return configProperties.getBoolean(resolvePropertyKey(name));
}

@Nullable
@Override
public Integer getInt(String name) {
return configProperties.getInt(resolvePropertyKey(name));
}

@Nullable
@Override
public Long getLong(String name) {
return configProperties.getLong(resolvePropertyKey(name));
}

@Nullable
@Override
public Double getDouble(String name) {
return configProperties.getDouble(resolvePropertyKey(name));
}

/**
* Important: this method should return null if there is no structured child with the given name,
* but unfortunately that is not implementable on top of ConfigProperties.
*
* <p>This will be misleading if anyone is comparing the return value to null.
*/
@Override
public DeclarativeConfigProperties getStructured(String name) {
List<String> newPath = new ArrayList<>(path);
newPath.add(name);
return new ConfigPropertiesBackedDeclarativeConfigProperties(configProperties, newPath);
}

@Nullable
@Override
@SuppressWarnings("unchecked") // Safe because T is known to be String via scalarType check
public <T> List<T> getScalarList(String name, Class<T> scalarType) {
if (scalarType != String.class) {
return null;
}
List<String> list = configProperties.getList(resolvePropertyKey(name));
if (list.isEmpty()) {
return null;
}
return (List<T>) list;
}

@Nullable
@Override
public List<DeclarativeConfigProperties> getStructuredList(String name) {
return null;
}

@Override
public Set<String> getPropertyKeys() {
// this is not supported when using system properties based configuration
return emptySet();
}

@Override
public ComponentLoader getComponentLoader() {
return configProperties.getComponentLoader();
}

private String resolvePropertyKey(String name) {
String fullPath = pathWithName(name);

if (!fullPath.startsWith("java.")) {
return "";
}

// Remove "java." prefix and translate the remaining path
String[] segments = fullPath.substring(5).split("\\.");
StringBuilder translatedPath = new StringBuilder();

for (int i = 0; i < segments.length; i++) {
if (i > 0) {
translatedPath.append(".");
}
translatedPath.append(translateName(segments[i]));
}

return "otel.instrumentation." + translatedPath;
}

private String pathWithName(String name) {
if (path.isEmpty()) {
return name;
}
return String.join(".", path) + "." + name;
}

private static String translateName(String name) {
if (name.endsWith("/development")) {
name = name.substring(0, name.length() - "/development".length());
if (!name.contains("experimental")) {
name = "experimental." + name;
}
}
return name.replace('_', '-');
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
import io.opentelemetry.sdk.OpenTelemetrySdkBuilder;
import io.opentelemetry.sdk.extension.incubator.ExtendedOpenTelemetrySdk;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel;
import io.opentelemetry.sdk.builder.internal.OpenTelemetrySdkBuilderUtil;
import io.opentelemetry.sdk.metrics.SdkMeterProvider;
import io.opentelemetry.sdk.resources.Resource;
import java.util.Objects;
Expand All @@ -34,7 +35,9 @@ public ExtendedOpenTelemetrySdk create(
OpenTelemetryConfigurationModel model, DeclarativeConfigContext context) {
SdkConfigProvider sdkConfigProvider =
SdkConfigProvider.create(model, context.getSpiHelper().getComponentLoader());
OpenTelemetrySdkBuilder builder = OpenTelemetrySdk.builder();
OpenTelemetrySdkBuilder builder =
OpenTelemetrySdkBuilderUtil.setSdkConfigProvider(
OpenTelemetrySdk.builder(), sdkConfigProvider);
String fileFormat = model.getFileFormat();
if (fileFormat == null || !SUPPORTED_FILE_FORMATS.matcher(fileFormat).matches()) {
throw new DeclarativeConfigException(
Expand All @@ -44,7 +47,7 @@ public ExtendedOpenTelemetrySdk create(
// behavior for experimental properties.

if (Objects.equals(true, model.getDisabled())) {
return ExtendedOpenTelemetrySdk.create(builder.build(), sdkConfigProvider);
return (ExtendedOpenTelemetrySdk) builder.build();
}

if (model.getPropagator() != null) {
Expand Down Expand Up @@ -92,7 +95,6 @@ public ExtendedOpenTelemetrySdk create(
.build()));
}

OpenTelemetrySdk openTelemetrySdk = context.addCloseable(builder.build());
return ExtendedOpenTelemetrySdk.create(openTelemetrySdk, sdkConfigProvider);
return (ExtendedOpenTelemetrySdk) context.addCloseable(builder.build());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -19,10 +19,13 @@ public final class SdkConfigProvider implements ConfigProvider {

private SdkConfigProvider(
OpenTelemetryConfigurationModel model, ComponentLoader componentLoader) {
DeclarativeConfigProperties configProperties =
DeclarativeConfiguration.toConfigProperties(model, componentLoader);
this.instrumentationConfig =
configProperties.getStructured("instrumentation/development", empty());
this(
DeclarativeConfiguration.toConfigProperties(model, componentLoader)
.getStructured("instrumentation/development", empty()));
}

private SdkConfigProvider(DeclarativeConfigProperties instrumentationConfig) {
this.instrumentationConfig = instrumentationConfig;
}

/**
Expand All @@ -47,6 +50,15 @@ public static SdkConfigProvider create(
return new SdkConfigProvider(model, componentLoader);
}

/**
* Create a no-op {@link SdkConfigProvider}.
*
* @return the no-op {@link SdkConfigProvider}
*/
public static SdkConfigProvider noop() {
return new SdkConfigProvider(DeclarativeConfigProperties.empty());
}

@Override
public DeclarativeConfigProperties getInstrumentationConfig() {
return instrumentationConfig;
Expand Down
Loading
Loading