From 208a3ec9f83105940f9217e530b792e9d225b86b Mon Sep 17 00:00:00 2001 From: Jack Berg Date: Wed, 4 Feb 2026 15:56:00 -0600 Subject: [PATCH 1/3] Add support for setting internal telemetry version w/ declarative config --- .../internal/OtlpDeclarativeConfigUtil.java | 33 +- ...rpcLogRecordExporterComponentProvider.java | 12 +- ...lpGrpcMetricExporterComponentProvider.java | 11 +- ...OtlpGrpcSpanExporterComponentProvider.java | 11 +- ...ttpLogRecordExporterComponentProvider.java | 12 +- ...lpHttpMetricExporterComponentProvider.java | 11 +- ...OtlpHttpSpanExporterComponentProvider.java | 11 +- .../internal/ExtendedComponentProvider.java | 36 ++ sdk-extensions/autoconfigure/build.gradle.kts | 5 + .../FullDeclarativeConfigTest.java | 379 ++++++++++++++++++ .../fileconfig/DeclarativeConfigContext.java | 39 +- .../fileconfig/LogRecordProcessorFactory.java | 5 + .../fileconfig/LoggerProviderFactory.java | 6 + .../OpenTelemetryConfigurationFactory.java | 1 + .../fileconfig/SpanProcessorFactory.java | 5 + .../fileconfig/TracerProviderFactory.java | 6 + 16 files changed, 557 insertions(+), 26 deletions(-) create mode 100644 sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/ExtendedComponentProvider.java create mode 100644 sdk-extensions/autoconfigure/src/testIncubating/java/io/opentelemetry/sdk/autoconfigure/FullDeclarativeConfigTest.java diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpDeclarativeConfigUtil.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpDeclarativeConfigUtil.java index ef4e2b8a099..8e71c2c8289 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpDeclarativeConfigUtil.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpDeclarativeConfigUtil.java @@ -10,20 +10,25 @@ import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.readFileBytes; import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.validateEndpoint; +import io.opentelemetry.api.incubator.config.ConfigProvider; +import io.opentelemetry.api.incubator.config.DeclarativeConfigException; import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.common.ComponentLoader; import io.opentelemetry.exporter.internal.IncubatingExporterBuilderUtil; 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.common.InternalTelemetryVersion; import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.common.export.RetryPolicy; import java.net.URL; import java.time.Duration; import java.util.Collections; import java.util.List; +import java.util.Locale; import java.util.function.BiConsumer; import java.util.function.Consumer; +import javax.annotation.Nullable; /** * This class is internal and is hence not for public use. Its APIs are unstable and can change at @@ -48,6 +53,7 @@ public static String getStructuredConfigOtlpProtocol(DeclarativeConfigProperties public static void configureOtlpExporterBuilder( String dataType, DeclarativeConfigProperties config, + ConfigProvider configProvider, Consumer setComponentLoader, Consumer setEndpoint, BiConsumer addHeader, @@ -57,7 +63,8 @@ public static void configureOtlpExporterBuilder( BiConsumer setClientTls, Consumer setRetryPolicy, Consumer setMemoryMode, - boolean isHttpProtobuf) { + boolean isHttpProtobuf, + Consumer internalTelemetryVersionConsumer) { setComponentLoader.accept(config.getComponentLoader()); URL endpoint = validateEndpoint(config.getString("endpoint"), isHttpProtobuf); @@ -119,6 +126,30 @@ public static void configureOtlpExporterBuilder( } IncubatingExporterBuilderUtil.configureExporterMemoryMode(config, setMemoryMode); + + InternalTelemetryVersion internalTelemetryVersion = getInternalTelemetryVersion(configProvider); + if (internalTelemetryVersion != null) { + internalTelemetryVersionConsumer.accept(internalTelemetryVersion); + } + } + + @Nullable + private static InternalTelemetryVersion getInternalTelemetryVersion( + ConfigProvider configProvider) { + String internalTelemetryVersion = + configProvider.getInstrumentationConfig("otel_sdk").getString("internal_telemetry_version"); + if (internalTelemetryVersion == null) { + return null; + } + switch (internalTelemetryVersion.toLowerCase(Locale.ROOT)) { + case "legacy": + return InternalTelemetryVersion.LEGACY; + case "latest": + return InternalTelemetryVersion.LATEST; + default: + throw new DeclarativeConfigException( + "Invalid sdk telemetry version: " + internalTelemetryVersion); + } } private OtlpDeclarativeConfigUtil() {} diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpGrpcLogRecordExporterComponentProvider.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpGrpcLogRecordExporterComponentProvider.java index 6afb9a601cd..29e4a5e958c 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpGrpcLogRecordExporterComponentProvider.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpGrpcLogRecordExporterComponentProvider.java @@ -7,10 +7,11 @@ import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.DATA_TYPE_LOGS; +import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporter; import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder; -import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; +import io.opentelemetry.sdk.autoconfigure.spi.internal.ExtendedComponentProvider; import io.opentelemetry.sdk.logs.export.LogRecordExporter; /** @@ -19,7 +20,7 @@ *

This class is internal and is hence not for public use. Its APIs are unstable and can change * at any time. */ -public class OtlpGrpcLogRecordExporterComponentProvider implements ComponentProvider { +public class OtlpGrpcLogRecordExporterComponentProvider implements ExtendedComponentProvider { @Override public Class getType() { @@ -32,12 +33,14 @@ public String getName() { } @Override - public LogRecordExporter create(DeclarativeConfigProperties config) { + public LogRecordExporter create( + DeclarativeConfigProperties config, ConfigProvider configProvider) { OtlpGrpcLogRecordExporterBuilder builder = grpcBuilder(); OtlpDeclarativeConfigUtil.configureOtlpExporterBuilder( DATA_TYPE_LOGS, config, + configProvider, builder::setComponentLoader, builder::setEndpoint, builder::addHeader, @@ -47,7 +50,8 @@ public LogRecordExporter create(DeclarativeConfigProperties config) { builder::setClientTls, builder::setRetryPolicy, builder::setMemoryMode, - /* isHttpProtobuf= */ false); + /* isHttpProtobuf= */ false, + builder::setInternalTelemetryVersion); return builder.build(); } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpGrpcMetricExporterComponentProvider.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpGrpcMetricExporterComponentProvider.java index cf8107f8499..aa09f069327 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpGrpcMetricExporterComponentProvider.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpGrpcMetricExporterComponentProvider.java @@ -7,11 +7,12 @@ import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.DATA_TYPE_METRICS; +import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.exporter.internal.IncubatingExporterBuilderUtil; import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporter; import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder; -import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; +import io.opentelemetry.sdk.autoconfigure.spi.internal.ExtendedComponentProvider; import io.opentelemetry.sdk.metrics.export.MetricExporter; /** @@ -20,7 +21,7 @@ *

This class is internal and is hence not for public use. Its APIs are unstable and can change * at any time. */ -public class OtlpGrpcMetricExporterComponentProvider implements ComponentProvider { +public class OtlpGrpcMetricExporterComponentProvider implements ExtendedComponentProvider { @Override public Class getType() { @@ -33,12 +34,13 @@ public String getName() { } @Override - public MetricExporter create(DeclarativeConfigProperties config) { + public MetricExporter create(DeclarativeConfigProperties config, ConfigProvider configProvider) { OtlpGrpcMetricExporterBuilder builder = grpcBuilder(); OtlpDeclarativeConfigUtil.configureOtlpExporterBuilder( DATA_TYPE_METRICS, config, + configProvider, builder::setComponentLoader, builder::setEndpoint, builder::addHeader, @@ -48,7 +50,8 @@ public MetricExporter create(DeclarativeConfigProperties config) { builder::setClientTls, builder::setRetryPolicy, builder::setMemoryMode, - /* isHttpProtobuf= */ false); + /* isHttpProtobuf= */ false, + builder::setInternalTelemetryVersion); IncubatingExporterBuilderUtil.configureOtlpAggregationTemporality( config, builder::setAggregationTemporalitySelector); IncubatingExporterBuilderUtil.configureOtlpHistogramDefaultAggregation( diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpGrpcSpanExporterComponentProvider.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpGrpcSpanExporterComponentProvider.java index 17995efb946..920683c2bfa 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpGrpcSpanExporterComponentProvider.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpGrpcSpanExporterComponentProvider.java @@ -7,10 +7,11 @@ import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.DATA_TYPE_TRACES; +import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter; import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder; -import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; +import io.opentelemetry.sdk.autoconfigure.spi.internal.ExtendedComponentProvider; import io.opentelemetry.sdk.trace.export.SpanExporter; /** @@ -19,7 +20,7 @@ *

This class is internal and is hence not for public use. Its APIs are unstable and can change * at any time. */ -public class OtlpGrpcSpanExporterComponentProvider implements ComponentProvider { +public class OtlpGrpcSpanExporterComponentProvider implements ExtendedComponentProvider { @Override public Class getType() { @@ -32,12 +33,13 @@ public String getName() { } @Override - public SpanExporter create(DeclarativeConfigProperties config) { + public SpanExporter create(DeclarativeConfigProperties config, ConfigProvider configProvider) { OtlpGrpcSpanExporterBuilder builder = grpcBuilder(); OtlpDeclarativeConfigUtil.configureOtlpExporterBuilder( DATA_TYPE_TRACES, config, + configProvider, builder::setComponentLoader, builder::setEndpoint, builder::addHeader, @@ -47,7 +49,8 @@ public SpanExporter create(DeclarativeConfigProperties config) { builder::setClientTls, builder::setRetryPolicy, builder::setMemoryMode, - /* isHttpProtobuf= */ false); + /* isHttpProtobuf= */ false, + builder::setInternalTelemetryVersion); return builder.build(); } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpHttpLogRecordExporterComponentProvider.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpHttpLogRecordExporterComponentProvider.java index a2850b254ca..e40a8d60eb7 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpHttpLogRecordExporterComponentProvider.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpHttpLogRecordExporterComponentProvider.java @@ -7,10 +7,11 @@ import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.DATA_TYPE_LOGS; +import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporter; import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder; -import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; +import io.opentelemetry.sdk.autoconfigure.spi.internal.ExtendedComponentProvider; import io.opentelemetry.sdk.logs.export.LogRecordExporter; /** @@ -19,7 +20,7 @@ *

This class is internal and is hence not for public use. Its APIs are unstable and can change * at any time. */ -public class OtlpHttpLogRecordExporterComponentProvider implements ComponentProvider { +public class OtlpHttpLogRecordExporterComponentProvider implements ExtendedComponentProvider { @Override public Class getType() { @@ -32,12 +33,14 @@ public String getName() { } @Override - public LogRecordExporter create(DeclarativeConfigProperties config) { + public LogRecordExporter create( + DeclarativeConfigProperties config, ConfigProvider configProvider) { OtlpHttpLogRecordExporterBuilder builder = httpBuilder(); OtlpDeclarativeConfigUtil.configureOtlpExporterBuilder( DATA_TYPE_LOGS, config, + configProvider, builder::setComponentLoader, builder::setEndpoint, builder::addHeader, @@ -47,7 +50,8 @@ public LogRecordExporter create(DeclarativeConfigProperties config) { builder::setClientTls, builder::setRetryPolicy, builder::setMemoryMode, - /* isHttpProtobuf= */ true); + /* isHttpProtobuf= */ true, + builder::setInternalTelemetryVersion); return builder.build(); } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpHttpMetricExporterComponentProvider.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpHttpMetricExporterComponentProvider.java index 0b59ee9380a..cbe75458edc 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpHttpMetricExporterComponentProvider.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpHttpMetricExporterComponentProvider.java @@ -7,11 +7,12 @@ import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.DATA_TYPE_METRICS; +import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.exporter.internal.IncubatingExporterBuilderUtil; import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporter; import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder; -import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; +import io.opentelemetry.sdk.autoconfigure.spi.internal.ExtendedComponentProvider; import io.opentelemetry.sdk.metrics.export.MetricExporter; /** @@ -20,7 +21,7 @@ *

This class is internal and is hence not for public use. Its APIs are unstable and can change * at any time. */ -public class OtlpHttpMetricExporterComponentProvider implements ComponentProvider { +public class OtlpHttpMetricExporterComponentProvider implements ExtendedComponentProvider { @Override public Class getType() { @@ -33,12 +34,13 @@ public String getName() { } @Override - public MetricExporter create(DeclarativeConfigProperties config) { + public MetricExporter create(DeclarativeConfigProperties config, ConfigProvider configProvider) { OtlpHttpMetricExporterBuilder builder = httpBuilder(); OtlpDeclarativeConfigUtil.configureOtlpExporterBuilder( DATA_TYPE_METRICS, config, + configProvider, builder::setComponentLoader, builder::setEndpoint, builder::addHeader, @@ -48,7 +50,8 @@ public MetricExporter create(DeclarativeConfigProperties config) { builder::setClientTls, builder::setRetryPolicy, builder::setMemoryMode, - /* isHttpProtobuf= */ true); + /* isHttpProtobuf= */ true, + builder::setInternalTelemetryVersion); IncubatingExporterBuilderUtil.configureOtlpAggregationTemporality( config, builder::setAggregationTemporalitySelector); IncubatingExporterBuilderUtil.configureOtlpHistogramDefaultAggregation( diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpHttpSpanExporterComponentProvider.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpHttpSpanExporterComponentProvider.java index d97b2e30628..e797a548cdd 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpHttpSpanExporterComponentProvider.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpHttpSpanExporterComponentProvider.java @@ -7,10 +7,11 @@ import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.DATA_TYPE_TRACES; +import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporter; import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder; -import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; +import io.opentelemetry.sdk.autoconfigure.spi.internal.ExtendedComponentProvider; import io.opentelemetry.sdk.trace.export.SpanExporter; /** @@ -19,7 +20,7 @@ *

This class is internal and is hence not for public use. Its APIs are unstable and can change * at any time. */ -public class OtlpHttpSpanExporterComponentProvider implements ComponentProvider { +public class OtlpHttpSpanExporterComponentProvider implements ExtendedComponentProvider { @Override public Class getType() { @@ -32,12 +33,13 @@ public String getName() { } @Override - public SpanExporter create(DeclarativeConfigProperties config) { + public SpanExporter create(DeclarativeConfigProperties config, ConfigProvider configProvider) { OtlpHttpSpanExporterBuilder builder = httpBuilder(); OtlpDeclarativeConfigUtil.configureOtlpExporterBuilder( DATA_TYPE_TRACES, config, + configProvider, builder::setComponentLoader, builder::setEndpoint, builder::addHeader, @@ -47,7 +49,8 @@ public SpanExporter create(DeclarativeConfigProperties config) { builder::setClientTls, builder::setRetryPolicy, builder::setMemoryMode, - /* isHttpProtobuf= */ true); + /* isHttpProtobuf= */ true, + builder::setInternalTelemetryVersion); return builder.build(); } diff --git a/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/ExtendedComponentProvider.java b/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/ExtendedComponentProvider.java new file mode 100644 index 00000000000..e2c8c194d7f --- /dev/null +++ b/sdk-extensions/autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi/internal/ExtendedComponentProvider.java @@ -0,0 +1,36 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.autoconfigure.spi.internal; + +import io.opentelemetry.api.incubator.config.ConfigProvider; +import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; + +/** + * Extended version of {@link ComponentProvider} that allows access to the {@link ConfigProvider}. + * + *

This class is internal and is hence not for public use. Its APIs are unstable and can change + * at any time. + */ +public interface ExtendedComponentProvider extends ComponentProvider { + + /** + * Configure an instance of the SDK extension component according to the {@code config}. + * + *

While this is the method called by the SDK, implementations can safely only implement {@link + * #create(DeclarativeConfigProperties)} since the default implementation delegates to it. + * + * @param config the configuration provided where the component is referenced in a configuration + * file. + * @param configProvider the configuration provider. + * @return an instance the SDK extension component + */ + Object create(DeclarativeConfigProperties config, ConfigProvider configProvider); + + @Override + default Object create(DeclarativeConfigProperties config) { + return create(config, ConfigProvider.noop()); + } +} diff --git a/sdk-extensions/autoconfigure/build.gradle.kts b/sdk-extensions/autoconfigure/build.gradle.kts index 3d54ea736c4..4d45a9ba673 100644 --- a/sdk-extensions/autoconfigure/build.gradle.kts +++ b/sdk-extensions/autoconfigure/build.gradle.kts @@ -85,7 +85,12 @@ testing { dependencies { implementation(project(":sdk-extensions:incubator")) implementation(project(":exporters:logging")) + implementation(project(":exporters:otlp:all")) implementation(project(":sdk:testing")) + + implementation("io.opentelemetry.proto:opentelemetry-proto") + implementation("com.linecorp.armeria:armeria-junit5") + implementation("com.linecorp.armeria:armeria-grpc") } } diff --git a/sdk-extensions/autoconfigure/src/testIncubating/java/io/opentelemetry/sdk/autoconfigure/FullDeclarativeConfigTest.java b/sdk-extensions/autoconfigure/src/testIncubating/java/io/opentelemetry/sdk/autoconfigure/FullDeclarativeConfigTest.java new file mode 100644 index 00000000000..aebb8b0122c --- /dev/null +++ b/sdk-extensions/autoconfigure/src/testIncubating/java/io/opentelemetry/sdk/autoconfigure/FullDeclarativeConfigTest.java @@ -0,0 +1,379 @@ +/* + * Copyright The OpenTelemetry Authors + * SPDX-License-Identifier: Apache-2.0 + */ + +package io.opentelemetry.sdk.autoconfigure; + +import static org.assertj.core.api.Assertions.assertThat; +import static org.awaitility.Awaitility.await; + +import com.linecorp.armeria.server.ServerBuilder; +import com.linecorp.armeria.server.grpc.GrpcService; +import com.linecorp.armeria.server.logging.LoggingService; +import com.linecorp.armeria.testing.junit5.server.ServerExtension; +import io.grpc.stub.StreamObserver; +import io.opentelemetry.api.GlobalOpenTelemetry; +import io.opentelemetry.api.baggage.propagation.W3CBaggagePropagator; +import io.opentelemetry.api.logs.Logger; +import io.opentelemetry.api.logs.Severity; +import io.opentelemetry.api.metrics.Meter; +import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator; +import io.opentelemetry.proto.collector.logs.v1.ExportLogsServiceRequest; +import io.opentelemetry.proto.collector.logs.v1.ExportLogsServiceResponse; +import io.opentelemetry.proto.collector.logs.v1.LogsServiceGrpc; +import io.opentelemetry.proto.collector.metrics.v1.ExportMetricsServiceRequest; +import io.opentelemetry.proto.collector.metrics.v1.ExportMetricsServiceResponse; +import io.opentelemetry.proto.collector.metrics.v1.MetricsServiceGrpc; +import io.opentelemetry.proto.collector.trace.v1.ExportTraceServiceRequest; +import io.opentelemetry.proto.collector.trace.v1.ExportTraceServiceResponse; +import io.opentelemetry.proto.collector.trace.v1.TraceServiceGrpc; +import io.opentelemetry.proto.common.v1.AnyValue; +import io.opentelemetry.proto.common.v1.KeyValue; +import io.opentelemetry.sdk.OpenTelemetrySdk; +import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; +import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; +import java.io.IOException; +import java.nio.charset.StandardCharsets; +import java.nio.file.Files; +import java.nio.file.Path; +import java.util.ArrayList; +import java.util.Collection; +import java.util.Collections; +import java.util.List; +import java.util.concurrent.BlockingQueue; +import java.util.concurrent.LinkedBlockingDeque; +import java.util.concurrent.TimeUnit; +import org.junit.jupiter.api.AfterEach; +import org.junit.jupiter.api.BeforeEach; +import org.junit.jupiter.api.Test; +import org.junit.jupiter.api.extension.RegisterExtension; +import org.junit.jupiter.api.io.TempDir; + +/** Same as {@code FullConfigTest}, but using declarative configuration. */ +@SuppressWarnings("InterruptedExceptionSwallowed") +public class FullDeclarativeConfigTest { + + private static final BlockingQueue otlpTraceRequests = + new LinkedBlockingDeque<>(); + private static final BlockingQueue otlpMetricsRequests = + new LinkedBlockingDeque<>(); + private static final BlockingQueue otlpLogsRequests = + new LinkedBlockingDeque<>(); + + @RegisterExtension + public static final ServerExtension server = + new ServerExtension() { + @Override + protected void configure(ServerBuilder sb) { + sb.service( + GrpcService.builder() + // OTLP spans + .addService( + new TraceServiceGrpc.TraceServiceImplBase() { + @Override + public void export( + ExportTraceServiceRequest request, + StreamObserver responseObserver) { + otlpTraceRequests.add(request); + responseObserver.onNext(ExportTraceServiceResponse.getDefaultInstance()); + responseObserver.onCompleted(); + } + }) + // OTLP metrics + .addService( + new MetricsServiceGrpc.MetricsServiceImplBase() { + @Override + public void export( + ExportMetricsServiceRequest request, + StreamObserver responseObserver) { + if (request.getResourceMetricsCount() > 0) { + otlpMetricsRequests.add(request); + } + responseObserver.onNext( + ExportMetricsServiceResponse.getDefaultInstance()); + responseObserver.onCompleted(); + } + }) + // OTLP logs + .addService( + new LogsServiceGrpc.LogsServiceImplBase() { + @Override + public void export( + ExportLogsServiceRequest request, + StreamObserver responseObserver) { + if (request.getResourceLogsCount() > 0) { + otlpLogsRequests.add(request); + } + responseObserver.onNext(ExportLogsServiceResponse.getDefaultInstance()); + responseObserver.onCompleted(); + } + }) + .useBlockingTaskExecutor(true) + .build()); + sb.decorator(LoggingService.newDecorator()); + } + }; + + private OpenTelemetrySdk openTelemetrySdk; + + @BeforeEach + void setUp(@TempDir Path tempDir) throws IOException { + otlpTraceRequests.clear(); + otlpMetricsRequests.clear(); + otlpLogsRequests.clear(); + + String endpoint = "http://localhost:" + server.httpPort(); + String yaml = + "file_format: \"1.0-rc.1\"\n" + + "resource:\n" + + " attributes:\n" + + " - name: service.name\n" + + " value: test\n" + + "propagator:\n" + + " composite:\n" + + " - tracecontext:\n" + + " - baggage:\n" + + "tracer_provider:\n" + + " processors:\n" + + " - batch:\n" + + " schedule_delay: 60000\n" // High delay for reliable export batches after + // flushing + + " exporter:\n" + + " otlp_grpc:\n" + + " endpoint: " + + endpoint + + "\n" + + "meter_provider:\n" + + " readers:\n" + + " - periodic:\n" + + " exporter:\n" + + " otlp_grpc:\n" + + " endpoint: " + + endpoint + + "\n" + + "logger_provider:\n" + + " processors:\n" + + " - batch:\n" + + " schedule_delay: 60000\n" // High delay for reliable export batches after + // flushing + + " exporter:\n" + + " otlp_grpc:\n" + + " endpoint: " + + endpoint + + "\n" + + "instrumentation/development:\n" + + " java:\n" + + " otel_sdk:\n" + + " internal_telemetry_version: latest\n"; + + Path path = tempDir.resolve("otel-config.yaml"); + Files.write(path, yaml.getBytes(StandardCharsets.UTF_8)); + + // Initialize here so we can shutdown when done + GlobalOpenTelemetry.resetForTest(); + ConfigProperties config = + DefaultConfigProperties.createFromMap( + Collections.singletonMap("otel.experimental.config.file", path.toString())); + openTelemetrySdk = + AutoConfiguredOpenTelemetrySdk.builder() + .setConfig(config) + .setResultAsGlobal() + .build() + .getOpenTelemetrySdk(); + } + + @AfterEach + void afterEach() { + openTelemetrySdk.close(); + GlobalOpenTelemetry.resetForTest(); + } + + @Test + void configures() throws Exception { + Collection fields = + GlobalOpenTelemetry.get().getPropagators().getTextMapPropagator().fields(); + List keys = new ArrayList<>(); + keys.addAll(W3CTraceContextPropagator.getInstance().fields()); + keys.addAll(W3CBaggagePropagator.getInstance().fields()); + assertThat(fields).containsExactlyInAnyOrderElementsOf(keys); + + GlobalOpenTelemetry.get() + .getTracer("test") + .spanBuilder("test") + .startSpan() + .setAttribute("cat", "meow") + .end(); + + Meter meter = GlobalOpenTelemetry.get().getMeter("test"); + meter.counterBuilder("my-metric").build().add(1); + + Logger logger = GlobalOpenTelemetry.get().getLogsBridge().get("test"); + logger.logRecordBuilder().setBody("info log message").setSeverity(Severity.INFO).emit(); + + openTelemetrySdk.getSdkTracerProvider().forceFlush().join(10, TimeUnit.SECONDS); + openTelemetrySdk.getSdkLoggerProvider().forceFlush().join(10, TimeUnit.SECONDS); + openTelemetrySdk.getSdkMeterProvider().forceFlush().join(10, TimeUnit.SECONDS); + + await().untilAsserted(() -> assertThat(otlpTraceRequests).hasSize(1)); + + ExportTraceServiceRequest traceRequest = otlpTraceRequests.take(); + List spanResourceAttributes = + traceRequest.getResourceSpans(0).getResource().getAttributesList(); + assertHasKeyValue(spanResourceAttributes, "service.name", "test"); + io.opentelemetry.proto.trace.v1.Span span = + traceRequest.getResourceSpans(0).getScopeSpans(0).getSpans(0); + assertHasKeyValue(span.getAttributesList(), "cat", "meow"); + + // Flush again to get metric exporter metrics. + openTelemetrySdk.getSdkMeterProvider().forceFlush().join(10, TimeUnit.SECONDS); + // await on assertions since metrics may come in different order for BatchSpanProcessor, + // exporter, or the ones we created in the test. + await() + .untilAsserted( + () -> { + ExportMetricsServiceRequest metricRequest = otlpMetricsRequests.take(); + + assertThat(metricRequest.getResourceMetricsList()) + .satisfiesExactly( + resourceMetrics -> { + List metricResourceAttributes = + resourceMetrics.getResource().getAttributesList(); + assertHasKeyValue(metricResourceAttributes, "service.name", "test"); + assertThat(resourceMetrics.getScopeMetricsList()) + .anySatisfy( + scopeMetrics -> { + assertThat(scopeMetrics.getScope().getName()).isEqualTo("test"); + assertThat(scopeMetrics.getMetricsList()) + .satisfiesExactlyInAnyOrder( + metric -> + assertThat(metric.getName()).isEqualTo("my-metric")); + }) + // This verifies that MeterProvider was injected into OTLP exporters and + // the internal telemetry version was set. + .anySatisfy( + scopeMetrics -> { + assertThat(scopeMetrics.getScope().getName()) + .isEqualTo( + "io.opentelemetry.exporters.otlp_grpc_metric_exporter"); + assertThat(scopeMetrics.getMetricsList()) + .satisfiesExactlyInAnyOrder( + metric -> + assertThat(metric.getName()) + .isEqualTo( + "otel.sdk.exporter.metric_data_point.inflight"), + metric -> + assertThat(metric.getName()) + .isEqualTo( + "otel.sdk.exporter.operation.duration"), + metric -> + assertThat(metric.getName()) + .isEqualTo( + "otel.sdk.exporter.metric_data_point.exported")); + }) + .anySatisfy( + scopeMetrics -> { + assertThat(scopeMetrics.getScope().getName()) + .isEqualTo( + "io.opentelemetry.exporters.otlp_grpc_log_exporter"); + assertThat(scopeMetrics.getMetricsList()) + .satisfiesExactlyInAnyOrder( + metric -> + assertThat(metric.getName()) + .isEqualTo("otel.sdk.exporter.log.inflight"), + metric -> + assertThat(metric.getName()) + .isEqualTo( + "otel.sdk.exporter.operation.duration"), + metric -> + assertThat(metric.getName()) + .isEqualTo("otel.sdk.exporter.log.exported")); + }) + .anySatisfy( + scopeMetrics -> { + assertThat(scopeMetrics.getScope().getName()) + .isEqualTo( + "io.opentelemetry.exporters.otlp_grpc_span_exporter"); + assertThat(scopeMetrics.getMetricsList()) + .satisfiesExactlyInAnyOrder( + metric -> + assertThat(metric.getName()) + .isEqualTo("otel.sdk.exporter.span.inflight"), + metric -> + assertThat(metric.getName()) + .isEqualTo( + "otel.sdk.exporter.operation.duration"), + metric -> + assertThat(metric.getName()) + .isEqualTo("otel.sdk.exporter.span.exported")); + }) + .anySatisfy( + scopeMetrics -> { + assertThat(scopeMetrics.getScope().getName()) + .isEqualTo("io.opentelemetry.sdk.logs"); + assertThat(scopeMetrics.getMetricsList()) + .satisfiesExactlyInAnyOrder( + metric -> + assertThat(metric.getName()) + .isEqualTo("otel.sdk.log.created"), + metric -> + assertThat(metric.getName()) + .isEqualTo("otel.sdk.processor.log.processed"), + metric -> + assertThat(metric.getName()) + .isEqualTo( + "otel.sdk.processor.log.queue.capacity"), + metric -> + assertThat(metric.getName()) + .isEqualTo("otel.sdk.processor.log.queue.size")); + }) + .anySatisfy( + scopeMetrics -> { + assertThat(scopeMetrics.getScope().getName()) + .isEqualTo("io.opentelemetry.sdk.trace"); + assertThat(scopeMetrics.getMetricsList()) + .satisfiesExactlyInAnyOrder( + metric -> + assertThat(metric.getName()) + .isEqualTo("otel.sdk.span.live"), + metric -> + assertThat(metric.getName()) + .isEqualTo("otel.sdk.span.started"), + metric -> + assertThat(metric.getName()) + .isEqualTo("otel.sdk.processor.span.processed"), + metric -> + assertThat(metric.getName()) + .isEqualTo( + "otel.sdk.processor.span.queue.capacity"), + metric -> + assertThat(metric.getName()) + .isEqualTo("otel.sdk.processor.span.queue.size")); + }); + }); + }); + + await().untilAsserted(() -> assertThat(otlpLogsRequests).hasSize(1)); + ExportLogsServiceRequest logRequest = otlpLogsRequests.take(); + List logResourceAttributes = + logRequest.getResourceLogs(0).getResource().getAttributesList(); + assertHasKeyValue(logResourceAttributes, "service.name", "test"); + + assertThat(logRequest.getResourceLogs(0).getScopeLogs(0).getLogRecordsList()) + .satisfiesExactlyInAnyOrder( + logRecord -> { + assertThat(logRecord.getBody().getStringValue()).isEqualTo("info log message"); + assertThat(logRecord.getSeverityNumberValue()) + .isEqualTo(Severity.INFO.getSeverityNumber()); + }); + } + + private static void assertHasKeyValue(List keyValues, String key, String value) { + assertThat(keyValues) + .contains( + KeyValue.newBuilder() + .setKey(key) + .setValue(AnyValue.newBuilder().setStringValue(value)) + .build()); + } +} diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigContext.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigContext.java index 404fab7bc56..7ae3df963d6 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigContext.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigContext.java @@ -5,17 +5,21 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig; +import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.api.incubator.config.DeclarativeConfigException; import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; import io.opentelemetry.api.metrics.MeterProvider; import io.opentelemetry.common.ComponentLoader; import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper; import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider; +import io.opentelemetry.sdk.autoconfigure.spi.internal.ExtendedComponentProvider; +import io.opentelemetry.sdk.common.InternalTelemetryVersion; import io.opentelemetry.sdk.resources.Resource; import java.io.Closeable; import java.util.ArrayList; import java.util.Collections; import java.util.List; +import java.util.Locale; import java.util.stream.Collectors; import javax.annotation.Nullable; @@ -26,6 +30,7 @@ class DeclarativeConfigContext { private final List closeables = new ArrayList<>(); @Nullable private volatile MeterProvider meterProvider; @Nullable private Resource resource = null; + @Nullable private ConfigProvider configProvider; // Visible for testing DeclarativeConfigContext(SpiHelper spiHelper) { @@ -58,6 +63,10 @@ public void setMeterProvider(MeterProvider meterProvider) { this.meterProvider = meterProvider; } + public void setConfigProvider(ConfigProvider configProvider) { + this.configProvider = configProvider; + } + Resource getResource() { // called via reflection from io.opentelemetry.sdk.autoconfigure.IncubatingUtil if (resource == null) { @@ -70,6 +79,27 @@ void setResource(Resource resource) { this.resource = resource; } + @Nullable + InternalTelemetryVersion getInternalTelemetryVersion() { + if (configProvider == null) { + return null; + } + String internalTelemetryVersion = + configProvider.getInstrumentationConfig("otel_sdk").getString("internal_telemetry_version"); + if (internalTelemetryVersion == null) { + return null; + } + switch (internalTelemetryVersion.toLowerCase(Locale.ROOT)) { + case "legacy": + return InternalTelemetryVersion.LEGACY; + case "latest": + return InternalTelemetryVersion.LATEST; + default: + throw new DeclarativeConfigException( + "Invalid sdk telemetry version: " + internalTelemetryVersion); + } + } + SpiHelper getSpiHelper() { return spiHelper; } @@ -112,9 +142,16 @@ T loadComponent(Class type, ConfigKeyValue configKeyValue) { } // Exactly one matching component provider ComponentProvider provider = matchedProviders.get(0); + ConfigProvider configProvider = this.configProvider; + if (configProvider == null) { + configProvider = ConfigProvider.noop(); + } try { - Object component = provider.create(config); + Object component = + (provider instanceof ExtendedComponentProvider) + ? ((ExtendedComponentProvider) provider).create(config, configProvider) + : provider.create(config); if (component instanceof Closeable) { closeables.add((Closeable) component); } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactory.java index 22d53510bca..9d867b0c09c 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactory.java @@ -6,6 +6,7 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig; import io.opentelemetry.api.metrics.MeterProvider; +import io.opentelemetry.sdk.common.InternalTelemetryVersion; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.BatchLogRecordProcessorModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordExporterModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordProcessorModel; @@ -71,6 +72,10 @@ private static LogRecordProcessor createBatchLogRecordProcessor( if (meterProvider != null) { builder.setMeterProvider(meterProvider); } + InternalTelemetryVersion telemetryVersion = context.getInternalTelemetryVersion(); + if (telemetryVersion != null) { + builder.setInternalTelemetryVersion(telemetryVersion); + } return context.addCloseable(builder.build()); } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LoggerProviderFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LoggerProviderFactory.java index 892dc65c77a..f11b87c798e 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LoggerProviderFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LoggerProviderFactory.java @@ -8,6 +8,7 @@ import static io.opentelemetry.sdk.extension.incubator.fileconfig.FileConfigUtil.requireNonNull; import io.opentelemetry.api.logs.Severity; +import io.opentelemetry.api.metrics.MeterProvider; import io.opentelemetry.sdk.common.internal.ScopeConfigurator; import io.opentelemetry.sdk.common.internal.ScopeConfiguratorBuilder; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalLoggerConfigModel; @@ -45,6 +46,11 @@ public SdkLoggerProviderBuilder create( return builder; } + MeterProvider meterProvider = context.getMeterProvider(); + if (meterProvider != null) { + builder.setMeterProvider(() -> meterProvider); + } + LogLimits logLimits = LogLimitsFactory.getInstance() .create( diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactory.java index 649df9abb98..0a3ca0ea489 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/OpenTelemetryConfigurationFactory.java @@ -39,6 +39,7 @@ public ExtendedOpenTelemetrySdk create( DeclarativeConfiguration.toConfigProperties( model, context.getSpiHelper().getComponentLoader()); SdkConfigProvider sdkConfigProvider = SdkConfigProvider.create(modelProperties); + context.setConfigProvider(sdkConfigProvider); OpenTelemetrySdkBuilder builder = OpenTelemetrySdkBuilderUtil.setConfigProvider( OpenTelemetrySdk.builder(), sdkConfigProvider); diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactory.java index 75b0a557cc3..3c0cf40c74a 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactory.java @@ -6,6 +6,7 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig; import io.opentelemetry.api.metrics.MeterProvider; +import io.opentelemetry.sdk.common.InternalTelemetryVersion; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.BatchSpanProcessorModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SimpleSpanProcessorModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanExporterModel; @@ -67,6 +68,10 @@ private static SpanProcessor createBatchLogRecordProcessor( if (meterProvider != null) { builder.setMeterProvider(() -> meterProvider); } + InternalTelemetryVersion telemetryVersion = context.getInternalTelemetryVersion(); + if (telemetryVersion != null) { + builder.setInternalTelemetryVersion(telemetryVersion); + } return context.addCloseable(builder.build()); } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TracerProviderFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TracerProviderFactory.java index 4e28bb25c73..e2e700865c8 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TracerProviderFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TracerProviderFactory.java @@ -7,6 +7,7 @@ import static io.opentelemetry.sdk.extension.incubator.fileconfig.FileConfigUtil.requireNonNull; +import io.opentelemetry.api.metrics.MeterProvider; import io.opentelemetry.sdk.common.internal.ScopeConfigurator; import io.opentelemetry.sdk.common.internal.ScopeConfiguratorBuilder; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalTracerConfigModel; @@ -42,6 +43,11 @@ public SdkTracerProviderBuilder create( return builder; } + MeterProvider meterProvider = context.getMeterProvider(); + if (meterProvider != null) { + builder.setMeterProvider(() -> meterProvider); + } + SpanLimits spanLimits = SpanLimitsFactory.getInstance() .create( From bae2e17f1987ef3231fe7018010c3f6eb896035c Mon Sep 17 00:00:00 2001 From: Jack Berg Date: Tue, 10 Feb 2026 12:31:13 -0600 Subject: [PATCH 2/3] Declarative config defaults to disabled internal telemetry --- .../internal/OtlpDeclarativeConfigUtil.java | 13 +++++++---- ...rpcLogRecordExporterComponentProvider.java | 4 +++- ...lpGrpcMetricExporterComponentProvider.java | 4 +++- ...OtlpGrpcSpanExporterComponentProvider.java | 4 +++- ...ttpLogRecordExporterComponentProvider.java | 4 +++- ...lpHttpMetricExporterComponentProvider.java | 4 +++- ...OtlpHttpSpanExporterComponentProvider.java | 4 +++- .../fileconfig/DeclarativeConfigContext.java | 22 ++++++++++++++----- .../fileconfig/LogRecordProcessorFactory.java | 20 +++++------------ .../fileconfig/LoggerProviderFactory.java | 6 +---- .../fileconfig/SpanProcessorFactory.java | 16 ++------------ .../fileconfig/TracerProviderFactory.java | 6 +---- 12 files changed, 52 insertions(+), 55 deletions(-) diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpDeclarativeConfigUtil.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpDeclarativeConfigUtil.java index 8e71c2c8289..bcb55667f50 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpDeclarativeConfigUtil.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpDeclarativeConfigUtil.java @@ -64,7 +64,8 @@ public static void configureOtlpExporterBuilder( Consumer setRetryPolicy, Consumer setMemoryMode, boolean isHttpProtobuf, - Consumer internalTelemetryVersionConsumer) { + Consumer internalTelemetryVersionConsumer, + Runnable setNoopMeterProvider) { setComponentLoader.accept(config.getComponentLoader()); URL endpoint = validateEndpoint(config.getString("endpoint"), isHttpProtobuf); @@ -127,9 +128,13 @@ public static void configureOtlpExporterBuilder( IncubatingExporterBuilderUtil.configureExporterMemoryMode(config, setMemoryMode); - InternalTelemetryVersion internalTelemetryVersion = getInternalTelemetryVersion(configProvider); - if (internalTelemetryVersion != null) { - internalTelemetryVersionConsumer.accept(internalTelemetryVersion); + // InternalTelemetryVersion defaults to disabled (i.e. null) until semantic conventions are + // stable. To disable, set a noop meter provider. + InternalTelemetryVersion telemetryVersion = getInternalTelemetryVersion(configProvider); + if (telemetryVersion == null) { + setNoopMeterProvider.run(); + } else { + internalTelemetryVersionConsumer.accept(telemetryVersion); } } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpGrpcLogRecordExporterComponentProvider.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpGrpcLogRecordExporterComponentProvider.java index 29e4a5e958c..332787e9bf7 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpGrpcLogRecordExporterComponentProvider.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpGrpcLogRecordExporterComponentProvider.java @@ -9,6 +9,7 @@ import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; +import io.opentelemetry.api.metrics.MeterProvider; import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporter; import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder; import io.opentelemetry.sdk.autoconfigure.spi.internal.ExtendedComponentProvider; @@ -51,7 +52,8 @@ public LogRecordExporter create( builder::setRetryPolicy, builder::setMemoryMode, /* isHttpProtobuf= */ false, - builder::setInternalTelemetryVersion); + builder::setInternalTelemetryVersion, + () -> builder.setMeterProvider(MeterProvider::noop)); return builder.build(); } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpGrpcMetricExporterComponentProvider.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpGrpcMetricExporterComponentProvider.java index aa09f069327..6b8e2c60751 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpGrpcMetricExporterComponentProvider.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpGrpcMetricExporterComponentProvider.java @@ -9,6 +9,7 @@ import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; +import io.opentelemetry.api.metrics.MeterProvider; import io.opentelemetry.exporter.internal.IncubatingExporterBuilderUtil; import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporter; import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder; @@ -51,7 +52,8 @@ public MetricExporter create(DeclarativeConfigProperties config, ConfigProvider builder::setRetryPolicy, builder::setMemoryMode, /* isHttpProtobuf= */ false, - builder::setInternalTelemetryVersion); + builder::setInternalTelemetryVersion, + () -> builder.setMeterProvider(MeterProvider::noop)); IncubatingExporterBuilderUtil.configureOtlpAggregationTemporality( config, builder::setAggregationTemporalitySelector); IncubatingExporterBuilderUtil.configureOtlpHistogramDefaultAggregation( diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpGrpcSpanExporterComponentProvider.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpGrpcSpanExporterComponentProvider.java index 920683c2bfa..fe703101c2b 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpGrpcSpanExporterComponentProvider.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpGrpcSpanExporterComponentProvider.java @@ -9,6 +9,7 @@ import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; +import io.opentelemetry.api.metrics.MeterProvider; import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter; import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder; import io.opentelemetry.sdk.autoconfigure.spi.internal.ExtendedComponentProvider; @@ -50,7 +51,8 @@ public SpanExporter create(DeclarativeConfigProperties config, ConfigProvider co builder::setRetryPolicy, builder::setMemoryMode, /* isHttpProtobuf= */ false, - builder::setInternalTelemetryVersion); + builder::setInternalTelemetryVersion, + () -> builder.setMeterProvider(MeterProvider::noop)); return builder.build(); } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpHttpLogRecordExporterComponentProvider.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpHttpLogRecordExporterComponentProvider.java index e40a8d60eb7..902583f317a 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpHttpLogRecordExporterComponentProvider.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpHttpLogRecordExporterComponentProvider.java @@ -9,6 +9,7 @@ import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; +import io.opentelemetry.api.metrics.MeterProvider; import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporter; import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder; import io.opentelemetry.sdk.autoconfigure.spi.internal.ExtendedComponentProvider; @@ -51,7 +52,8 @@ public LogRecordExporter create( builder::setRetryPolicy, builder::setMemoryMode, /* isHttpProtobuf= */ true, - builder::setInternalTelemetryVersion); + builder::setInternalTelemetryVersion, + () -> builder.setMeterProvider(MeterProvider::noop)); return builder.build(); } diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpHttpMetricExporterComponentProvider.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpHttpMetricExporterComponentProvider.java index cbe75458edc..7c0568d57dd 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpHttpMetricExporterComponentProvider.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpHttpMetricExporterComponentProvider.java @@ -9,6 +9,7 @@ import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; +import io.opentelemetry.api.metrics.MeterProvider; import io.opentelemetry.exporter.internal.IncubatingExporterBuilderUtil; import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporter; import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporterBuilder; @@ -51,7 +52,8 @@ public MetricExporter create(DeclarativeConfigProperties config, ConfigProvider builder::setRetryPolicy, builder::setMemoryMode, /* isHttpProtobuf= */ true, - builder::setInternalTelemetryVersion); + builder::setInternalTelemetryVersion, + () -> builder.setMeterProvider(MeterProvider::noop)); IncubatingExporterBuilderUtil.configureOtlpAggregationTemporality( config, builder::setAggregationTemporalitySelector); IncubatingExporterBuilderUtil.configureOtlpHistogramDefaultAggregation( diff --git a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpHttpSpanExporterComponentProvider.java b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpHttpSpanExporterComponentProvider.java index e797a548cdd..4479801d436 100644 --- a/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpHttpSpanExporterComponentProvider.java +++ b/exporters/otlp/all/src/main/java/io/opentelemetry/exporter/otlp/internal/OtlpHttpSpanExporterComponentProvider.java @@ -9,6 +9,7 @@ import io.opentelemetry.api.incubator.config.ConfigProvider; import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties; +import io.opentelemetry.api.metrics.MeterProvider; import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporter; import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder; import io.opentelemetry.sdk.autoconfigure.spi.internal.ExtendedComponentProvider; @@ -50,7 +51,8 @@ public SpanExporter create(DeclarativeConfigProperties config, ConfigProvider co builder::setRetryPolicy, builder::setMemoryMode, /* isHttpProtobuf= */ true, - builder::setInternalTelemetryVersion); + builder::setInternalTelemetryVersion, + () -> builder.setMeterProvider(MeterProvider::noop)); return builder.build(); } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigContext.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigContext.java index 7ae3df963d6..beb0505f4e5 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigContext.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/DeclarativeConfigContext.java @@ -20,6 +20,9 @@ import java.util.Collections; import java.util.List; import java.util.Locale; +import java.util.Objects; +import java.util.function.Consumer; +import java.util.function.Supplier; import java.util.stream.Collectors; import javax.annotation.Nullable; @@ -54,11 +57,6 @@ List getCloseables() { return Collections.unmodifiableList(closeables); } - @Nullable - public MeterProvider getMeterProvider() { - return meterProvider; - } - public void setMeterProvider(MeterProvider meterProvider) { this.meterProvider = meterProvider; } @@ -79,8 +77,20 @@ void setResource(Resource resource) { this.resource = resource; } + public void setInternalTelemetry( + Consumer internalTelemetrySetter, + Consumer> meterProviderSetter) { + InternalTelemetryVersion telemetryVersion = getInternalTelemetryVersion(); + if (telemetryVersion != null) { + meterProviderSetter.accept(() -> Objects.requireNonNull(meterProvider)); + internalTelemetrySetter.accept(telemetryVersion); + } else { + meterProviderSetter.accept(MeterProvider::noop); + } + } + @Nullable - InternalTelemetryVersion getInternalTelemetryVersion() { + private InternalTelemetryVersion getInternalTelemetryVersion() { if (configProvider == null) { return null; } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactory.java index 9d867b0c09c..84ef72748ed 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LogRecordProcessorFactory.java @@ -5,8 +5,6 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig; -import io.opentelemetry.api.metrics.MeterProvider; -import io.opentelemetry.sdk.common.InternalTelemetryVersion; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.BatchLogRecordProcessorModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordExporterModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordProcessorModel; @@ -16,6 +14,7 @@ import io.opentelemetry.sdk.logs.export.BatchLogRecordProcessorBuilder; import io.opentelemetry.sdk.logs.export.LogRecordExporter; import io.opentelemetry.sdk.logs.export.SimpleLogRecordProcessor; +import io.opentelemetry.sdk.logs.export.SimpleLogRecordProcessorBuilder; import java.time.Duration; final class LogRecordProcessorFactory @@ -68,14 +67,7 @@ private static LogRecordProcessor createBatchLogRecordProcessor( if (batchModel.getScheduleDelay() != null) { builder.setScheduleDelay(Duration.ofMillis(batchModel.getScheduleDelay())); } - MeterProvider meterProvider = context.getMeterProvider(); - if (meterProvider != null) { - builder.setMeterProvider(meterProvider); - } - InternalTelemetryVersion telemetryVersion = context.getInternalTelemetryVersion(); - if (telemetryVersion != null) { - builder.setInternalTelemetryVersion(telemetryVersion); - } + context.setInternalTelemetry(builder::setInternalTelemetryVersion, builder::setMeterProvider); return context.addCloseable(builder.build()); } @@ -87,10 +79,8 @@ private static LogRecordProcessor createSimpleLogRecordProcessor( simpleModel.getExporter(), "simple log record processor exporter"); LogRecordExporter logRecordExporter = LogRecordExporterFactory.getInstance().create(exporterModel, context); - MeterProvider meterProvider = context.getMeterProvider(); - return context.addCloseable( - SimpleLogRecordProcessor.builder(logRecordExporter) - .setMeterProvider(() -> meterProvider) - .build()); + SimpleLogRecordProcessorBuilder builder = SimpleLogRecordProcessor.builder(logRecordExporter); + context.setInternalTelemetry(unused -> {}, builder::setMeterProvider); + return context.addCloseable(builder.build()); } } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LoggerProviderFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LoggerProviderFactory.java index f11b87c798e..cad9f24fcc3 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LoggerProviderFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/LoggerProviderFactory.java @@ -8,7 +8,6 @@ import static io.opentelemetry.sdk.extension.incubator.fileconfig.FileConfigUtil.requireNonNull; import io.opentelemetry.api.logs.Severity; -import io.opentelemetry.api.metrics.MeterProvider; import io.opentelemetry.sdk.common.internal.ScopeConfigurator; import io.opentelemetry.sdk.common.internal.ScopeConfiguratorBuilder; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalLoggerConfigModel; @@ -46,10 +45,7 @@ public SdkLoggerProviderBuilder create( return builder; } - MeterProvider meterProvider = context.getMeterProvider(); - if (meterProvider != null) { - builder.setMeterProvider(() -> meterProvider); - } + context.setInternalTelemetry(unused -> {}, builder::setMeterProvider); LogLimits logLimits = LogLimitsFactory.getInstance() diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactory.java index 3c0cf40c74a..1cf6a6e7021 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/SpanProcessorFactory.java @@ -5,8 +5,6 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig; -import io.opentelemetry.api.metrics.MeterProvider; -import io.opentelemetry.sdk.common.InternalTelemetryVersion; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.BatchSpanProcessorModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SimpleSpanProcessorModel; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanExporterModel; @@ -64,14 +62,7 @@ private static SpanProcessor createBatchLogRecordProcessor( if (batchModel.getScheduleDelay() != null) { builder.setScheduleDelay(Duration.ofMillis(batchModel.getScheduleDelay())); } - MeterProvider meterProvider = context.getMeterProvider(); - if (meterProvider != null) { - builder.setMeterProvider(() -> meterProvider); - } - InternalTelemetryVersion telemetryVersion = context.getInternalTelemetryVersion(); - if (telemetryVersion != null) { - builder.setInternalTelemetryVersion(telemetryVersion); - } + context.setInternalTelemetry(builder::setInternalTelemetryVersion, builder::setMeterProvider); return context.addCloseable(builder.build()); } @@ -82,10 +73,7 @@ private static SpanProcessor createSimpleLogRecordProcessor( FileConfigUtil.requireNonNull(simpleModel.getExporter(), "simple span processor exporter"); SpanExporter spanExporter = SpanExporterFactory.getInstance().create(exporterModel, context); SimpleSpanProcessorBuilder builder = SimpleSpanProcessor.builder(spanExporter); - MeterProvider meterProvider = context.getMeterProvider(); - if (meterProvider != null) { - builder.setMeterProvider(() -> meterProvider); - } + context.setInternalTelemetry(unused -> {}, builder::setMeterProvider); return context.addCloseable(builder.build()); } } diff --git a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TracerProviderFactory.java b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TracerProviderFactory.java index e2e700865c8..4dc789bfa65 100644 --- a/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TracerProviderFactory.java +++ b/sdk-extensions/incubator/src/main/java/io/opentelemetry/sdk/extension/incubator/fileconfig/TracerProviderFactory.java @@ -7,7 +7,6 @@ import static io.opentelemetry.sdk.extension.incubator.fileconfig.FileConfigUtil.requireNonNull; -import io.opentelemetry.api.metrics.MeterProvider; import io.opentelemetry.sdk.common.internal.ScopeConfigurator; import io.opentelemetry.sdk.common.internal.ScopeConfiguratorBuilder; import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalTracerConfigModel; @@ -43,10 +42,7 @@ public SdkTracerProviderBuilder create( return builder; } - MeterProvider meterProvider = context.getMeterProvider(); - if (meterProvider != null) { - builder.setMeterProvider(() -> meterProvider); - } + context.setInternalTelemetry(unused -> {}, builder::setMeterProvider); SpanLimits spanLimits = SpanLimitsFactory.getInstance() From ef41c82d56cd190472b51b80fc367c3e8edcc3d0 Mon Sep 17 00:00:00 2001 From: Jack Berg Date: Tue, 10 Feb 2026 12:39:20 -0600 Subject: [PATCH 3/3] Simplify test --- .../FullDeclarativeConfigTest.java | 113 ++++++------------ 1 file changed, 38 insertions(+), 75 deletions(-) diff --git a/sdk-extensions/autoconfigure/src/testIncubating/java/io/opentelemetry/sdk/autoconfigure/FullDeclarativeConfigTest.java b/sdk-extensions/autoconfigure/src/testIncubating/java/io/opentelemetry/sdk/autoconfigure/FullDeclarativeConfigTest.java index aebb8b0122c..ac6b7ab4aae 100644 --- a/sdk-extensions/autoconfigure/src/testIncubating/java/io/opentelemetry/sdk/autoconfigure/FullDeclarativeConfigTest.java +++ b/sdk-extensions/autoconfigure/src/testIncubating/java/io/opentelemetry/sdk/autoconfigure/FullDeclarativeConfigTest.java @@ -30,6 +30,8 @@ import io.opentelemetry.proto.collector.trace.v1.TraceServiceGrpc; import io.opentelemetry.proto.common.v1.AnyValue; import io.opentelemetry.proto.common.v1.KeyValue; +import io.opentelemetry.proto.metrics.v1.Metric; +import io.opentelemetry.proto.metrics.v1.ScopeMetrics; import io.opentelemetry.sdk.OpenTelemetrySdk; import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties; import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties; @@ -44,6 +46,7 @@ import java.util.concurrent.BlockingQueue; import java.util.concurrent.LinkedBlockingDeque; import java.util.concurrent.TimeUnit; +import java.util.stream.Collectors; import org.junit.jupiter.api.AfterEach; import org.junit.jupiter.api.BeforeEach; import org.junit.jupiter.api.Test; @@ -244,10 +247,7 @@ void configures() throws Exception { .anySatisfy( scopeMetrics -> { assertThat(scopeMetrics.getScope().getName()).isEqualTo("test"); - assertThat(scopeMetrics.getMetricsList()) - .satisfiesExactlyInAnyOrder( - metric -> - assertThat(metric.getName()).isEqualTo("my-metric")); + assertMetricNames(scopeMetrics, "my-metric"); }) // This verifies that MeterProvider was injected into OTLP exporters and // the internal telemetry version was set. @@ -256,99 +256,56 @@ void configures() throws Exception { assertThat(scopeMetrics.getScope().getName()) .isEqualTo( "io.opentelemetry.exporters.otlp_grpc_metric_exporter"); - assertThat(scopeMetrics.getMetricsList()) - .satisfiesExactlyInAnyOrder( - metric -> - assertThat(metric.getName()) - .isEqualTo( - "otel.sdk.exporter.metric_data_point.inflight"), - metric -> - assertThat(metric.getName()) - .isEqualTo( - "otel.sdk.exporter.operation.duration"), - metric -> - assertThat(metric.getName()) - .isEqualTo( - "otel.sdk.exporter.metric_data_point.exported")); + assertMetricNames( + scopeMetrics, + "otel.sdk.exporter.metric_data_point.inflight", + "otel.sdk.exporter.operation.duration", + "otel.sdk.exporter.metric_data_point.exported"); }) .anySatisfy( scopeMetrics -> { assertThat(scopeMetrics.getScope().getName()) .isEqualTo( "io.opentelemetry.exporters.otlp_grpc_log_exporter"); - assertThat(scopeMetrics.getMetricsList()) - .satisfiesExactlyInAnyOrder( - metric -> - assertThat(metric.getName()) - .isEqualTo("otel.sdk.exporter.log.inflight"), - metric -> - assertThat(metric.getName()) - .isEqualTo( - "otel.sdk.exporter.operation.duration"), - metric -> - assertThat(metric.getName()) - .isEqualTo("otel.sdk.exporter.log.exported")); + assertMetricNames( + scopeMetrics, + "otel.sdk.exporter.log.inflight", + "otel.sdk.exporter.operation.duration", + "otel.sdk.exporter.log.exported"); }) .anySatisfy( scopeMetrics -> { assertThat(scopeMetrics.getScope().getName()) .isEqualTo( "io.opentelemetry.exporters.otlp_grpc_span_exporter"); - assertThat(scopeMetrics.getMetricsList()) - .satisfiesExactlyInAnyOrder( - metric -> - assertThat(metric.getName()) - .isEqualTo("otel.sdk.exporter.span.inflight"), - metric -> - assertThat(metric.getName()) - .isEqualTo( - "otel.sdk.exporter.operation.duration"), - metric -> - assertThat(metric.getName()) - .isEqualTo("otel.sdk.exporter.span.exported")); + assertMetricNames( + scopeMetrics, + "otel.sdk.exporter.span.inflight", + "otel.sdk.exporter.operation.duration", + "otel.sdk.exporter.span.exported"); }) .anySatisfy( scopeMetrics -> { assertThat(scopeMetrics.getScope().getName()) .isEqualTo("io.opentelemetry.sdk.logs"); - assertThat(scopeMetrics.getMetricsList()) - .satisfiesExactlyInAnyOrder( - metric -> - assertThat(metric.getName()) - .isEqualTo("otel.sdk.log.created"), - metric -> - assertThat(metric.getName()) - .isEqualTo("otel.sdk.processor.log.processed"), - metric -> - assertThat(metric.getName()) - .isEqualTo( - "otel.sdk.processor.log.queue.capacity"), - metric -> - assertThat(metric.getName()) - .isEqualTo("otel.sdk.processor.log.queue.size")); + assertMetricNames( + scopeMetrics, + "otel.sdk.log.created", + "otel.sdk.processor.log.processed", + "otel.sdk.processor.log.queue.capacity", + "otel.sdk.processor.log.queue.size"); }) .anySatisfy( scopeMetrics -> { assertThat(scopeMetrics.getScope().getName()) .isEqualTo("io.opentelemetry.sdk.trace"); - assertThat(scopeMetrics.getMetricsList()) - .satisfiesExactlyInAnyOrder( - metric -> - assertThat(metric.getName()) - .isEqualTo("otel.sdk.span.live"), - metric -> - assertThat(metric.getName()) - .isEqualTo("otel.sdk.span.started"), - metric -> - assertThat(metric.getName()) - .isEqualTo("otel.sdk.processor.span.processed"), - metric -> - assertThat(metric.getName()) - .isEqualTo( - "otel.sdk.processor.span.queue.capacity"), - metric -> - assertThat(metric.getName()) - .isEqualTo("otel.sdk.processor.span.queue.size")); + assertMetricNames( + scopeMetrics, + "otel.sdk.span.live", + "otel.sdk.span.started", + "otel.sdk.processor.span.processed", + "otel.sdk.processor.span.queue.capacity", + "otel.sdk.processor.span.queue.size"); }); }); }); @@ -376,4 +333,10 @@ private static void assertHasKeyValue(List keyValues, String key, Stri .setValue(AnyValue.newBuilder().setStringValue(value)) .build()); } + + private static void assertMetricNames(ScopeMetrics scopeMetrics, String... names) { + assertThat( + scopeMetrics.getMetricsList().stream().map(Metric::getName).collect(Collectors.toSet())) + .containsExactlyInAnyOrder(names); + } }