Declarative config 0.4 (#7064)

This commit is contained in:
jack-berg 2025-04-18 14:20:38 -05:00 committed by GitHub
parent 04677f93b3
commit 9e3f702d5b
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
85 changed files with 2756 additions and 1268 deletions

View File

@ -26,7 +26,7 @@ public final class OtlpStdoutLogRecordExporterComponentProvider
@Override
public String getName() {
return "experimental-otlp/stdout";
return "otlp_file/development";
}
@Override

View File

@ -26,7 +26,7 @@ public final class OtlpStdoutMetricExporterComponentProvider
@Override
public String getName() {
return "experimental-otlp/stdout";
return "otlp_file/development";
}
@Override

View File

@ -26,7 +26,7 @@ public final class OtlpStdoutSpanExporterComponentProvider
@Override
public String getName() {
return "experimental-otlp/stdout";
return "otlp_file/development";
}
@Override

View File

@ -335,7 +335,7 @@ abstract class AbstractOtlpStdoutExporterTest<T> {
.filter(
p -> {
ComponentProvider<?> c = (ComponentProvider<?>) p;
return "experimental-otlp/stdout".equals(c.getName())
return "otlp_file/development".equals(c.getName())
&& c.getType().equals(componentProviderType);
})
.findFirst()

View File

@ -54,9 +54,8 @@ public final class OtlpDeclarativeConfigUtil {
Consumer<byte[]> setTrustedCertificates,
BiConsumer<byte[], byte[]> setClientTls,
Consumer<RetryPolicy> setRetryPolicy,
Consumer<MemoryMode> setMemoryMode) {
String protocol = getStructuredConfigOtlpProtocol(config);
boolean isHttpProtobuf = protocol.equals(PROTOCOL_HTTP_PROTOBUF);
Consumer<MemoryMode> setMemoryMode,
boolean isHttpProtobuf) {
URL endpoint = validateEndpoint(config.getString("endpoint"), isHttpProtobuf);
if (endpoint != null) {
setEndpoint.accept(endpoint.toString());
@ -92,16 +91,16 @@ public final class OtlpDeclarativeConfigUtil {
setTimeout.accept(Duration.ofMillis(timeoutMs));
}
String certificatePath = config.getString("certificate");
String clientKeyPath = config.getString("client_key");
String clientKeyChainPath = config.getString("client_certificate");
String certificatePath = config.getString("certificate_file");
String clientKeyPath = config.getString("client_key_file");
String clientKeyChainPath = config.getString("client_certificate_file");
if (clientKeyPath != null && clientKeyChainPath == null) {
throw new ConfigurationException(
"client_key provided without client_certificate - both client_key and client_certificate must be set");
"client_key_file provided without client_certificate_file - both client_key_file and client_certificate_file must be set");
} else if (clientKeyPath == null && clientKeyChainPath != null) {
throw new ConfigurationException(
"client_certificate provided without client_key - both client_key and client_certificate must be set");
"client_certificate_file provided without client_key_file - both client_key_file and client_certificate_file must be set");
}
byte[] certificateBytes = readFileBytes(certificatePath);
if (certificateBytes != null) {

View File

@ -0,0 +1,59 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.exporter.otlp.internal;
import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.DATA_TYPE_LOGS;
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.logs.export.LogRecordExporter;
/**
* Declarative configuration SPI implementation for {@link OtlpGrpcLogRecordExporter}.
*
* <p>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<LogRecordExporter> {
@Override
public Class<LogRecordExporter> getType() {
return LogRecordExporter.class;
}
@Override
public String getName() {
return "otlp_grpc";
}
@Override
public LogRecordExporter create(DeclarativeConfigProperties config) {
OtlpGrpcLogRecordExporterBuilder builder = grpcBuilder();
OtlpDeclarativeConfigUtil.configureOtlpExporterBuilder(
DATA_TYPE_LOGS,
config,
builder::setEndpoint,
builder::addHeader,
builder::setCompression,
builder::setTimeout,
builder::setTrustedCertificates,
builder::setClientTls,
builder::setRetryPolicy,
builder::setMemoryMode,
/* isHttpProtobuf= */ false);
return builder.build();
}
// Visible for testing
OtlpGrpcLogRecordExporterBuilder grpcBuilder() {
return OtlpGrpcLogRecordExporter.builder();
}
}

View File

@ -0,0 +1,63 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.exporter.otlp.internal;
import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.DATA_TYPE_METRICS;
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.metrics.export.MetricExporter;
/**
* Declarative configuration SPI implementation for {@link OtlpGrpcMetricExporter}.
*
* <p>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<MetricExporter> {
@Override
public Class<MetricExporter> getType() {
return MetricExporter.class;
}
@Override
public String getName() {
return "otlp_grpc";
}
@Override
public MetricExporter create(DeclarativeConfigProperties config) {
OtlpGrpcMetricExporterBuilder builder = grpcBuilder();
OtlpDeclarativeConfigUtil.configureOtlpExporterBuilder(
DATA_TYPE_METRICS,
config,
builder::setEndpoint,
builder::addHeader,
builder::setCompression,
builder::setTimeout,
builder::setTrustedCertificates,
builder::setClientTls,
builder::setRetryPolicy,
builder::setMemoryMode,
/* isHttpProtobuf= */ false);
IncubatingExporterBuilderUtil.configureOtlpAggregationTemporality(
config, builder::setAggregationTemporalitySelector);
IncubatingExporterBuilderUtil.configureOtlpHistogramDefaultAggregation(
config, builder::setDefaultAggregationSelector);
return builder.build();
}
// Visible for testing
OtlpGrpcMetricExporterBuilder grpcBuilder() {
return OtlpGrpcMetricExporter.builder();
}
}

View File

@ -0,0 +1,58 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.exporter.otlp.internal;
import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.DATA_TYPE_TRACES;
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.trace.export.SpanExporter;
/**
* Declarative configuration SPI implementation for {@link OtlpGrpcSpanExporter}.
*
* <p>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<SpanExporter> {
@Override
public Class<SpanExporter> getType() {
return SpanExporter.class;
}
@Override
public String getName() {
return "otlp_grpc";
}
@Override
public SpanExporter create(DeclarativeConfigProperties config) {
OtlpGrpcSpanExporterBuilder builder = grpcBuilder();
OtlpDeclarativeConfigUtil.configureOtlpExporterBuilder(
DATA_TYPE_TRACES,
config,
builder::setEndpoint,
builder::addHeader,
builder::setCompression,
builder::setTimeout,
builder::setTrustedCertificates,
builder::setClientTls,
builder::setRetryPolicy,
builder::setMemoryMode,
/* isHttpProtobuf= */ false);
return builder.build();
}
// Visible for testing
OtlpGrpcSpanExporterBuilder grpcBuilder() {
return OtlpGrpcSpanExporter.builder();
}
}

View File

@ -0,0 +1,59 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.exporter.otlp.internal;
import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.DATA_TYPE_LOGS;
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.logs.export.LogRecordExporter;
/**
* Declarative configuration SPI implementation for {@link OtlpHttpLogRecordExporter}.
*
* <p>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<LogRecordExporter> {
@Override
public Class<LogRecordExporter> getType() {
return LogRecordExporter.class;
}
@Override
public String getName() {
return "otlp_http";
}
@Override
public LogRecordExporter create(DeclarativeConfigProperties config) {
OtlpHttpLogRecordExporterBuilder builder = httpBuilder();
OtlpDeclarativeConfigUtil.configureOtlpExporterBuilder(
DATA_TYPE_LOGS,
config,
builder::setEndpoint,
builder::addHeader,
builder::setCompression,
builder::setTimeout,
builder::setTrustedCertificates,
builder::setClientTls,
builder::setRetryPolicy,
builder::setMemoryMode,
/* isHttpProtobuf= */ true);
return builder.build();
}
// Visible for testing
OtlpHttpLogRecordExporterBuilder httpBuilder() {
return OtlpHttpLogRecordExporter.builder();
}
}

View File

@ -0,0 +1,63 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.exporter.otlp.internal;
import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.DATA_TYPE_METRICS;
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.metrics.export.MetricExporter;
/**
* Declarative configuration SPI implementation for {@link OtlpHttpMetricExporter}.
*
* <p>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<MetricExporter> {
@Override
public Class<MetricExporter> getType() {
return MetricExporter.class;
}
@Override
public String getName() {
return "otlp_http";
}
@Override
public MetricExporter create(DeclarativeConfigProperties config) {
OtlpHttpMetricExporterBuilder builder = httpBuilder();
OtlpDeclarativeConfigUtil.configureOtlpExporterBuilder(
DATA_TYPE_METRICS,
config,
builder::setEndpoint,
builder::addHeader,
builder::setCompression,
builder::setTimeout,
builder::setTrustedCertificates,
builder::setClientTls,
builder::setRetryPolicy,
builder::setMemoryMode,
/* isHttpProtobuf= */ true);
IncubatingExporterBuilderUtil.configureOtlpAggregationTemporality(
config, builder::setAggregationTemporalitySelector);
IncubatingExporterBuilderUtil.configureOtlpHistogramDefaultAggregation(
config, builder::setDefaultAggregationSelector);
return builder.build();
}
// Visible for testing
OtlpHttpMetricExporterBuilder httpBuilder() {
return OtlpHttpMetricExporter.builder();
}
}

View File

@ -0,0 +1,58 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.exporter.otlp.internal;
import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.DATA_TYPE_TRACES;
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.trace.export.SpanExporter;
/**
* Declarative configuration SPI implementation for {@link OtlpHttpSpanExporter}.
*
* <p>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<SpanExporter> {
@Override
public Class<SpanExporter> getType() {
return SpanExporter.class;
}
@Override
public String getName() {
return "otlp_http";
}
@Override
public SpanExporter create(DeclarativeConfigProperties config) {
OtlpHttpSpanExporterBuilder builder = httpBuilder();
OtlpDeclarativeConfigUtil.configureOtlpExporterBuilder(
DATA_TYPE_TRACES,
config,
builder::setEndpoint,
builder::addHeader,
builder::setCompression,
builder::setTimeout,
builder::setTrustedCertificates,
builder::setClientTls,
builder::setRetryPolicy,
builder::setMemoryMode,
/* isHttpProtobuf= */ true);
return builder.build();
}
// Visible for testing
OtlpHttpSpanExporterBuilder httpBuilder() {
return OtlpHttpSpanExporter.builder();
}
}

View File

@ -1,90 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.exporter.otlp.internal;
import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.DATA_TYPE_LOGS;
import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.PROTOCOL_GRPC;
import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.PROTOCOL_HTTP_PROTOBUF;
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.exporter.otlp.logs.OtlpGrpcLogRecordExporter;
import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException;
import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider;
import io.opentelemetry.sdk.logs.export.LogRecordExporter;
/**
* Declarative configuration SPI implementation for {@link OtlpHttpLogRecordExporter} and {@link
* OtlpGrpcLogRecordExporter}.
*
* <p>This class is internal and is hence not for public use. Its APIs are unstable and can change
* at any time.
*/
public class OtlpLogRecordExporterComponentProvider
implements ComponentProvider<LogRecordExporter> {
@Override
public Class<LogRecordExporter> getType() {
return LogRecordExporter.class;
}
@Override
public String getName() {
return "otlp";
}
@Override
public LogRecordExporter create(DeclarativeConfigProperties config) {
String protocol = OtlpDeclarativeConfigUtil.getStructuredConfigOtlpProtocol(config);
if (protocol.equals(PROTOCOL_HTTP_PROTOBUF)) {
OtlpHttpLogRecordExporterBuilder builder = httpBuilder();
OtlpDeclarativeConfigUtil.configureOtlpExporterBuilder(
DATA_TYPE_LOGS,
config,
builder::setEndpoint,
builder::addHeader,
builder::setCompression,
builder::setTimeout,
builder::setTrustedCertificates,
builder::setClientTls,
builder::setRetryPolicy,
builder::setMemoryMode);
return builder.build();
} else if (protocol.equals(PROTOCOL_GRPC)) {
OtlpGrpcLogRecordExporterBuilder builder = grpcBuilder();
OtlpDeclarativeConfigUtil.configureOtlpExporterBuilder(
DATA_TYPE_LOGS,
config,
builder::setEndpoint,
builder::addHeader,
builder::setCompression,
builder::setTimeout,
builder::setTrustedCertificates,
builder::setClientTls,
builder::setRetryPolicy,
builder::setMemoryMode);
return builder.build();
}
throw new ConfigurationException("Unsupported OTLP metrics protocol: " + protocol);
}
// Visible for testing
OtlpHttpLogRecordExporterBuilder httpBuilder() {
return OtlpHttpLogRecordExporter.builder();
}
// Visible for testing
OtlpGrpcLogRecordExporterBuilder grpcBuilder() {
return OtlpGrpcLogRecordExporter.builder();
}
}

View File

@ -1,98 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.exporter.otlp.internal;
import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.DATA_TYPE_METRICS;
import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.PROTOCOL_GRPC;
import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.PROTOCOL_HTTP_PROTOBUF;
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.exporter.otlp.metrics.OtlpGrpcMetricExporter;
import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporterBuilder;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException;
import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider;
import io.opentelemetry.sdk.metrics.export.MetricExporter;
/**
* Declarative configuration SPI implementation for {@link OtlpHttpMetricExporter} and {@link
* OtlpGrpcMetricExporter}.
*
* <p>This class is internal and is hence not for public use. Its APIs are unstable and can change
* at any time.
*/
public class OtlpMetricExporterComponentProvider implements ComponentProvider<MetricExporter> {
@Override
public Class<MetricExporter> getType() {
return MetricExporter.class;
}
@Override
public String getName() {
return "otlp";
}
@Override
public MetricExporter create(DeclarativeConfigProperties config) {
String protocol = OtlpDeclarativeConfigUtil.getStructuredConfigOtlpProtocol(config);
if (protocol.equals(PROTOCOL_HTTP_PROTOBUF)) {
OtlpHttpMetricExporterBuilder builder = httpBuilder();
OtlpDeclarativeConfigUtil.configureOtlpExporterBuilder(
DATA_TYPE_METRICS,
config,
builder::setEndpoint,
builder::addHeader,
builder::setCompression,
builder::setTimeout,
builder::setTrustedCertificates,
builder::setClientTls,
builder::setRetryPolicy,
builder::setMemoryMode);
IncubatingExporterBuilderUtil.configureOtlpAggregationTemporality(
config, builder::setAggregationTemporalitySelector);
IncubatingExporterBuilderUtil.configureOtlpHistogramDefaultAggregation(
config, builder::setDefaultAggregationSelector);
return builder.build();
} else if (protocol.equals(PROTOCOL_GRPC)) {
OtlpGrpcMetricExporterBuilder builder = grpcBuilder();
OtlpDeclarativeConfigUtil.configureOtlpExporterBuilder(
DATA_TYPE_METRICS,
config,
builder::setEndpoint,
builder::addHeader,
builder::setCompression,
builder::setTimeout,
builder::setTrustedCertificates,
builder::setClientTls,
builder::setRetryPolicy,
builder::setMemoryMode);
IncubatingExporterBuilderUtil.configureOtlpAggregationTemporality(
config, builder::setAggregationTemporalitySelector);
IncubatingExporterBuilderUtil.configureOtlpHistogramDefaultAggregation(
config, builder::setDefaultAggregationSelector);
return builder.build();
}
throw new ConfigurationException("Unsupported OTLP metrics protocol: " + protocol);
}
// Visible for testing
OtlpHttpMetricExporterBuilder httpBuilder() {
return OtlpHttpMetricExporter.builder();
}
// Visible for testing
OtlpGrpcMetricExporterBuilder grpcBuilder() {
return OtlpGrpcMetricExporter.builder();
}
}

View File

@ -1,89 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.exporter.otlp.internal;
import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.DATA_TYPE_TRACES;
import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.PROTOCOL_GRPC;
import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.PROTOCOL_HTTP_PROTOBUF;
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.exporter.otlp.trace.OtlpGrpcSpanExporter;
import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException;
import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider;
import io.opentelemetry.sdk.trace.export.SpanExporter;
/**
* Declarative configuration SPI implementation for {@link OtlpHttpSpanExporter} and {@link
* OtlpGrpcSpanExporter}.
*
* <p>This class is internal and is hence not for public use. Its APIs are unstable and can change
* at any time.
*/
public class OtlpSpanExporterComponentProvider implements ComponentProvider<SpanExporter> {
@Override
public Class<SpanExporter> getType() {
return SpanExporter.class;
}
@Override
public String getName() {
return "otlp";
}
@Override
public SpanExporter create(DeclarativeConfigProperties config) {
String protocol = OtlpDeclarativeConfigUtil.getStructuredConfigOtlpProtocol(config);
if (protocol.equals(PROTOCOL_HTTP_PROTOBUF)) {
OtlpHttpSpanExporterBuilder builder = httpBuilder();
OtlpDeclarativeConfigUtil.configureOtlpExporterBuilder(
DATA_TYPE_TRACES,
config,
builder::setEndpoint,
builder::addHeader,
builder::setCompression,
builder::setTimeout,
builder::setTrustedCertificates,
builder::setClientTls,
builder::setRetryPolicy,
builder::setMemoryMode);
return builder.build();
} else if (protocol.equals(PROTOCOL_GRPC)) {
OtlpGrpcSpanExporterBuilder builder = grpcBuilder();
OtlpDeclarativeConfigUtil.configureOtlpExporterBuilder(
DATA_TYPE_TRACES,
config,
builder::setEndpoint,
builder::addHeader,
builder::setCompression,
builder::setTimeout,
builder::setTrustedCertificates,
builder::setClientTls,
builder::setRetryPolicy,
builder::setMemoryMode);
return builder.build();
}
throw new ConfigurationException("Unsupported OTLP metrics protocol: " + protocol);
}
// Visible for testing
OtlpHttpSpanExporterBuilder httpBuilder() {
return OtlpHttpSpanExporter.builder();
}
// Visible for testing
OtlpGrpcSpanExporterBuilder grpcBuilder() {
return OtlpGrpcSpanExporter.builder();
}
}

View File

@ -1,3 +1,6 @@
io.opentelemetry.exporter.otlp.internal.OtlpMetricExporterComponentProvider
io.opentelemetry.exporter.otlp.internal.OtlpSpanExporterComponentProvider
io.opentelemetry.exporter.otlp.internal.OtlpLogRecordExporterComponentProvider
io.opentelemetry.exporter.otlp.internal.OtlpHttpMetricExporterComponentProvider
io.opentelemetry.exporter.otlp.internal.OtlpHttpSpanExporterComponentProvider
io.opentelemetry.exporter.otlp.internal.OtlpHttpLogRecordExporterComponentProvider
io.opentelemetry.exporter.otlp.internal.OtlpGrpcMetricExporterComponentProvider
io.opentelemetry.exporter.otlp.internal.OtlpGrpcSpanExporterComponentProvider
io.opentelemetry.exporter.otlp.internal.OtlpGrpcLogRecordExporterComponentProvider

View File

@ -23,7 +23,7 @@ class DeclarativeConfigurationTest {
@Test
void configFile(@TempDir Path tempDir) throws IOException {
String yaml =
"file_format: \"0.3\"\n"
"file_format: \"0.4\"\n"
+ "resource:\n"
+ " attributes:\n"
+ " - name: service.name\n"

View File

@ -62,7 +62,7 @@ class DeclarativeConfigurationTest {
@BeforeEach
void setup() throws IOException {
String yaml =
"file_format: \"0.3\"\n"
"file_format: \"0.4\"\n"
+ "resource:\n"
+ " attributes:\n"
+ " - name: service.name\n"
@ -199,7 +199,7 @@ class DeclarativeConfigurationTest {
@Test
void configFile_Error(@TempDir Path tempDir) throws IOException {
String yaml =
"file_format: \"0.3\"\n"
"file_format: \"0.4\"\n"
+ "resource:\n"
+ " attributes:\n"
+ " - name: service.name\n"

View File

@ -34,6 +34,7 @@ dependencies {
testImplementation(project(":sdk:testing"))
testImplementation(project(":sdk-extensions:autoconfigure"))
testImplementation(project(":exporters:logging"))
testImplementation(project(":exporters:logging-otlp"))
testImplementation(project(":exporters:otlp:all"))
testImplementation(project(":exporters:prometheus"))
testImplementation(project(":exporters:zipkin"))
@ -56,11 +57,8 @@ dependencies {
// 7. deleteJs2pTmp - delete tmp directory
// ... proceed with normal sourcesJar, compileJava, etc
// TODO (trask) revert after the 0.4.0 release
// it was needed after 0.3.0 release because file_format in the examples weren't updated prior to the release tag
// val configurationTag = "0.3.0"
// val configurationRef = "refs/tags/v$configurationTag" // Replace with commit SHA to point to experiment with a specific commit
val configurationRef = "cea3905ce0a542d573968c3c47d413143d473cf4"
val configurationTag = "0.4.0"
val configurationRef = "refs/tags/v$configurationTag" // Replace with commit SHA to point to experiment with a specific commit
val configurationRepoZip = "https://github.com/open-telemetry/opentelemetry-configuration/archive/$configurationRef.zip"
val buildDirectory = layout.buildDirectory.asFile.get()

View File

@ -8,8 +8,8 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig;
import io.opentelemetry.api.incubator.config.DeclarativeConfigException;
import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AggregationModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Base2ExponentialBucketHistogramModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExplicitBucketHistogramModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Base2ExponentialBucketHistogramAggregationModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExplicitBucketHistogramAggregationModel;
import io.opentelemetry.sdk.metrics.Aggregation;
import java.io.Closeable;
import java.util.List;
@ -36,7 +36,7 @@ final class AggregationFactory implements Factory<AggregationModel, Aggregation>
if (model.getLastValue() != null) {
return Aggregation.lastValue();
}
Base2ExponentialBucketHistogramModel exponentialBucketHistogram =
Base2ExponentialBucketHistogramAggregationModel exponentialBucketHistogram =
model.getBase2ExponentialBucketHistogram();
if (exponentialBucketHistogram != null) {
Integer maxScale = exponentialBucketHistogram.getMaxScale();
@ -53,7 +53,8 @@ final class AggregationFactory implements Factory<AggregationModel, Aggregation>
throw new DeclarativeConfigException("Invalid exponential bucket histogram", e);
}
}
ExplicitBucketHistogramModel explicitBucketHistogram = model.getExplicitBucketHistogram();
ExplicitBucketHistogramAggregationModel explicitBucketHistogram =
model.getExplicitBucketHistogram();
if (explicitBucketHistogram != null) {
List<Double> boundaries = explicitBucketHistogram.getBoundaries();
if (boundaries == null) {

View File

@ -43,9 +43,9 @@ final class AttributeListFactory implements Factory<List<AttributeNameValueModel
AttributeNameValueModel nameValueModel, AttributesBuilder builder) {
String name = FileConfigUtil.requireNonNull(nameValueModel.getName(), "attribute name");
Object value = FileConfigUtil.requireNonNull(nameValueModel.getValue(), "attribute value");
AttributeNameValueModel.Type type = nameValueModel.getType();
AttributeNameValueModel.AttributeType type = nameValueModel.getType();
if (type == null) {
type = AttributeNameValueModel.Type.STRING;
type = AttributeNameValueModel.AttributeType.STRING;
}
switch (type) {
case STRING:

View File

@ -0,0 +1,64 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.sdk.extension.incubator.fileconfig;
import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.CardinalityLimitsModel;
import io.opentelemetry.sdk.metrics.export.CardinalityLimitSelector;
import io.opentelemetry.sdk.metrics.internal.state.MetricStorage;
import java.io.Closeable;
import java.util.List;
import javax.annotation.Nullable;
final class CardinalityLimitsFactory
implements Factory<CardinalityLimitsModel, CardinalityLimitSelector> {
private static final CardinalityLimitsFactory INSTANCE = new CardinalityLimitsFactory();
private CardinalityLimitsFactory() {}
static CardinalityLimitsFactory getInstance() {
return INSTANCE;
}
@Override
public CardinalityLimitSelector create(
CardinalityLimitsModel model, SpiHelper spiHelper, List<Closeable> closeables) {
int defaultLimit = getOrDefault(model.getDefault(), MetricStorage.DEFAULT_MAX_CARDINALITY);
int counterLimit = getOrDefault(model.getCounter(), defaultLimit);
int gaugeLimit = getOrDefault(model.getGauge(), defaultLimit);
int histogramLimit = getOrDefault(model.getHistogram(), defaultLimit);
int observableCounterLimit = getOrDefault(model.getObservableCounter(), defaultLimit);
int observableGaugeLimit = getOrDefault(model.getObservableGauge(), defaultLimit);
int observableUpDownCounterLimit =
getOrDefault(model.getObservableUpDownCounter(), defaultLimit);
int upDownCounterLimit = getOrDefault(model.getUpDownCounter(), defaultLimit);
return instrumentType -> {
switch (instrumentType) {
case COUNTER:
return counterLimit;
case UP_DOWN_COUNTER:
return upDownCounterLimit;
case HISTOGRAM:
return histogramLimit;
case OBSERVABLE_COUNTER:
return observableCounterLimit;
case OBSERVABLE_UP_DOWN_COUNTER:
return observableUpDownCounterLimit;
case OBSERVABLE_GAUGE:
return observableGaugeLimit;
case GAUGE:
return gaugeLimit;
}
return defaultLimit;
};
}
private static int getOrDefault(@Nullable Integer value, int defaultValue) {
return value == null ? defaultValue : value;
}
}

View File

@ -5,12 +5,15 @@
package io.opentelemetry.sdk.extension.incubator.fileconfig;
import static java.util.stream.Collectors.joining;
import io.opentelemetry.api.incubator.config.DeclarativeConfigException;
import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties;
import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper;
import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider;
import java.io.Closeable;
import java.util.List;
import java.util.Map;
import java.util.function.Function;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
@ -103,4 +106,24 @@ final class FileConfigUtil {
"Error configuring " + type.getName() + " with name \"" + name + "\"", throwable);
}
}
static Map.Entry<String, Object> getSingletonMapEntry(
Map<String, Object> additionalProperties, String resourceName) {
if (additionalProperties.isEmpty()) {
throw new DeclarativeConfigException(resourceName + " must be set");
}
if (additionalProperties.size() > 1) {
throw new DeclarativeConfigException(
"Invalid configuration - multiple "
+ resourceName
+ "s set: "
+ additionalProperties.keySet().stream().collect(joining(",", "[", "]")));
}
return additionalProperties.entrySet().stream()
.findFirst()
.orElseThrow(
() ->
new IllegalStateException(
"Missing " + resourceName + ". This is a programming error."));
}
}

View File

@ -7,14 +7,14 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig;
import io.opentelemetry.api.incubator.config.DeclarativeConfigException;
import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SelectorModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ViewSelectorModel;
import io.opentelemetry.sdk.metrics.InstrumentSelector;
import io.opentelemetry.sdk.metrics.InstrumentSelectorBuilder;
import io.opentelemetry.sdk.metrics.InstrumentType;
import java.io.Closeable;
import java.util.List;
final class InstrumentSelectorFactory implements Factory<SelectorModel, InstrumentSelector> {
final class InstrumentSelectorFactory implements Factory<ViewSelectorModel, InstrumentSelector> {
private static final InstrumentSelectorFactory INSTANCE = new InstrumentSelectorFactory();
@ -26,7 +26,7 @@ final class InstrumentSelectorFactory implements Factory<SelectorModel, Instrume
@Override
public InstrumentSelector create(
SelectorModel model, SpiHelper spiHelper, List<Closeable> closeables) {
ViewSelectorModel model, SpiHelper spiHelper, List<Closeable> closeables) {
InstrumentSelectorBuilder builder = InstrumentSelector.builder();
if (model.getInstrumentName() != null) {
builder.setName(model.getInstrumentName());

View File

@ -5,13 +5,8 @@
package io.opentelemetry.sdk.extension.incubator.fileconfig;
import static java.util.stream.Collectors.joining;
import io.opentelemetry.api.incubator.config.DeclarativeConfigException;
import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ConsoleModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordExporterModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpModel;
import io.opentelemetry.sdk.logs.export.LogRecordExporter;
import java.io.Closeable;
import java.util.List;
@ -30,38 +25,19 @@ final class LogRecordExporterFactory implements Factory<LogRecordExporterModel,
@Override
public LogRecordExporter create(
LogRecordExporterModel model, SpiHelper spiHelper, List<Closeable> closeables) {
OtlpModel otlpModel = model.getOtlp();
if (otlpModel != null) {
model.getAdditionalProperties().put("otlp", otlpModel);
}
ConsoleModel consoleModel = model.getConsole();
if (consoleModel != null) {
model.getAdditionalProperties().put("console", consoleModel);
}
model.getAdditionalProperties().compute("otlp_http", (k, v) -> model.getOtlpHttp());
model.getAdditionalProperties().compute("otlp_grpc", (k, v) -> model.getOtlpGrpc());
model
.getAdditionalProperties()
.compute("otlp_file/development", (k, v) -> model.getOtlpFileDevelopment());
model.getAdditionalProperties().compute("console", (k, v) -> model.getConsole());
if (!model.getAdditionalProperties().isEmpty()) {
Map<String, Object> additionalProperties = model.getAdditionalProperties();
if (additionalProperties.size() > 1) {
throw new DeclarativeConfigException(
"Invalid configuration - multiple log record exporters set: "
+ additionalProperties.keySet().stream().collect(joining(",", "[", "]")));
}
Map.Entry<String, Object> exporterKeyValue =
additionalProperties.entrySet().stream()
.findFirst()
.orElseThrow(
() ->
new IllegalStateException("Missing exporter. This is a programming error."));
LogRecordExporter logRecordExporter =
FileConfigUtil.loadComponent(
spiHelper,
LogRecordExporter.class,
exporterKeyValue.getKey(),
exporterKeyValue.getValue());
return FileConfigUtil.addAndReturn(closeables, logRecordExporter);
} else {
throw new DeclarativeConfigException("log exporter must be set");
}
Map.Entry<String, Object> keyValue =
FileConfigUtil.getSingletonMapEntry(model.getAdditionalProperties(), "log record exporter");
LogRecordExporter logRecordExporter =
FileConfigUtil.loadComponent(
spiHelper, LogRecordExporter.class, keyValue.getKey(), keyValue.getValue());
return FileConfigUtil.addAndReturn(closeables, logRecordExporter);
}
}

View File

@ -5,9 +5,6 @@
package io.opentelemetry.sdk.extension.incubator.fileconfig;
import static java.util.stream.Collectors.joining;
import io.opentelemetry.api.incubator.config.DeclarativeConfigException;
import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.BatchLogRecordProcessorModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordExporterModel;
@ -72,28 +69,12 @@ final class LogRecordProcessorFactory
closeables, SimpleLogRecordProcessor.create(logRecordExporter));
}
if (!model.getAdditionalProperties().isEmpty()) {
Map<String, Object> additionalProperties = model.getAdditionalProperties();
if (additionalProperties.size() > 1) {
throw new DeclarativeConfigException(
"Invalid configuration - multiple log record processors set: "
+ additionalProperties.keySet().stream().collect(joining(",", "[", "]")));
}
Map.Entry<String, Object> processorKeyValue =
additionalProperties.entrySet().stream()
.findFirst()
.orElseThrow(
() ->
new IllegalStateException("Missing processor. This is a programming error."));
LogRecordProcessor logRecordProcessor =
FileConfigUtil.loadComponent(
spiHelper,
LogRecordProcessor.class,
processorKeyValue.getKey(),
processorKeyValue.getValue());
return FileConfigUtil.addAndReturn(closeables, logRecordProcessor);
} else {
throw new DeclarativeConfigException("log processor must be set");
}
Map.Entry<String, Object> keyValue =
FileConfigUtil.getSingletonMapEntry(
model.getAdditionalProperties(), "log record processor");
LogRecordProcessor logRecordProcessor =
FileConfigUtil.loadComponent(
spiHelper, LogRecordProcessor.class, keyValue.getKey(), keyValue.getValue());
return FileConfigUtil.addAndReturn(closeables, logRecordProcessor);
}
}

View File

@ -5,12 +5,21 @@
package io.opentelemetry.sdk.extension.incubator.fileconfig;
import static io.opentelemetry.sdk.extension.incubator.fileconfig.FileConfigUtil.requireNonNull;
import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalLoggerConfigModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalLoggerConfiguratorModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalLoggerMatcherAndConfigModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordProcessorModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LoggerProviderModel;
import io.opentelemetry.sdk.internal.ScopeConfigurator;
import io.opentelemetry.sdk.internal.ScopeConfiguratorBuilder;
import io.opentelemetry.sdk.logs.LogLimits;
import io.opentelemetry.sdk.logs.SdkLoggerProvider;
import io.opentelemetry.sdk.logs.SdkLoggerProviderBuilder;
import io.opentelemetry.sdk.logs.internal.LoggerConfig;
import io.opentelemetry.sdk.logs.internal.SdkLoggerProviderUtil;
import java.io.Closeable;
import java.util.List;
@ -53,6 +62,50 @@ final class LoggerProviderFactory
.create(processor, spiHelper, closeables)));
}
ExperimentalLoggerConfiguratorModel loggerConfiguratorModel =
loggerProviderModel.getLoggerConfiguratorDevelopment();
if (loggerConfiguratorModel != null) {
ExperimentalLoggerConfigModel defaultConfigModel = loggerConfiguratorModel.getDefaultConfig();
ScopeConfiguratorBuilder<LoggerConfig> configuratorBuilder = ScopeConfigurator.builder();
if (defaultConfigModel != null) {
configuratorBuilder.setDefault(
LoggerConfigFactory.INSTANCE.create(defaultConfigModel, spiHelper, closeables));
}
List<ExperimentalLoggerMatcherAndConfigModel> loggerMatcherAndConfigs =
loggerConfiguratorModel.getLoggers();
if (loggerMatcherAndConfigs != null) {
for (ExperimentalLoggerMatcherAndConfigModel loggerMatcherAndConfig :
loggerMatcherAndConfigs) {
String name = requireNonNull(loggerMatcherAndConfig.getName(), "logger matcher name");
ExperimentalLoggerConfigModel config = loggerMatcherAndConfig.getConfig();
if (name == null || config == null) {
continue;
}
configuratorBuilder.addCondition(
ScopeConfiguratorBuilder.nameMatchesGlob(name),
LoggerProviderFactory.LoggerConfigFactory.INSTANCE.create(
config, spiHelper, closeables));
}
}
SdkLoggerProviderUtil.setLoggerConfigurator(builder, configuratorBuilder.build());
}
return builder;
}
private static class LoggerConfigFactory
implements Factory<ExperimentalLoggerConfigModel, LoggerConfig> {
private static final LoggerProviderFactory.LoggerConfigFactory INSTANCE =
new LoggerProviderFactory.LoggerConfigFactory();
@Override
public LoggerConfig create(
ExperimentalLoggerConfigModel model, SpiHelper spiHelper, List<Closeable> closeables) {
if (model.getDisabled() != null && model.getDisabled()) {
return LoggerConfig.disabled();
}
return LoggerConfig.defaultConfig();
}
}
}

View File

@ -8,14 +8,21 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig;
import static io.opentelemetry.sdk.extension.incubator.fileconfig.FileConfigUtil.requireNonNull;
import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalMeterConfigModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalMeterConfiguratorModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalMeterMatcherAndConfigModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MeterProviderModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricReaderModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SelectorModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.StreamModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ViewModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ViewSelectorModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ViewStreamModel;
import io.opentelemetry.sdk.internal.ScopeConfigurator;
import io.opentelemetry.sdk.internal.ScopeConfiguratorBuilder;
import io.opentelemetry.sdk.metrics.SdkMeterProvider;
import io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder;
import io.opentelemetry.sdk.metrics.export.MetricReader;
import io.opentelemetry.sdk.metrics.export.CardinalityLimitSelector;
import io.opentelemetry.sdk.metrics.internal.MeterConfig;
import io.opentelemetry.sdk.metrics.internal.SdkMeterProviderUtil;
import java.io.Closeable;
import java.util.List;
@ -38,10 +45,15 @@ final class MeterProviderFactory implements Factory<MeterProviderModel, SdkMeter
if (readerModels != null) {
readerModels.forEach(
readerModel -> {
MetricReader metricReader =
MetricReaderAndCardinalityLimits readerAndCardinalityLimits =
MetricReaderFactory.getInstance().create(readerModel, spiHelper, closeables);
if (metricReader != null) {
builder.registerMetricReader(metricReader);
CardinalityLimitSelector cardinalityLimits =
readerAndCardinalityLimits.getCardinalityLimitsSelector();
if (cardinalityLimits == null) {
builder.registerMetricReader(readerAndCardinalityLimits.getMetricReader());
} else {
builder.registerMetricReader(
readerAndCardinalityLimits.getMetricReader(), cardinalityLimits);
}
});
}
@ -50,14 +62,56 @@ final class MeterProviderFactory implements Factory<MeterProviderModel, SdkMeter
if (viewModels != null) {
viewModels.forEach(
viewModel -> {
SelectorModel selector = requireNonNull(viewModel.getSelector(), "view selector");
StreamModel stream = requireNonNull(viewModel.getStream(), "view stream");
ViewSelectorModel selector = requireNonNull(viewModel.getSelector(), "view selector");
ViewStreamModel stream = requireNonNull(viewModel.getStream(), "view stream");
builder.registerView(
InstrumentSelectorFactory.getInstance().create(selector, spiHelper, closeables),
ViewFactory.getInstance().create(stream, spiHelper, closeables));
});
}
ExperimentalMeterConfiguratorModel meterConfiguratorModel =
model.getMeterConfiguratorDevelopment();
if (meterConfiguratorModel != null) {
ExperimentalMeterConfigModel defaultConfigModel = meterConfiguratorModel.getDefaultConfig();
ScopeConfiguratorBuilder<MeterConfig> configuratorBuilder = ScopeConfigurator.builder();
if (defaultConfigModel != null) {
configuratorBuilder.setDefault(
MeterConfigFactory.INSTANCE.create(defaultConfigModel, spiHelper, closeables));
}
List<ExperimentalMeterMatcherAndConfigModel> meterMatcherAndConfigs =
meterConfiguratorModel.getMeters();
if (meterMatcherAndConfigs != null) {
for (ExperimentalMeterMatcherAndConfigModel meterMatcherAndConfig :
meterMatcherAndConfigs) {
String name = requireNonNull(meterMatcherAndConfig.getName(), "meter matcher name");
ExperimentalMeterConfigModel config = meterMatcherAndConfig.getConfig();
if (name == null || config == null) {
continue;
}
configuratorBuilder.addCondition(
ScopeConfiguratorBuilder.nameMatchesGlob(name),
MeterConfigFactory.INSTANCE.create(config, spiHelper, closeables));
}
}
SdkMeterProviderUtil.setMeterConfigurator(builder, configuratorBuilder.build());
}
return builder;
}
private static class MeterConfigFactory
implements Factory<ExperimentalMeterConfigModel, MeterConfig> {
private static final MeterConfigFactory INSTANCE = new MeterConfigFactory();
@Override
public MeterConfig create(
ExperimentalMeterConfigModel model, SpiHelper spiHelper, List<Closeable> closeables) {
if (model.getDisabled() != null && model.getDisabled()) {
return MeterConfig.disabled();
}
return MeterConfig.defaultConfig();
}
}
}

View File

@ -5,11 +5,7 @@
package io.opentelemetry.sdk.extension.incubator.fileconfig;
import static java.util.stream.Collectors.joining;
import io.opentelemetry.api.incubator.config.DeclarativeConfigException;
import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpMetricModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PushMetricExporterModel;
import io.opentelemetry.sdk.metrics.export.MetricExporter;
import java.io.Closeable;
@ -29,37 +25,19 @@ final class MetricExporterFactory implements Factory<PushMetricExporterModel, Me
@Override
public MetricExporter create(
PushMetricExporterModel model, SpiHelper spiHelper, List<Closeable> closeables) {
OtlpMetricModel otlpModel = model.getOtlp();
if (otlpModel != null) {
model.getAdditionalProperties().put("otlp", otlpModel);
}
if (model.getConsole() != null) {
model.getAdditionalProperties().put("console", model.getConsole());
}
model.getAdditionalProperties().compute("otlp_http", (k, v) -> model.getOtlpHttp());
model.getAdditionalProperties().compute("otlp_grpc", (k, v) -> model.getOtlpGrpc());
model
.getAdditionalProperties()
.compute("otlp_file/development", (k, v) -> model.getOtlpFileDevelopment());
model.getAdditionalProperties().compute("console", (k, v) -> model.getConsole());
if (!model.getAdditionalProperties().isEmpty()) {
Map<String, Object> additionalProperties = model.getAdditionalProperties();
if (additionalProperties.size() > 1) {
throw new DeclarativeConfigException(
"Invalid configuration - multiple metric exporters set: "
+ additionalProperties.keySet().stream().collect(joining(",", "[", "]")));
}
Map.Entry<String, Object> exporterKeyValue =
additionalProperties.entrySet().stream()
.findFirst()
.orElseThrow(
() ->
new IllegalStateException("Missing exporter. This is a programming error."));
MetricExporter metricExporter =
FileConfigUtil.loadComponent(
spiHelper,
MetricExporter.class,
exporterKeyValue.getKey(),
exporterKeyValue.getValue());
return FileConfigUtil.addAndReturn(closeables, metricExporter);
} else {
throw new DeclarativeConfigException("metric exporter must be set");
}
Map.Entry<String, Object> keyValue =
FileConfigUtil.getSingletonMapEntry(model.getAdditionalProperties(), "metric exporter");
MetricExporter metricExporter =
FileConfigUtil.loadComponent(
spiHelper, MetricExporter.class, keyValue.getKey(), keyValue.getValue());
return FileConfigUtil.addAndReturn(closeables, metricExporter);
}
}

View File

@ -0,0 +1,25 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.sdk.extension.incubator.fileconfig;
import com.google.auto.value.AutoValue;
import io.opentelemetry.sdk.metrics.export.CardinalityLimitSelector;
import io.opentelemetry.sdk.metrics.export.MetricReader;
import javax.annotation.Nullable;
@AutoValue
abstract class MetricReaderAndCardinalityLimits {
static MetricReaderAndCardinalityLimits create(
MetricReader metricReader, @Nullable CardinalityLimitSelector cardinalityLimitSelector) {
return new AutoValue_MetricReaderAndCardinalityLimits(metricReader, cardinalityLimitSelector);
}
abstract MetricReader getMetricReader();
@Nullable
abstract CardinalityLimitSelector getCardinalityLimitsSelector();
}

View File

@ -9,12 +9,13 @@ import static io.opentelemetry.sdk.extension.incubator.fileconfig.FileConfigUtil
import io.opentelemetry.api.incubator.config.DeclarativeConfigException;
import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalPrometheusMetricExporterModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricReaderModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PeriodicMetricReaderModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PrometheusModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PullMetricExporterModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PullMetricReaderModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PushMetricExporterModel;
import io.opentelemetry.sdk.metrics.export.CardinalityLimitSelector;
import io.opentelemetry.sdk.metrics.export.MetricExporter;
import io.opentelemetry.sdk.metrics.export.MetricReader;
import io.opentelemetry.sdk.metrics.export.PeriodicMetricReader;
@ -23,7 +24,8 @@ import java.io.Closeable;
import java.time.Duration;
import java.util.List;
final class MetricReaderFactory implements Factory<MetricReaderModel, MetricReader> {
final class MetricReaderFactory
implements Factory<MetricReaderModel, MetricReaderAndCardinalityLimits> {
private static final MetricReaderFactory INSTANCE = new MetricReaderFactory();
@ -34,38 +36,89 @@ final class MetricReaderFactory implements Factory<MetricReaderModel, MetricRead
}
@Override
public MetricReader create(
public MetricReaderAndCardinalityLimits create(
MetricReaderModel model, SpiHelper spiHelper, List<Closeable> closeables) {
PeriodicMetricReaderModel periodicModel = model.getPeriodic();
if (periodicModel != null) {
PushMetricExporterModel exporterModel =
requireNonNull(periodicModel.getExporter(), "periodic metric reader exporter");
MetricExporter metricExporter =
MetricExporterFactory.getInstance().create(exporterModel, spiHelper, closeables);
PeriodicMetricReaderBuilder builder =
PeriodicMetricReader.builder(FileConfigUtil.addAndReturn(closeables, metricExporter));
if (periodicModel.getInterval() != null) {
builder.setInterval(Duration.ofMillis(periodicModel.getInterval()));
}
return FileConfigUtil.addAndReturn(closeables, builder.build());
return PeriodicMetricReaderFactory.INSTANCE.create(periodicModel, spiHelper, closeables);
}
PullMetricReaderModel pullModel = model.getPull();
if (pullModel != null) {
return PullMetricReaderFactory.INSTANCE.create(pullModel, spiHelper, closeables);
}
throw new DeclarativeConfigException("reader must be set");
}
private static class PeriodicMetricReaderFactory
implements Factory<PeriodicMetricReaderModel, MetricReaderAndCardinalityLimits> {
private static final PeriodicMetricReaderFactory INSTANCE = new PeriodicMetricReaderFactory();
private PeriodicMetricReaderFactory() {}
@Override
public MetricReaderAndCardinalityLimits create(
PeriodicMetricReaderModel model, SpiHelper spiHelper, List<Closeable> closeables) {
PushMetricExporterModel exporterModel =
requireNonNull(model.getExporter(), "periodic metric reader exporter");
MetricExporter metricExporter =
MetricExporterFactory.getInstance().create(exporterModel, spiHelper, closeables);
PeriodicMetricReaderBuilder builder =
PeriodicMetricReader.builder(FileConfigUtil.addAndReturn(closeables, metricExporter));
if (model.getInterval() != null) {
builder.setInterval(Duration.ofMillis(model.getInterval()));
}
CardinalityLimitSelector cardinalityLimitSelector = null;
if (model.getCardinalityLimits() != null) {
cardinalityLimitSelector =
CardinalityLimitsFactory.getInstance()
.create(model.getCardinalityLimits(), spiHelper, closeables);
}
MetricReaderAndCardinalityLimits readerAndCardinalityLimits =
MetricReaderAndCardinalityLimits.create(builder.build(), cardinalityLimitSelector);
return FileConfigUtil.addAndReturn(closeables, readerAndCardinalityLimits);
}
}
private static class PullMetricReaderFactory
implements Factory<PullMetricReaderModel, MetricReaderAndCardinalityLimits> {
private static final PullMetricReaderFactory INSTANCE = new PullMetricReaderFactory();
private PullMetricReaderFactory() {}
@Override
public MetricReaderAndCardinalityLimits create(
PullMetricReaderModel model, SpiHelper spiHelper, List<Closeable> closeables) {
PullMetricExporterModel exporterModel =
requireNonNull(pullModel.getExporter(), "pull metric reader exporter");
PrometheusModel prometheusModel = exporterModel.getPrometheus();
requireNonNull(model.getExporter(), "pull metric reader exporter");
ExperimentalPrometheusMetricExporterModel prometheusModel =
exporterModel.getPrometheusDevelopment();
if (prometheusModel != null) {
MetricReader metricReader =
FileConfigUtil.loadComponent(
spiHelper, MetricReader.class, "prometheus", prometheusModel);
return FileConfigUtil.addAndReturn(closeables, metricReader);
CardinalityLimitSelector cardinalityLimitSelector = null;
if (model.getCardinalityLimits() != null) {
cardinalityLimitSelector =
CardinalityLimitsFactory.getInstance()
.create(model.getCardinalityLimits(), spiHelper, closeables);
}
MetricReaderAndCardinalityLimits readerAndCardinalityLimits =
MetricReaderAndCardinalityLimits.create(metricReader, cardinalityLimitSelector);
return FileConfigUtil.addAndReturn(closeables, readerAndCardinalityLimits);
}
throw new DeclarativeConfigException(
"prometheus is the only currently supported pull reader");
}
throw new DeclarativeConfigException("reader must be set");
}
}

View File

@ -18,6 +18,8 @@ import java.util.Objects;
final class OpenTelemetryConfigurationFactory
implements Factory<OpenTelemetryConfigurationModel, OpenTelemetrySdk> {
private static final String CURRENT_SUPPORTED_FILE_FORMAT = "0.4";
private static final OpenTelemetryConfigurationFactory INSTANCE =
new OpenTelemetryConfigurationFactory();
@ -31,9 +33,9 @@ final class OpenTelemetryConfigurationFactory
public OpenTelemetrySdk create(
OpenTelemetryConfigurationModel model, SpiHelper spiHelper, List<Closeable> closeables) {
OpenTelemetrySdkBuilder builder = OpenTelemetrySdk.builder();
if (!"0.3".equals(model.getFileFormat())) {
if (!CURRENT_SUPPORTED_FILE_FORMAT.equals(model.getFileFormat())) {
throw new DeclarativeConfigException(
"Unsupported file format. Supported formats include: 0.3");
"Unsupported file format. Supported formats include: " + CURRENT_SUPPORTED_FILE_FORMAT);
}
if (Objects.equals(Boolean.TRUE, model.getDisabled())) {

View File

@ -5,14 +5,18 @@
package io.opentelemetry.sdk.extension.incubator.fileconfig;
import static io.opentelemetry.sdk.extension.incubator.fileconfig.FileConfigUtil.requireNonNull;
import io.opentelemetry.context.propagation.ContextPropagators;
import io.opentelemetry.context.propagation.TextMapPropagator;
import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PropagatorModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.TextMapPropagatorModel;
import java.io.Closeable;
import java.util.ArrayList;
import java.util.HashSet;
import java.util.List;
import java.util.Set;
import java.util.stream.Collectors;
import java.util.stream.Stream;
final class PropagatorFactory implements Factory<PropagatorModel, ContextPropagators> {
@ -27,9 +31,40 @@ final class PropagatorFactory implements Factory<PropagatorModel, ContextPropaga
@Override
public ContextPropagators create(
PropagatorModel model, SpiHelper spiHelper, List<Closeable> closeables) {
List<String> compositeModel = requireNonNull(model.getComposite(), "composite propagator");
TextMapPropagator textMapPropagator =
TextMapPropagatorFactory.getInstance().create(compositeModel, spiHelper, closeables);
return ContextPropagators.create(textMapPropagator);
List<TextMapPropagatorModel> textMapPropagatorModels = model.getComposite();
Set<String> propagatorNames = new HashSet<>();
List<TextMapPropagator> textMapPropagators = new ArrayList<>();
if (textMapPropagatorModels != null) {
textMapPropagatorModels.forEach(
textMapPropagatorModel -> {
TextMapPropagatorAndName propagatorAndName =
TextMapPropagatorFactory.getInstance()
.create(textMapPropagatorModel, spiHelper, closeables);
textMapPropagators.add(propagatorAndName.getTextMapPropagator());
propagatorNames.add(propagatorAndName.getName());
});
}
String compositeList = model.getCompositeList();
if (compositeList != null) {
List<String> propagatorNamesList =
// Process string list same as we process OTEL_PROPAGATORS, trimming and filtering empty
// and 'none'
Stream.of(compositeList.split(","))
.map(String::trim)
.filter(s -> !s.isEmpty())
.filter(s -> !s.equals("none"))
.collect(Collectors.toList());
for (String propagatorName : propagatorNamesList) {
// Only add entries which weren't already previously added
if (propagatorNames.add(propagatorName)) {
textMapPropagators.add(
TextMapPropagatorFactory.getPropagator(spiHelper, propagatorName)
.getTextMapPropagator());
}
}
}
return ContextPropagators.create(TextMapPropagator.composite(textMapPropagators));
}
}

View File

@ -0,0 +1,34 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.sdk.extension.incubator.fileconfig;
import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalResourceDetectorModel;
import io.opentelemetry.sdk.resources.Resource;
import java.io.Closeable;
import java.util.List;
import java.util.Map;
final class ResourceDetectorFactory
implements Factory<ExperimentalResourceDetectorModel, Resource> {
private static final ResourceDetectorFactory INSTANCE = new ResourceDetectorFactory();
private ResourceDetectorFactory() {}
static ResourceDetectorFactory getInstance() {
return INSTANCE;
}
@Override
public Resource create(
ExperimentalResourceDetectorModel model, SpiHelper spiHelper, List<Closeable> closeables) {
Map.Entry<String, Object> keyValue =
FileConfigUtil.getSingletonMapEntry(model.getAdditionalProperties(), "resource detector");
return FileConfigUtil.loadComponent(
spiHelper, Resource.class, keyValue.getKey(), keyValue.getValue());
}
}

View File

@ -5,28 +5,23 @@
package io.opentelemetry.sdk.extension.incubator.fileconfig;
import static io.opentelemetry.sdk.internal.GlobUtil.toGlobPatternPredicate;
import static io.opentelemetry.sdk.internal.GlobUtil.createGlobPatternPredicate;
import io.opentelemetry.api.incubator.config.DeclarativeConfigException;
import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.sdk.autoconfigure.ResourceConfiguration;
import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper;
import io.opentelemetry.sdk.autoconfigure.spi.Ordered;
import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider;
import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributeNameValueModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.DetectorAttributesModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.DetectorsModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalResourceDetectionModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalResourceDetectorModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.IncludeExcludeModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ResourceModel;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.resources.ResourceBuilder;
import java.io.Closeable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.Comparator;
import java.util.List;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
final class ResourceFactory implements Factory<ResourceModel, Resource> {
@ -43,18 +38,27 @@ final class ResourceFactory implements Factory<ResourceModel, Resource> {
public Resource create(ResourceModel model, SpiHelper spiHelper, List<Closeable> closeables) {
ResourceBuilder builder = Resource.getDefault().toBuilder();
ResourceBuilder detectedResourceBuilder = Resource.builder();
List<Resource> resourceDetectorResources = loadFromResourceDetectors(spiHelper);
for (Resource resourceProviderResource : resourceDetectorResources) {
detectedResourceBuilder.putAll(resourceProviderResource);
ExperimentalResourceDetectionModel detectionModel = model.getDetectionDevelopment();
if (detectionModel != null) {
ResourceBuilder detectedResourceBuilder = Resource.builder();
List<ExperimentalResourceDetectorModel> detectorModels = detectionModel.getDetectors();
if (detectorModels != null) {
for (ExperimentalResourceDetectorModel detectorModel : detectorModels) {
detectedResourceBuilder.putAll(
ResourceDetectorFactory.getInstance().create(detectorModel, spiHelper, closeables));
}
}
Predicate<String> detectorAttributeFilter =
detectorAttributeFilter(detectionModel.getAttributes());
Attributes filteredDetectedAttributes =
detectedResourceBuilder.build().getAttributes().toBuilder()
.removeIf(attributeKey -> !detectorAttributeFilter.test(attributeKey.getKey()))
.build();
builder.putAll(filteredDetectedAttributes);
}
Predicate<String> detectorAttributeFilter = detectorAttributeFilter(model.getDetectors());
builder
.putAll(
detectedResourceBuilder.build().getAttributes().toBuilder()
.removeIf(attributeKey -> !detectorAttributeFilter.test(attributeKey.getKey()))
.build())
.build();
String attributeList = model.getAttributesList();
if (attributeList != null) {
@ -76,77 +80,17 @@ final class ResourceFactory implements Factory<ResourceModel, Resource> {
return builder.build();
}
/**
* Load resources from resource detectors, in order of lowest priority to highest priority.
*
* <p>In declarative configuration, a resource detector is a {@link ComponentProvider} with {@link
* ComponentProvider#getType()} set to {@link Resource}. Unlike other {@link ComponentProvider}s,
* the resource detector version does not use {@link ComponentProvider#getName()} (except for
* debug messages), and {@link ComponentProvider#create(DeclarativeConfigProperties)} is called
* with an empty instance. Additionally, the {@link Ordered#order()} value is respected for
* resource detectors which implement {@link Ordered}.
*/
@SuppressWarnings("rawtypes")
private static List<Resource> loadFromResourceDetectors(SpiHelper spiHelper) {
List<ComponentProvider> componentProviders = spiHelper.load(ComponentProvider.class);
List<ResourceAndOrder> resourceAndOrders = new ArrayList<>();
for (ComponentProvider<?> componentProvider : componentProviders) {
if (componentProvider.getType() != Resource.class) {
continue;
}
Resource resource;
try {
resource = (Resource) componentProvider.create(DeclarativeConfigProperties.empty());
} catch (Throwable throwable) {
throw new DeclarativeConfigException(
"Error configuring "
+ Resource.class.getName()
+ " with name \""
+ componentProvider.getName()
+ "\"",
throwable);
}
int order =
(componentProvider instanceof Ordered) ? ((Ordered) componentProvider).order() : 0;
resourceAndOrders.add(new ResourceAndOrder(resource, order));
}
resourceAndOrders.sort(Comparator.comparing(ResourceAndOrder::order));
return resourceAndOrders.stream().map(ResourceAndOrder::resource).collect(Collectors.toList());
}
private static final class ResourceAndOrder {
private final Resource resource;
private final int order;
private ResourceAndOrder(Resource resource, int order) {
this.resource = resource;
this.order = order;
}
private Resource resource() {
return resource;
}
private int order() {
return order;
}
}
private static boolean matchAll(String attributeKey) {
return true;
}
private static Predicate<String> detectorAttributeFilter(
@Nullable DetectorsModel detectorsModel) {
if (detectorsModel == null) {
@Nullable IncludeExcludeModel includedExcludeModel) {
if (includedExcludeModel == null) {
return ResourceFactory::matchAll;
}
DetectorAttributesModel detectorAttributesModel = detectorsModel.getAttributes();
if (detectorAttributesModel == null) {
return ResourceFactory::matchAll;
}
List<String> included = detectorAttributesModel.getIncluded();
List<String> excluded = detectorAttributesModel.getExcluded();
List<String> included = includedExcludeModel.getIncluded();
List<String> excluded = includedExcludeModel.getExcluded();
if (included == null && excluded == null) {
return ResourceFactory::matchAll;
}
@ -165,7 +109,7 @@ final class ResourceFactory implements Factory<ResourceModel, Resource> {
private static Predicate<String> includedPredicate(List<String> included) {
Predicate<String> result = attributeKey -> false;
for (String include : included) {
result = result.or(toGlobPatternPredicate(include));
result = result.or(createGlobPatternPredicate(include));
}
return result;
}
@ -177,7 +121,7 @@ final class ResourceFactory implements Factory<ResourceModel, Resource> {
private static Predicate<String> excludedPredicate(List<String> excluded) {
Predicate<String> result = attributeKey -> true;
for (String exclude : excluded) {
result = result.and(toGlobPatternPredicate(exclude).negate());
result = result.and(createGlobPatternPredicate(exclude).negate());
}
return result;
}

View File

@ -5,14 +5,10 @@
package io.opentelemetry.sdk.extension.incubator.fileconfig;
import static java.util.stream.Collectors.joining;
import io.opentelemetry.api.incubator.config.DeclarativeConfigException;
import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.JaegerRemoteModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ParentBasedModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ParentBasedSamplerModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SamplerModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.TraceIdRatioBasedModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.TraceIdRatioBasedSamplerModel;
import io.opentelemetry.sdk.trace.samplers.ParentBasedSamplerBuilder;
import io.opentelemetry.sdk.trace.samplers.Sampler;
import java.io.Closeable;
@ -37,7 +33,7 @@ final class SamplerFactory implements Factory<SamplerModel, Sampler> {
if (model.getAlwaysOff() != null) {
return Sampler.alwaysOff();
}
TraceIdRatioBasedModel traceIdRatioBasedModel = model.getTraceIdRatioBased();
TraceIdRatioBasedSamplerModel traceIdRatioBasedModel = model.getTraceIdRatioBased();
if (traceIdRatioBasedModel != null) {
Double ratio = traceIdRatioBasedModel.getRatio();
if (ratio == null) {
@ -45,7 +41,7 @@ final class SamplerFactory implements Factory<SamplerModel, Sampler> {
}
return Sampler.traceIdRatioBased(ratio);
}
ParentBasedModel parentBasedModel = model.getParentBased();
ParentBasedSamplerModel parentBasedModel = model.getParentBased();
if (parentBasedModel != null) {
Sampler root =
parentBasedModel.getRoot() == null
@ -73,29 +69,13 @@ final class SamplerFactory implements Factory<SamplerModel, Sampler> {
return builder.build();
}
JaegerRemoteModel jaegerRemoteModel = model.getJaegerRemote();
if (jaegerRemoteModel != null) {
model.getAdditionalProperties().put("jaeger_remote", jaegerRemoteModel);
}
model.getAdditionalProperties().compute("jaeger_remote", (k, v) -> model.getJaegerRemote());
if (!model.getAdditionalProperties().isEmpty()) {
Map<String, Object> additionalProperties = model.getAdditionalProperties();
if (additionalProperties.size() > 1) {
throw new DeclarativeConfigException(
"Invalid configuration - multiple samplers exporters set: "
+ additionalProperties.keySet().stream().collect(joining(",", "[", "]")));
}
Map.Entry<String, Object> exporterKeyValue =
additionalProperties.entrySet().stream()
.findFirst()
.orElseThrow(
() -> new IllegalStateException("Missing sampler. This is a programming error."));
Sampler sampler =
FileConfigUtil.loadComponent(
spiHelper, Sampler.class, exporterKeyValue.getKey(), exporterKeyValue.getValue());
return FileConfigUtil.addAndReturn(closeables, sampler);
} else {
throw new DeclarativeConfigException("sampler must be set");
}
Map.Entry<String, Object> keyValue =
FileConfigUtil.getSingletonMapEntry(model.getAdditionalProperties(), "sampler");
Sampler sampler =
FileConfigUtil.loadComponent(
spiHelper, Sampler.class, keyValue.getKey(), keyValue.getValue());
return FileConfigUtil.addAndReturn(closeables, sampler);
}
}

View File

@ -5,13 +5,8 @@
package io.opentelemetry.sdk.extension.incubator.fileconfig;
import static java.util.stream.Collectors.joining;
import io.opentelemetry.api.incubator.config.DeclarativeConfigException;
import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanExporterModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ZipkinModel;
import io.opentelemetry.sdk.trace.export.SpanExporter;
import java.io.Closeable;
import java.util.List;
@ -30,42 +25,20 @@ final class SpanExporterFactory implements Factory<SpanExporterModel, SpanExport
@Override
public SpanExporter create(
SpanExporterModel model, SpiHelper spiHelper, List<Closeable> closeables) {
OtlpModel otlpModel = model.getOtlp();
if (otlpModel != null) {
model.getAdditionalProperties().put("otlp", otlpModel);
}
if (model.getConsole() != null) {
model.getAdditionalProperties().put("console", model.getConsole());
}
model.getAdditionalProperties().compute("otlp_http", (k, v) -> model.getOtlpHttp());
model.getAdditionalProperties().compute("otlp_grpc", (k, v) -> model.getOtlpGrpc());
model
.getAdditionalProperties()
.compute("otlp_file/development", (k, v) -> model.getOtlpFileDevelopment());
model.getAdditionalProperties().compute("console", (k, v) -> model.getConsole());
model.getAdditionalProperties().compute("zipkin", (k, v) -> model.getZipkin());
ZipkinModel zipkinModel = model.getZipkin();
if (zipkinModel != null) {
model.getAdditionalProperties().put("zipkin", model.getZipkin());
}
if (!model.getAdditionalProperties().isEmpty()) {
Map<String, Object> additionalProperties = model.getAdditionalProperties();
if (additionalProperties.size() > 1) {
throw new DeclarativeConfigException(
"Invalid configuration - multiple span exporters set: "
+ additionalProperties.keySet().stream().collect(joining(",", "[", "]")));
}
Map.Entry<String, Object> exporterKeyValue =
additionalProperties.entrySet().stream()
.findFirst()
.orElseThrow(
() ->
new IllegalStateException("Missing exporter. This is a programming error."));
SpanExporter spanExporter =
FileConfigUtil.loadComponent(
spiHelper,
SpanExporter.class,
exporterKeyValue.getKey(),
exporterKeyValue.getValue());
return FileConfigUtil.addAndReturn(closeables, spanExporter);
} else {
throw new DeclarativeConfigException("span exporter must be set");
}
Map.Entry<String, Object> keyValue =
FileConfigUtil.getSingletonMapEntry(model.getAdditionalProperties(), "span exporter");
SpanExporter metricExporter =
FileConfigUtil.loadComponent(
spiHelper, SpanExporter.class, keyValue.getKey(), keyValue.getValue());
return FileConfigUtil.addAndReturn(closeables, metricExporter);
}
}

View File

@ -5,9 +5,6 @@
package io.opentelemetry.sdk.extension.incubator.fileconfig;
import static java.util.stream.Collectors.joining;
import io.opentelemetry.api.incubator.config.DeclarativeConfigException;
import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.BatchSpanProcessorModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SimpleSpanProcessorModel;
@ -68,28 +65,11 @@ final class SpanProcessorFactory implements Factory<SpanProcessorModel, SpanProc
return FileConfigUtil.addAndReturn(closeables, SimpleSpanProcessor.create(spanExporter));
}
if (!model.getAdditionalProperties().isEmpty()) {
Map<String, Object> additionalProperties = model.getAdditionalProperties();
if (additionalProperties.size() > 1) {
throw new DeclarativeConfigException(
"Invalid configuration - multiple span processors set: "
+ additionalProperties.keySet().stream().collect(joining(",", "[", "]")));
}
Map.Entry<String, Object> processorKeyValue =
additionalProperties.entrySet().stream()
.findFirst()
.orElseThrow(
() ->
new IllegalStateException("Missing processor. This is a programming error."));
SpanProcessor spanProcessor =
FileConfigUtil.loadComponent(
spiHelper,
SpanProcessor.class,
processorKeyValue.getKey(),
processorKeyValue.getValue());
return FileConfigUtil.addAndReturn(closeables, spanProcessor);
} else {
throw new DeclarativeConfigException("span processor must be set");
}
Map.Entry<String, Object> keyValue =
FileConfigUtil.getSingletonMapEntry(model.getAdditionalProperties(), "span processor");
SpanProcessor spanProcessor =
FileConfigUtil.loadComponent(
spiHelper, SpanProcessor.class, keyValue.getKey(), keyValue.getValue());
return FileConfigUtil.addAndReturn(closeables, spanProcessor);
}
}

View File

@ -0,0 +1,21 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.sdk.extension.incubator.fileconfig;
import com.google.auto.value.AutoValue;
import io.opentelemetry.context.propagation.TextMapPropagator;
@AutoValue
abstract class TextMapPropagatorAndName {
static TextMapPropagatorAndName create(TextMapPropagator textMapPropagator, String name) {
return new AutoValue_TextMapPropagatorAndName(textMapPropagator, name);
}
abstract TextMapPropagator getTextMapPropagator();
abstract String getName();
}

View File

@ -6,17 +6,17 @@
package io.opentelemetry.sdk.extension.incubator.fileconfig;
import io.opentelemetry.api.baggage.propagation.W3CBaggagePropagator;
import io.opentelemetry.api.incubator.config.DeclarativeConfigException;
import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator;
import io.opentelemetry.context.propagation.TextMapPropagator;
import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.TextMapPropagatorModel;
import java.io.Closeable;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Map;
final class TextMapPropagatorFactory implements Factory<List<String>, TextMapPropagator> {
final class TextMapPropagatorFactory
implements Factory<TextMapPropagatorModel, TextMapPropagatorAndName> {
private static final TextMapPropagatorFactory INSTANCE = new TextMapPropagatorFactory();
@ -27,37 +27,46 @@ final class TextMapPropagatorFactory implements Factory<List<String>, TextMapPro
}
@Override
public TextMapPropagator create(
List<String> model, SpiHelper spiHelper, List<Closeable> closeables) {
if (model.isEmpty()) {
model = Arrays.asList("tracecontext", "baggage");
public TextMapPropagatorAndName create(
TextMapPropagatorModel model, SpiHelper spiHelper, List<Closeable> closeables) {
if (model.getTracecontext() != null) {
return getPropagator(spiHelper, "tracecontext");
}
if (model.getBaggage() != null) {
return getPropagator(spiHelper, "baggage");
}
if (model.getB3() != null) {
return getPropagator(spiHelper, "b3");
}
if (model.getB3multi() != null) {
return getPropagator(spiHelper, "b3multi");
}
if (model.getJaeger() != null) {
return getPropagator(spiHelper, "jaeger");
}
if (model.getOttrace() != null) {
return getPropagator(spiHelper, "ottrace");
}
if (model.contains("none")) {
if (model.size() > 1) {
throw new DeclarativeConfigException(
"propagators contains \"none\" along with other propagators");
}
return TextMapPropagator.noop();
}
List<TextMapPropagator> propagators = new ArrayList<>();
for (String propagator : model) {
propagators.add(getPropagator(spiHelper, propagator));
}
return TextMapPropagator.composite(propagators);
Map.Entry<String, Object> keyValue =
FileConfigUtil.getSingletonMapEntry(model.getAdditionalProperties(), "propagator");
TextMapPropagator propagator =
FileConfigUtil.loadComponent(
spiHelper, TextMapPropagator.class, keyValue.getKey(), keyValue.getValue());
return TextMapPropagatorAndName.create(propagator, keyValue.getKey());
}
private static TextMapPropagator getPropagator(SpiHelper spiHelper, String name) {
static TextMapPropagatorAndName getPropagator(SpiHelper spiHelper, String name) {
TextMapPropagator textMapPropagator;
if (name.equals("tracecontext")) {
return W3CTraceContextPropagator.getInstance();
textMapPropagator = W3CTraceContextPropagator.getInstance();
} else if (name.equals("baggage")) {
textMapPropagator = W3CBaggagePropagator.getInstance();
} else {
textMapPropagator =
FileConfigUtil.loadComponent(
spiHelper, TextMapPropagator.class, name, Collections.emptyMap());
}
if (name.equals("baggage")) {
return W3CBaggagePropagator.getInstance();
}
return FileConfigUtil.loadComponent(
spiHelper, TextMapPropagator.class, name, Collections.emptyMap());
return TextMapPropagatorAndName.create(textMapPropagator, name);
}
}

View File

@ -5,12 +5,21 @@
package io.opentelemetry.sdk.extension.incubator.fileconfig;
import static io.opentelemetry.sdk.extension.incubator.fileconfig.FileConfigUtil.requireNonNull;
import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalTracerConfigModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalTracerConfiguratorModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalTracerMatcherAndConfigModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanProcessorModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.TracerProviderModel;
import io.opentelemetry.sdk.internal.ScopeConfigurator;
import io.opentelemetry.sdk.internal.ScopeConfiguratorBuilder;
import io.opentelemetry.sdk.trace.SdkTracerProvider;
import io.opentelemetry.sdk.trace.SdkTracerProviderBuilder;
import io.opentelemetry.sdk.trace.SpanLimits;
import io.opentelemetry.sdk.trace.internal.SdkTracerProviderUtil;
import io.opentelemetry.sdk.trace.internal.TracerConfig;
import io.opentelemetry.sdk.trace.samplers.Sampler;
import java.io.Closeable;
import java.util.List;
@ -59,6 +68,48 @@ final class TracerProviderFactory
SpanProcessorFactory.getInstance().create(processor, spiHelper, closeables)));
}
ExperimentalTracerConfiguratorModel tracerConfiguratorModel =
tracerProviderModel.getTracerConfiguratorDevelopment();
if (tracerConfiguratorModel != null) {
ExperimentalTracerConfigModel defaultConfigModel = tracerConfiguratorModel.getDefaultConfig();
ScopeConfiguratorBuilder<TracerConfig> configuratorBuilder = ScopeConfigurator.builder();
if (defaultConfigModel != null) {
configuratorBuilder.setDefault(
TracerConfigFactory.INSTANCE.create(defaultConfigModel, spiHelper, closeables));
}
List<ExperimentalTracerMatcherAndConfigModel> tracerMatcherAndConfigs =
tracerConfiguratorModel.getTracers();
if (tracerMatcherAndConfigs != null) {
for (ExperimentalTracerMatcherAndConfigModel tracerMatcherAndConfig :
tracerMatcherAndConfigs) {
String name = requireNonNull(tracerMatcherAndConfig.getName(), "tracer matcher name");
ExperimentalTracerConfigModel config = tracerMatcherAndConfig.getConfig();
if (name == null || config == null) {
continue;
}
configuratorBuilder.addCondition(
ScopeConfiguratorBuilder.nameMatchesGlob(name),
TracerConfigFactory.INSTANCE.create(config, spiHelper, closeables));
}
}
SdkTracerProviderUtil.setTracerConfigurator(builder, configuratorBuilder.build());
}
return builder;
}
private static class TracerConfigFactory
implements Factory<ExperimentalTracerConfigModel, TracerConfig> {
private static final TracerConfigFactory INSTANCE = new TracerConfigFactory();
@Override
public TracerConfig create(
ExperimentalTracerConfigModel model, SpiHelper spiHelper, List<Closeable> closeables) {
if (model.getDisabled() != null && model.getDisabled()) {
return TracerConfig.disabled();
}
return TracerConfig.defaultConfig();
}
}
}

View File

@ -7,7 +7,7 @@ package io.opentelemetry.sdk.extension.incubator.fileconfig;
import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.IncludeExcludeModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.StreamModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ViewStreamModel;
import io.opentelemetry.sdk.metrics.View;
import io.opentelemetry.sdk.metrics.ViewBuilder;
import java.io.Closeable;
@ -16,7 +16,7 @@ import java.util.List;
import java.util.Set;
import javax.annotation.Nullable;
final class ViewFactory implements Factory<StreamModel, View> {
final class ViewFactory implements Factory<ViewStreamModel, View> {
private static final ViewFactory INSTANCE = new ViewFactory();
@ -27,7 +27,7 @@ final class ViewFactory implements Factory<StreamModel, View> {
}
@Override
public View create(StreamModel model, SpiHelper spiHelper, List<Closeable> closeables) {
public View create(ViewStreamModel model, SpiHelper spiHelper, List<Closeable> closeables) {
ViewBuilder builder = View.builder();
if (model.getName() != null) {
builder.setName(model.getName());
@ -43,6 +43,9 @@ final class ViewFactory implements Factory<StreamModel, View> {
builder.setAggregation(
AggregationFactory.getInstance().create(model.getAggregation(), spiHelper, closeables));
}
if (model.getAggregationCardinalityLimit() != null) {
builder.setCardinalityLimit(model.getAggregationCardinalityLimit());
}
return builder.build();
}

View File

@ -10,11 +10,11 @@ import static org.mockito.Mockito.mock;
import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AggregationModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Base2ExponentialBucketHistogramModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.DropModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExplicitBucketHistogramModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LastValueModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SumModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Base2ExponentialBucketHistogramAggregationModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.DropAggregationModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExplicitBucketHistogramAggregationModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LastValueAggregationModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SumAggregationModel;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.stream.Stream;
@ -37,32 +37,36 @@ class AggregationFactoryTest {
Arguments.of(
new AggregationModel(), io.opentelemetry.sdk.metrics.Aggregation.defaultAggregation()),
Arguments.of(
new AggregationModel().withDrop(new DropModel()),
new AggregationModel().withDrop(new DropAggregationModel()),
io.opentelemetry.sdk.metrics.Aggregation.drop()),
Arguments.of(
new AggregationModel().withSum(new SumModel()),
new AggregationModel().withSum(new SumAggregationModel()),
io.opentelemetry.sdk.metrics.Aggregation.sum()),
Arguments.of(
new AggregationModel().withLastValue(new LastValueModel()),
new AggregationModel().withLastValue(new LastValueAggregationModel()),
io.opentelemetry.sdk.metrics.Aggregation.lastValue()),
Arguments.of(
new AggregationModel()
.withBase2ExponentialBucketHistogram(new Base2ExponentialBucketHistogramModel()),
.withBase2ExponentialBucketHistogram(
new Base2ExponentialBucketHistogramAggregationModel()),
io.opentelemetry.sdk.metrics.Aggregation.base2ExponentialBucketHistogram()),
Arguments.of(
new AggregationModel()
.withBase2ExponentialBucketHistogram(
new Base2ExponentialBucketHistogramModel().withMaxSize(2).withMaxScale(2)),
new Base2ExponentialBucketHistogramAggregationModel()
.withMaxSize(2)
.withMaxScale(2)),
io.opentelemetry.sdk.metrics.Aggregation.base2ExponentialBucketHistogram(2, 2)),
Arguments.of(
new AggregationModel()
.withExplicitBucketHistogram(
new ExplicitBucketHistogramModel().withBoundaries(null)),
new ExplicitBucketHistogramAggregationModel().withBoundaries(null)),
io.opentelemetry.sdk.metrics.Aggregation.explicitBucketHistogram()),
Arguments.of(
new AggregationModel()
.withExplicitBucketHistogram(
new ExplicitBucketHistogramModel().withBoundaries(Arrays.asList(1.0, 2.0))),
new ExplicitBucketHistogramAggregationModel()
.withBoundaries(Arrays.asList(1.0, 2.0))),
io.opentelemetry.sdk.metrics.Aggregation.explicitBucketHistogram(
Arrays.asList(1.0, 2.0))));
}

View File

@ -48,14 +48,14 @@ class AttributeListFactoryTest {
Collections.singletonList(
new AttributeNameValueModel()
.withName("key")
.withType(AttributeNameValueModel.Type.INT)
.withType(AttributeNameValueModel.AttributeType.INT)
.withValue(Arrays.asList(1L, 1))),
"Error processing attribute with name \"key\": value did not match type INT"),
Arguments.of(
Collections.singletonList(
new AttributeNameValueModel()
.withName("key")
.withType(AttributeNameValueModel.Type.INT)
.withType(AttributeNameValueModel.AttributeType.INT)
.withValue(true)),
"Error processing attribute with name \"key\": value did not match type INT"));
}
@ -88,51 +88,51 @@ class AttributeListFactoryTest {
new AttributeNameValueModel()
.withName("strKey")
.withValue("val")
.withType(AttributeNameValueModel.Type.STRING),
.withType(AttributeNameValueModel.AttributeType.STRING),
new AttributeNameValueModel()
.withName("longKey")
.withValue(1L)
.withType(AttributeNameValueModel.Type.INT),
.withType(AttributeNameValueModel.AttributeType.INT),
new AttributeNameValueModel()
.withName("intKey")
.withValue(2)
.withType(AttributeNameValueModel.Type.INT),
.withType(AttributeNameValueModel.AttributeType.INT),
new AttributeNameValueModel()
.withName("doubleKey")
.withValue(1.0d)
.withType(AttributeNameValueModel.Type.DOUBLE),
.withType(AttributeNameValueModel.AttributeType.DOUBLE),
new AttributeNameValueModel()
.withName("floatKey")
.withValue(2.0f)
.withType(AttributeNameValueModel.Type.DOUBLE),
.withType(AttributeNameValueModel.AttributeType.DOUBLE),
new AttributeNameValueModel()
.withName("boolKey")
.withValue(true)
.withType(AttributeNameValueModel.Type.BOOL),
.withType(AttributeNameValueModel.AttributeType.BOOL),
new AttributeNameValueModel()
.withName("strArrKey")
.withValue(Arrays.asList("val1", "val2"))
.withType(AttributeNameValueModel.Type.STRING_ARRAY),
.withType(AttributeNameValueModel.AttributeType.STRING_ARRAY),
new AttributeNameValueModel()
.withName("longArrKey")
.withValue(Arrays.asList(1L, 2L))
.withType(AttributeNameValueModel.Type.INT_ARRAY),
.withType(AttributeNameValueModel.AttributeType.INT_ARRAY),
new AttributeNameValueModel()
.withName("intArrKey")
.withValue(Arrays.asList(1, 2))
.withType(AttributeNameValueModel.Type.INT_ARRAY),
.withType(AttributeNameValueModel.AttributeType.INT_ARRAY),
new AttributeNameValueModel()
.withName("doubleArrKey")
.withValue(Arrays.asList(1.0d, 2.0d))
.withType(AttributeNameValueModel.Type.DOUBLE_ARRAY),
.withType(AttributeNameValueModel.AttributeType.DOUBLE_ARRAY),
new AttributeNameValueModel()
.withName("floatArrKey")
.withValue(Arrays.asList(1.0f, 2.0f))
.withType(AttributeNameValueModel.Type.DOUBLE_ARRAY),
.withType(AttributeNameValueModel.AttributeType.DOUBLE_ARRAY),
new AttributeNameValueModel()
.withName("boolArrKey")
.withValue(Arrays.asList(true, false))
.withType(AttributeNameValueModel.Type.BOOL_ARRAY)),
.withType(AttributeNameValueModel.AttributeType.BOOL_ARRAY)),
mock(SpiHelper.class),
Collections.emptyList()))
.isEqualTo(expectedAttributes);

View File

@ -0,0 +1,81 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.sdk.extension.incubator.fileconfig;
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat;
import static org.mockito.Mockito.mock;
import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.CardinalityLimitsModel;
import io.opentelemetry.sdk.metrics.InstrumentType;
import io.opentelemetry.sdk.metrics.export.CardinalityLimitSelector;
import java.util.ArrayList;
import java.util.stream.Stream;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
class CardinalityLimitsFactoryTest {
@ParameterizedTest
@MethodSource("createTestCases")
void create(CardinalityLimitsModel model, CardinalityLimitSelector expectedResult) {
CardinalityLimitSelector cardinalityLimitSelector =
CardinalityLimitsFactory.getInstance()
.create(model, mock(SpiHelper.class), new ArrayList<>());
for (InstrumentType instrumentType : InstrumentType.values()) {
assertThat(cardinalityLimitSelector.getCardinalityLimit(instrumentType))
.describedAs(instrumentType.toString())
.isEqualTo(expectedResult.getCardinalityLimit(instrumentType));
}
}
private static Stream<Arguments> createTestCases() {
return Stream.of(
Arguments.of(
new CardinalityLimitsModel(),
CardinalityLimitSelector.defaultCardinalityLimitSelector()),
Arguments.of(
new CardinalityLimitsModel().withDefault(10).withCounter(1),
(CardinalityLimitSelector)
instrumentType -> {
if (instrumentType == InstrumentType.COUNTER) {
return 1;
}
return 10;
}),
Arguments.of(
new CardinalityLimitsModel()
.withCounter(1)
.withUpDownCounter(2)
.withHistogram(3)
.withObservableCounter(4)
.withObservableUpDownCounter(5)
.withObservableGauge(6)
.withGauge(7),
(CardinalityLimitSelector)
instrumentType -> {
switch (instrumentType) {
case COUNTER:
return 1;
case UP_DOWN_COUNTER:
return 2;
case HISTOGRAM:
return 3;
case OBSERVABLE_COUNTER:
return 4;
case OBSERVABLE_UP_DOWN_COUNTER:
return 5;
case OBSERVABLE_GAUGE:
return 6;
case GAUGE:
return 7;
}
return 2000;
}));
}
}

View File

@ -70,31 +70,24 @@ class DeclarativeConfigurationCreateTest {
assertThat(examplesDir).isDirectory();
for (File example : Objects.requireNonNull(examplesDir.listFiles())) {
// Skip anchors.yaml because support for merge (i.e. "<<: *anchor") was explicitly removed in
// snakeyaml-engine:
// https://bitbucket.org/snakeyaml/snakeyaml-engine/issues/18/merge-tag-support
// As discussed in this issue merge is supported in snakeyaml:
// https://bitbucket.org/snakeyaml/snakeyaml-engine/issues/14/read-in-yaml-with-merge-then-dump-strips
// TODO(jack-berg): decide if we should try to support anchors, or remove anchors example from
// opentelemetry-configuration
if (example.getName().equals("anchors.yaml")) {
continue;
}
// Rewrite references to cert files in examples
String exampleContent =
new String(Files.readAllBytes(example.toPath()), StandardCharsets.UTF_8);
String rewrittenExampleContent =
exampleContent
.replaceAll(
"certificate: .*\n",
"certificate: " + certificatePath.replace("\\", "\\\\") + System.lineSeparator())
"certificate_file: .*\n",
"certificate_file: "
+ certificatePath.replace("\\", "\\\\")
+ System.lineSeparator())
.replaceAll(
"client_key: .*\n",
"client_key: " + clientKeyPath.replace("\\", "\\\\") + System.lineSeparator())
"client_key_file: .*\n",
"client_key_file: "
+ clientKeyPath.replace("\\", "\\\\")
+ System.lineSeparator())
.replaceAll(
"client_certificate: .*\n",
"client_certificate: "
"client_certificate_file: .*\n",
"client_certificate_file: "
+ clientCertificatePath.replace("\\", "\\\\")
+ System.lineSeparator());
InputStream is =
@ -113,12 +106,12 @@ class DeclarativeConfigurationCreateTest {
// exporter with OTLP exporter, following by invalid batch exporter which references invalid
// exporter "foo".
String yaml =
"file_format: \"0.3\"\n"
"file_format: \"0.4\"\n"
+ "logger_provider:\n"
+ " processors:\n"
+ " - batch:\n"
+ " exporter:\n"
+ " otlp: {}\n"
+ " otlp_http: {}\n"
+ " - batch:\n"
+ " exporter:\n"
+ " foo: {}\n";
@ -140,7 +133,7 @@ class DeclarativeConfigurationCreateTest {
@Test
void parseAndCreate_EmptyComponentProviderConfig() {
String yaml =
"file_format: \"0.3\"\n"
"file_format: \"0.4\"\n"
+ "logger_provider:\n"
+ " processors:\n"
+ " - test:\n"
@ -158,7 +151,7 @@ class DeclarativeConfigurationCreateTest {
@Test
void create_ModelCustomizer() {
OpenTelemetryConfigurationModel model = new OpenTelemetryConfigurationModel();
model.withFileFormat("0.3");
model.withFileFormat("0.4");
model.withTracerProvider(
new TracerProviderModel()
.withProcessors(
@ -175,9 +168,7 @@ class DeclarativeConfigurationCreateTest {
"resource=Resource{schemaUrl=null, attributes={"
+ "color=\"blue\", "
+ "foo=\"bar\", "
+ "order=\"second\", "
+ "service.name=\"unknown_service:java\", "
+ "shape=\"square\", "
+ "telemetry.sdk.language=\"java\", "
+ "telemetry.sdk.name=\"opentelemetry\", "
+ "telemetry.sdk.version=\"");

View File

@ -10,22 +10,40 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy;
import io.opentelemetry.api.incubator.config.DeclarativeConfigException;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AggregationModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AlwaysOffModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AlwaysOnModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AlwaysOffSamplerModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AlwaysOnSamplerModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributeLimitsModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributeNameValueModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.B3MultiPropagatorModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.B3PropagatorModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.BaggagePropagatorModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.BatchLogRecordProcessorModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.BatchSpanProcessorModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.CardinalityLimitsModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ClientModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ConsoleModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.DetectorAttributesModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.DetectorsModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExplicitBucketHistogramModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.GeneralInstrumentationModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.HttpModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ConsoleExporterModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalGeneralInstrumentationModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalHttpInstrumentationModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalLanguageSpecificInstrumentationModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalLoggerConfigModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalLoggerConfiguratorModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalLoggerMatcherAndConfigModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalMeterConfigModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalMeterConfiguratorModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalMeterMatcherAndConfigModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalOtlpFileExporterModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalOtlpFileMetricExporterModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalPeerInstrumentationModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalPrometheusMetricExporterModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalResourceDetectionModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalResourceDetectorModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalTracerConfigModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalTracerConfiguratorModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalTracerMatcherAndConfigModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExplicitBucketHistogramAggregationModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.IncludeExcludeModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.InstrumentationModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LanguageSpecificInstrumentationModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.JaegerPropagatorModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordExporterModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordLimitsModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordProcessorModel;
@ -34,21 +52,21 @@ import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MeterP
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricProducerModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricReaderModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.NameStringValuePairModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenCensusMetricProducerModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpencensusModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpMetricModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ParentBasedModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PeerModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTracingPropagatorModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpGrpcExporterModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpGrpcMetricExporterModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpHttpExporterModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpHttpMetricExporterModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ParentBasedSamplerModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PeriodicMetricReaderModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PrometheusModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PropagatorModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PullMetricExporterModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PullMetricReaderModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PushMetricExporterModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ResourceModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SamplerModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SelectorModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ServerModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ServiceMappingModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SimpleLogRecordProcessorModel;
@ -56,11 +74,14 @@ import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Simple
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanExporterModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanLimitsModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanProcessorModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.StreamModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.TraceIdRatioBasedModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.TextMapPropagatorModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.TraceContextPropagatorModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.TraceIdRatioBasedSamplerModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.TracerProviderModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ViewModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ZipkinModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ViewSelectorModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ViewStreamModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ZipkinSpanExporterModel;
import java.io.ByteArrayInputStream;
import java.io.FileInputStream;
import java.io.IOException;
@ -92,8 +113,9 @@ class DeclarativeConfigurationParseTest {
void parse_KitchenSinkExampleFile() throws IOException {
OpenTelemetryConfigurationModel expected = new OpenTelemetryConfigurationModel();
expected.withFileFormat("0.3");
expected.withFileFormat("0.4");
expected.withDisabled(false);
expected.withLogLevel("info");
// General config
ResourceModel resource =
@ -106,42 +128,52 @@ class DeclarativeConfigurationParseTest {
new AttributeNameValueModel()
.withName("string_key")
.withValue("value")
.withType(AttributeNameValueModel.Type.STRING),
.withType(AttributeNameValueModel.AttributeType.STRING),
new AttributeNameValueModel()
.withName("bool_key")
.withValue(true)
.withType(AttributeNameValueModel.Type.BOOL),
.withType(AttributeNameValueModel.AttributeType.BOOL),
new AttributeNameValueModel()
.withName("int_key")
.withValue(1)
.withType(AttributeNameValueModel.Type.INT),
.withType(AttributeNameValueModel.AttributeType.INT),
new AttributeNameValueModel()
.withName("double_key")
.withValue(1.1)
.withType(AttributeNameValueModel.Type.DOUBLE),
.withType(AttributeNameValueModel.AttributeType.DOUBLE),
new AttributeNameValueModel()
.withName("string_array_key")
.withValue(Arrays.asList("value1", "value2"))
.withType(AttributeNameValueModel.Type.STRING_ARRAY),
.withType(AttributeNameValueModel.AttributeType.STRING_ARRAY),
new AttributeNameValueModel()
.withName("bool_array_key")
.withValue(Arrays.asList(true, false))
.withType(AttributeNameValueModel.Type.BOOL_ARRAY),
.withType(AttributeNameValueModel.AttributeType.BOOL_ARRAY),
new AttributeNameValueModel()
.withName("int_array_key")
.withValue(Arrays.asList(1, 2))
.withType(AttributeNameValueModel.Type.INT_ARRAY),
.withType(AttributeNameValueModel.AttributeType.INT_ARRAY),
new AttributeNameValueModel()
.withName("double_array_key")
.withValue(Arrays.asList(1.1, 2.2))
.withType(AttributeNameValueModel.Type.DOUBLE_ARRAY)))
.withType(AttributeNameValueModel.AttributeType.DOUBLE_ARRAY)))
.withAttributesList("service.namespace=my-namespace,service.version=1.0.0")
.withDetectors(
new DetectorsModel()
.withDetectionDevelopment(
new ExperimentalResourceDetectionModel()
.withAttributes(
new DetectorAttributesModel()
new IncludeExcludeModel()
.withIncluded(Collections.singletonList("process.*"))
.withExcluded(Collections.singletonList("process.command_args"))))
.withExcluded(Collections.singletonList("process.command_args")))
.withDetectors(
Arrays.asList(
new ExperimentalResourceDetectorModel()
.withAdditionalProperty("container", null),
new ExperimentalResourceDetectorModel()
.withAdditionalProperty("host", null),
new ExperimentalResourceDetectorModel()
.withAdditionalProperty("os", null),
new ExperimentalResourceDetectorModel()
.withAdditionalProperty("process", null))))
.withSchemaUrl("https://opentelemetry.io/schemas/1.16.0");
expected.withResource(resource);
@ -153,7 +185,14 @@ class DeclarativeConfigurationParseTest {
new PropagatorModel()
.withComposite(
Arrays.asList(
"tracecontext", "baggage", "b3", "b3multi", "jaeger", "xray", "ottrace"));
new TextMapPropagatorModel()
.withTracecontext(new TraceContextPropagatorModel()),
new TextMapPropagatorModel().withBaggage(new BaggagePropagatorModel()),
new TextMapPropagatorModel().withB3(new B3PropagatorModel()),
new TextMapPropagatorModel().withB3multi(new B3MultiPropagatorModel()),
new TextMapPropagatorModel().withJaeger(new JaegerPropagatorModel()),
new TextMapPropagatorModel().withOttrace(new OpenTracingPropagatorModel())))
.withCompositeList("tracecontext,baggage,b3,b3multi,jaeger,ottrace,xray");
expected.withPropagator(propagator);
// TracerProvider config
@ -172,18 +211,31 @@ class DeclarativeConfigurationParseTest {
SamplerModel sampler =
new SamplerModel()
.withParentBased(
new ParentBasedModel()
new ParentBasedSamplerModel()
.withRoot(
new SamplerModel()
.withTraceIdRatioBased(new TraceIdRatioBasedModel().withRatio(0.0001)))
.withRemoteParentSampled(new SamplerModel().withAlwaysOn(new AlwaysOnModel()))
.withTraceIdRatioBased(
new TraceIdRatioBasedSamplerModel().withRatio(0.0001)))
.withRemoteParentSampled(
new SamplerModel().withAlwaysOn(new AlwaysOnSamplerModel()))
.withRemoteParentNotSampled(
new SamplerModel().withAlwaysOff(new AlwaysOffModel()))
.withLocalParentSampled(new SamplerModel().withAlwaysOn(new AlwaysOnModel()))
new SamplerModel().withAlwaysOff(new AlwaysOffSamplerModel()))
.withLocalParentSampled(
new SamplerModel().withAlwaysOn(new AlwaysOnSamplerModel()))
.withLocalParentNotSampled(
new SamplerModel().withAlwaysOff(new AlwaysOffModel())));
new SamplerModel().withAlwaysOff(new AlwaysOffSamplerModel())));
tracerProvider.withSampler(sampler);
ExperimentalTracerConfiguratorModel tracerConfigurator =
new ExperimentalTracerConfiguratorModel()
.withDefaultConfig(new ExperimentalTracerConfigModel().withDisabled(true))
.withTracers(
Collections.singletonList(
new ExperimentalTracerMatcherAndConfigModel()
.withName("io.opentelemetry.contrib.*")
.withConfig(new ExperimentalTracerConfigModel().withDisabled(false))));
tracerProvider.withTracerConfiguratorDevelopment(tracerConfigurator);
SpanProcessorModel spanProcessor1 =
new SpanProcessorModel()
.withBatch(
@ -194,13 +246,34 @@ class DeclarativeConfigurationParseTest {
.withMaxExportBatchSize(512)
.withExporter(
new SpanExporterModel()
.withOtlp(
new OtlpModel()
.withProtocol("http/protobuf")
.withOtlpHttp(
new OtlpHttpExporterModel()
.withEndpoint("http://localhost:4318/v1/traces")
.withCertificate("/app/cert.pem")
.withClientKey("/app/cert.pem")
.withClientCertificate("/app/cert.pem")
.withCertificateFile("/app/cert.pem")
.withClientKeyFile("/app/cert.pem")
.withClientCertificateFile("/app/cert.pem")
.withHeaders(
Collections.singletonList(
new NameStringValuePairModel()
.withName("api-key")
.withValue("1234")))
.withHeadersList("api-key=1234")
.withCompression("gzip")
.withTimeout(10_000)
.withEncoding(
OtlpHttpExporterModel.OtlpHttpEncoding.PROTOBUF))));
SpanProcessorModel spanProcessor2 =
new SpanProcessorModel()
.withBatch(
new BatchSpanProcessorModel()
.withExporter(
new SpanExporterModel()
.withOtlpGrpc(
new OtlpGrpcExporterModel()
.withEndpoint("http://localhost:4317")
.withCertificateFile("/app/cert.pem")
.withClientKeyFile("/app/cert.pem")
.withClientCertificateFile("/app/cert.pem")
.withHeaders(
Collections.singletonList(
new NameStringValuePairModel()
@ -210,22 +283,47 @@ class DeclarativeConfigurationParseTest {
.withCompression("gzip")
.withTimeout(10_000)
.withInsecure(false))));
SpanProcessorModel spanProcessor2 =
SpanProcessorModel spanProcessor3 =
new SpanProcessorModel()
.withBatch(
new BatchSpanProcessorModel()
.withExporter(
new SpanExporterModel()
.withOtlpFileDevelopment(
new ExperimentalOtlpFileExporterModel()
.withOutputStream("file:///var/log/traces.jsonl"))));
SpanProcessorModel spanProcessor4 =
new SpanProcessorModel()
.withBatch(
new BatchSpanProcessorModel()
.withExporter(
new SpanExporterModel()
.withOtlpFileDevelopment(
new ExperimentalOtlpFileExporterModel()
.withOutputStream("stdout"))));
SpanProcessorModel spanProcessor5 =
new SpanProcessorModel()
.withBatch(
new BatchSpanProcessorModel()
.withExporter(
new SpanExporterModel()
.withZipkin(
new ZipkinModel()
new ZipkinSpanExporterModel()
.withEndpoint("http://localhost:9411/api/v2/spans")
.withTimeout(10_000))));
SpanProcessorModel spanProcessor3 =
SpanProcessorModel spanProcessor6 =
new SpanProcessorModel()
.withSimple(
new SimpleSpanProcessorModel()
.withExporter(new SpanExporterModel().withConsole(new ConsoleModel())));
tracerProvider.withProcessors(Arrays.asList(spanProcessor1, spanProcessor2, spanProcessor3));
.withExporter(new SpanExporterModel().withConsole(new ConsoleExporterModel())));
tracerProvider.withProcessors(
Arrays.asList(
spanProcessor1,
spanProcessor2,
spanProcessor3,
spanProcessor4,
spanProcessor5,
spanProcessor6));
expected.withTracerProvider(tracerProvider);
// end TracerProvider config
@ -237,6 +335,16 @@ class DeclarativeConfigurationParseTest {
new LogRecordLimitsModel().withAttributeValueLengthLimit(4096).withAttributeCountLimit(128);
loggerProvider.withLimits(logRecordLimits);
ExperimentalLoggerConfiguratorModel loggerConfigurator =
new ExperimentalLoggerConfiguratorModel()
.withDefaultConfig(new ExperimentalLoggerConfigModel().withDisabled(true))
.withLoggers(
Collections.singletonList(
new ExperimentalLoggerMatcherAndConfigModel()
.withName("io.opentelemetry.contrib.*")
.withConfig(new ExperimentalLoggerConfigModel().withDisabled(false))));
loggerProvider.withLoggerConfiguratorDevelopment(loggerConfigurator);
LogRecordProcessorModel logRecordProcessor1 =
new LogRecordProcessorModel()
.withBatch(
@ -247,13 +355,34 @@ class DeclarativeConfigurationParseTest {
.withMaxExportBatchSize(512)
.withExporter(
new LogRecordExporterModel()
.withOtlp(
new OtlpModel()
.withProtocol("http/protobuf")
.withOtlpHttp(
new OtlpHttpExporterModel()
.withEndpoint("http://localhost:4318/v1/logs")
.withCertificate("/app/cert.pem")
.withClientKey("/app/cert.pem")
.withClientCertificate("/app/cert.pem")
.withCertificateFile("/app/cert.pem")
.withClientKeyFile("/app/cert.pem")
.withClientCertificateFile("/app/cert.pem")
.withHeaders(
Collections.singletonList(
new NameStringValuePairModel()
.withName("api-key")
.withValue("1234")))
.withHeadersList("api-key=1234")
.withCompression("gzip")
.withTimeout(10_000)
.withEncoding(
OtlpHttpExporterModel.OtlpHttpEncoding.PROTOBUF))));
LogRecordProcessorModel logRecordProcessor2 =
new LogRecordProcessorModel()
.withBatch(
new BatchLogRecordProcessorModel()
.withExporter(
new LogRecordExporterModel()
.withOtlpGrpc(
new OtlpGrpcExporterModel()
.withEndpoint("http://localhost:4317")
.withCertificateFile("/app/cert.pem")
.withClientKeyFile("/app/cert.pem")
.withClientCertificateFile("/app/cert.pem")
.withHeaders(
Collections.singletonList(
new NameStringValuePairModel()
@ -263,12 +392,37 @@ class DeclarativeConfigurationParseTest {
.withCompression("gzip")
.withTimeout(10_000)
.withInsecure(false))));
LogRecordProcessorModel logRecordProcessor2 =
LogRecordProcessorModel logRecordProcessor3 =
new LogRecordProcessorModel()
.withBatch(
new BatchLogRecordProcessorModel()
.withExporter(
new LogRecordExporterModel()
.withOtlpFileDevelopment(
new ExperimentalOtlpFileExporterModel()
.withOutputStream("file:///var/log/logs.jsonl"))));
LogRecordProcessorModel logRecordProcessor4 =
new LogRecordProcessorModel()
.withBatch(
new BatchLogRecordProcessorModel()
.withExporter(
new LogRecordExporterModel()
.withOtlpFileDevelopment(
new ExperimentalOtlpFileExporterModel()
.withOutputStream("stdout"))));
LogRecordProcessorModel logRecordProcessor5 =
new LogRecordProcessorModel()
.withSimple(
new SimpleLogRecordProcessorModel()
.withExporter(new LogRecordExporterModel().withConsole(new ConsoleModel())));
loggerProvider.withProcessors(Arrays.asList(logRecordProcessor1, logRecordProcessor2));
.withExporter(
new LogRecordExporterModel().withConsole(new ConsoleExporterModel())));
loggerProvider.withProcessors(
Arrays.asList(
logRecordProcessor1,
logRecordProcessor2,
logRecordProcessor3,
logRecordProcessor4,
logRecordProcessor5));
expected.withLoggerProvider(loggerProvider);
// end LoggerProvider config
@ -282,8 +436,8 @@ class DeclarativeConfigurationParseTest {
new PullMetricReaderModel()
.withExporter(
new PullMetricExporterModel()
.withPrometheus(
new PrometheusModel()
.withPrometheusDevelopment(
new ExperimentalPrometheusMetricExporterModel()
.withHost("localhost")
.withPort(9464)
.withWithoutUnits(false)
@ -293,25 +447,76 @@ class DeclarativeConfigurationParseTest {
new IncludeExcludeModel()
.withIncluded(Collections.singletonList("service*"))
.withExcluded(
Collections.singletonList("service.attr1"))))))
.withProducers(
Collections.singletonList(
new MetricProducerModel().withOpencensus(new OpencensusModel())));
Collections.singletonList("service.attr1")))))
.withProducers(
Collections.singletonList(
new MetricProducerModel()
.withOpencensus(new OpenCensusMetricProducerModel())))
.withCardinalityLimits(
new CardinalityLimitsModel()
.withDefault(2000)
.withCounter(2000)
.withGauge(2000)
.withHistogram(2000)
.withObservableCounter(2000)
.withObservableGauge(2000)
.withObservableUpDownCounter(2000)
.withUpDownCounter(2000)));
MetricReaderModel metricReader2 =
new MetricReaderModel()
.withPeriodic(
new PeriodicMetricReaderModel()
.withInterval(5_000)
.withInterval(60_000)
.withTimeout(30_000)
.withExporter(
new PushMetricExporterModel()
.withOtlp(
new OtlpMetricModel()
.withProtocol("http/protobuf")
.withOtlpHttp(
new OtlpHttpMetricExporterModel()
.withEndpoint("http://localhost:4318/v1/metrics")
.withCertificate("/app/cert.pem")
.withClientKey("/app/cert.pem")
.withClientCertificate("/app/cert.pem")
.withCertificateFile("/app/cert.pem")
.withClientKeyFile("/app/cert.pem")
.withClientCertificateFile("/app/cert.pem")
.withHeaders(
Collections.singletonList(
new NameStringValuePairModel()
.withName("api-key")
.withValue("1234")))
.withHeadersList("api-key=1234")
.withCompression("gzip")
.withTimeout(10_000)
.withEncoding(OtlpHttpExporterModel.OtlpHttpEncoding.PROTOBUF)
.withTemporalityPreference(
OtlpHttpMetricExporterModel.ExporterTemporalityPreference
.DELTA)
.withDefaultHistogramAggregation(
OtlpHttpMetricExporterModel
.ExporterDefaultHistogramAggregation
.BASE_2_EXPONENTIAL_BUCKET_HISTOGRAM)))
.withProducers(
Collections.singletonList(
new MetricProducerModel().withAdditionalProperty("prometheus", null)))
.withCardinalityLimits(
new CardinalityLimitsModel()
.withDefault(2000)
.withCounter(2000)
.withGauge(2000)
.withHistogram(2000)
.withObservableCounter(2000)
.withObservableGauge(2000)
.withObservableUpDownCounter(2000)
.withUpDownCounter(2000)));
MetricReaderModel metricReader3 =
new MetricReaderModel()
.withPeriodic(
new PeriodicMetricReaderModel()
.withExporter(
new PushMetricExporterModel()
.withOtlpGrpc(
new OtlpGrpcMetricExporterModel()
.withEndpoint("http://localhost:4317")
.withCertificateFile("/app/cert.pem")
.withClientKeyFile("/app/cert.pem")
.withClientCertificateFile("/app/cert.pem")
.withHeaders(
Collections.singletonList(
new NameStringValuePairModel()
@ -321,49 +526,100 @@ class DeclarativeConfigurationParseTest {
.withCompression("gzip")
.withTimeout(10_000)
.withInsecure(false)
.withTemporalityPreference("delta")
.withTemporalityPreference(
OtlpHttpMetricExporterModel.ExporterTemporalityPreference
.DELTA)
.withDefaultHistogramAggregation(
OtlpMetricModel.DefaultHistogramAggregation
.BASE_2_EXPONENTIAL_BUCKET_HISTOGRAM))))
.withProducers(
Collections.singletonList(
new MetricProducerModel()
.withAdditionalProperty("prometheus", Collections.emptyMap())));
MetricReaderModel metricReader3 =
OtlpHttpMetricExporterModel
.ExporterDefaultHistogramAggregation
.BASE_2_EXPONENTIAL_BUCKET_HISTOGRAM))));
MetricReaderModel metricReader4 =
new MetricReaderModel()
.withPeriodic(
new PeriodicMetricReaderModel()
.withExporter(new PushMetricExporterModel().withConsole(new ConsoleModel())));
meterProvider.withReaders(Arrays.asList(metricReader1, metricReader2, metricReader3));
.withExporter(
new PushMetricExporterModel()
.withOtlpFileDevelopment(
new ExperimentalOtlpFileMetricExporterModel()
.withOutputStream("file:///var/log/metrics.jsonl")
.withTemporalityPreference(
OtlpHttpMetricExporterModel.ExporterTemporalityPreference
.DELTA)
.withDefaultHistogramAggregation(
OtlpHttpMetricExporterModel
.ExporterDefaultHistogramAggregation
.BASE_2_EXPONENTIAL_BUCKET_HISTOGRAM))));
MetricReaderModel metricReader5 =
new MetricReaderModel()
.withPeriodic(
new PeriodicMetricReaderModel()
.withExporter(
new PushMetricExporterModel()
.withOtlpFileDevelopment(
new ExperimentalOtlpFileMetricExporterModel()
.withOutputStream("stdout")
.withTemporalityPreference(
OtlpHttpMetricExporterModel.ExporterTemporalityPreference
.DELTA)
.withDefaultHistogramAggregation(
OtlpHttpMetricExporterModel
.ExporterDefaultHistogramAggregation
.BASE_2_EXPONENTIAL_BUCKET_HISTOGRAM))));
MetricReaderModel metricReader6 =
new MetricReaderModel()
.withPeriodic(
new PeriodicMetricReaderModel()
.withExporter(
new PushMetricExporterModel().withConsole(new ConsoleExporterModel())));
meterProvider.withReaders(
Arrays.asList(
metricReader1,
metricReader2,
metricReader3,
metricReader4,
metricReader5,
metricReader6));
ViewModel view =
new ViewModel()
.withSelector(
new SelectorModel()
new ViewSelectorModel()
.withInstrumentName("my-instrument")
.withInstrumentType(SelectorModel.InstrumentType.HISTOGRAM)
.withInstrumentType(ViewSelectorModel.InstrumentType.HISTOGRAM)
.withUnit("ms")
.withMeterName("my-meter")
.withMeterVersion("1.0.0")
.withMeterSchemaUrl("https://opentelemetry.io/schemas/1.16.0"))
.withStream(
new StreamModel()
new ViewStreamModel()
.withName("new_instrument_name")
.withDescription("new_description")
.withAggregation(
new AggregationModel()
.withExplicitBucketHistogram(
new ExplicitBucketHistogramModel()
new ExplicitBucketHistogramAggregationModel()
.withBoundaries(
Arrays.asList(
0.0, 5.0, 10.0, 25.0, 50.0, 75.0, 100.0, 250.0, 500.0,
750.0, 1000.0, 2500.0, 5000.0, 7500.0, 10000.0))
.withRecordMinMax(true)))
.withAggregationCardinalityLimit(2000)
.withAttributeKeys(
new IncludeExcludeModel()
.withIncluded(Arrays.asList("key1", "key2"))
.withExcluded(Collections.singletonList("key3"))));
meterProvider.withViews(Collections.singletonList(view));
meterProvider.withExemplarFilter(MeterProviderModel.ExemplarFilter.TRACE_BASED);
ExperimentalMeterConfiguratorModel meterConfigurator =
new ExperimentalMeterConfiguratorModel()
.withDefaultConfig(new ExperimentalMeterConfigModel().withDisabled(true))
.withMeters(
Collections.singletonList(
new ExperimentalMeterMatcherAndConfigModel()
.withName("io.opentelemetry.contrib.*")
.withConfig(new ExperimentalMeterConfigModel().withDisabled(false))));
meterProvider.withMeterConfiguratorDevelopment(meterConfigurator);
expected.withMeterProvider(meterProvider);
// end MeterProvider config
@ -372,9 +628,9 @@ class DeclarativeConfigurationParseTest {
InstrumentationModel instrumentation =
new InstrumentationModel()
.withGeneral(
new GeneralInstrumentationModel()
new ExperimentalGeneralInstrumentationModel()
.withPeer(
new PeerModel()
new ExperimentalPeerInstrumentationModel()
.withServiceMapping(
Arrays.asList(
new ServiceMappingModel()
@ -384,7 +640,7 @@ class DeclarativeConfigurationParseTest {
.withPeer("2.3.4.5")
.withService("BarService"))))
.withHttp(
new HttpModel()
new ExperimentalHttpInstrumentationModel()
.withClient(
new ClientModel()
.withRequestCapturedHeaders(
@ -398,50 +654,50 @@ class DeclarativeConfigurationParseTest {
.withResponseCapturedHeaders(
Arrays.asList("Content-Type", "Content-Encoding")))))
.withCpp(
new LanguageSpecificInstrumentationModel()
new ExperimentalLanguageSpecificInstrumentationModel()
.withAdditionalProperty(
"example", Collections.singletonMap("property", "value")))
.withDotnet(
new LanguageSpecificInstrumentationModel()
new ExperimentalLanguageSpecificInstrumentationModel()
.withAdditionalProperty(
"example", Collections.singletonMap("property", "value")))
.withErlang(
new LanguageSpecificInstrumentationModel()
new ExperimentalLanguageSpecificInstrumentationModel()
.withAdditionalProperty(
"example", Collections.singletonMap("property", "value")))
.withGo(
new LanguageSpecificInstrumentationModel()
new ExperimentalLanguageSpecificInstrumentationModel()
.withAdditionalProperty(
"example", Collections.singletonMap("property", "value")))
.withJava(
new LanguageSpecificInstrumentationModel()
new ExperimentalLanguageSpecificInstrumentationModel()
.withAdditionalProperty(
"example", Collections.singletonMap("property", "value")))
.withJs(
new LanguageSpecificInstrumentationModel()
new ExperimentalLanguageSpecificInstrumentationModel()
.withAdditionalProperty(
"example", Collections.singletonMap("property", "value")))
.withPhp(
new LanguageSpecificInstrumentationModel()
new ExperimentalLanguageSpecificInstrumentationModel()
.withAdditionalProperty(
"example", Collections.singletonMap("property", "value")))
.withPython(
new LanguageSpecificInstrumentationModel()
new ExperimentalLanguageSpecificInstrumentationModel()
.withAdditionalProperty(
"example", Collections.singletonMap("property", "value")))
.withRuby(
new LanguageSpecificInstrumentationModel()
new ExperimentalLanguageSpecificInstrumentationModel()
.withAdditionalProperty(
"example", Collections.singletonMap("property", "value")))
.withRust(
new LanguageSpecificInstrumentationModel()
new ExperimentalLanguageSpecificInstrumentationModel()
.withAdditionalProperty(
"example", Collections.singletonMap("property", "value")))
.withSwift(
new LanguageSpecificInstrumentationModel()
new ExperimentalLanguageSpecificInstrumentationModel()
.withAdditionalProperty(
"example", Collections.singletonMap("property", "value")));
expected.withInstrumentation(instrumentation);
expected.withInstrumentationDevelopment(instrumentation);
// end instrumentation config
try (FileInputStream configExampleFile =
@ -449,7 +705,7 @@ class DeclarativeConfigurationParseTest {
OpenTelemetryConfigurationModel config = DeclarativeConfiguration.parse(configExampleFile);
// General config
assertThat(config.getFileFormat()).isEqualTo("0.3");
assertThat(config.getFileFormat()).isEqualTo("0.4");
assertThat(config.getResource()).isEqualTo(resource);
assertThat(config.getAttributeLimits()).isEqualTo(attributeLimits);
assertThat(config.getPropagator()).isEqualTo(propagator);
@ -458,23 +714,52 @@ class DeclarativeConfigurationParseTest {
TracerProviderModel configTracerProvider = config.getTracerProvider();
assertThat(configTracerProvider.getLimits()).isEqualTo(spanLimits);
assertThat(configTracerProvider.getSampler()).isEqualTo(sampler);
assertThat(configTracerProvider.getTracerConfiguratorDevelopment())
.isEqualTo(tracerConfigurator);
assertThat(configTracerProvider.getProcessors())
.isEqualTo(Arrays.asList(spanProcessor1, spanProcessor2, spanProcessor3));
.isEqualTo(
Arrays.asList(
spanProcessor1,
spanProcessor2,
spanProcessor3,
spanProcessor4,
spanProcessor5,
spanProcessor6));
assertThat(configTracerProvider).isEqualTo(tracerProvider);
// LoggerProvider config
LoggerProviderModel configLoggerProvider = config.getLoggerProvider();
assertThat(configLoggerProvider.getLimits()).isEqualTo(logRecordLimits);
assertThat(configLoggerProvider.getLoggerConfiguratorDevelopment())
.isEqualTo(loggerConfigurator);
assertThat(configLoggerProvider.getProcessors())
.isEqualTo(Arrays.asList(logRecordProcessor1, logRecordProcessor2));
.isEqualTo(
Arrays.asList(
logRecordProcessor1,
logRecordProcessor2,
logRecordProcessor3,
logRecordProcessor4,
logRecordProcessor5));
assertThat(configLoggerProvider).isEqualTo(loggerProvider);
// MeterProvider config
MeterProviderModel configMeterProvider = config.getMeterProvider();
assertThat(configMeterProvider.getReaders())
.isEqualTo(Arrays.asList(metricReader1, metricReader2, metricReader3));
.isEqualTo(
Arrays.asList(
metricReader1,
metricReader2,
metricReader3,
metricReader4,
metricReader5,
metricReader6));
assertThat(configMeterProvider.getViews()).isEqualTo(Collections.singletonList(view));
assertThat(configMeterProvider.getMeterConfiguratorDevelopment())
.isEqualTo(meterConfigurator);
assertThat(configMeterProvider).isEqualTo(meterProvider);
// Instrumentation config
InstrumentationModel configInstrumentation = config.getInstrumentation();
InstrumentationModel configInstrumentation = config.getInstrumentationDevelopment();
assertThat(configInstrumentation).isEqualTo(instrumentation);
// All configuration
@ -485,7 +770,7 @@ class DeclarativeConfigurationParseTest {
@Test
void parse_nullValuesParsedToEmptyObjects() {
String objectPlaceholderString =
"file_format: \"0.3\"\n"
"file_format: \"0.4\"\n"
+ "tracer_provider:\n"
+ " processors:\n"
+ " - batch:\n"
@ -503,7 +788,7 @@ class DeclarativeConfigurationParseTest {
new ByteArrayInputStream(objectPlaceholderString.getBytes(StandardCharsets.UTF_8)));
String noOjbectPlaceholderString =
"file_format: \"0.3\"\n"
"file_format: \"0.4\"\n"
+ "tracer_provider:\n"
+ " processors:\n"
+ " - batch:\n"
@ -528,7 +813,7 @@ class DeclarativeConfigurationParseTest {
.getBatch()
.getExporter();
assertThat(exporter.getConsole()).isNotNull();
assertThat(exporter.getOtlp()).isNull();
assertThat(exporter.getOtlpHttp()).isNull();
AggregationModel aggregation =
noObjectPlaceholderModel.getMeterProvider().getViews().get(0).getStream().getAggregation();
@ -567,7 +852,7 @@ class DeclarativeConfigurationParseTest {
new TracerProviderModel()
.withSampler(
new SamplerModel()
.withTraceIdRatioBased(new TraceIdRatioBasedModel()))));
.withTraceIdRatioBased(new TraceIdRatioBasedSamplerModel()))));
}
@ParameterizedTest
@ -701,16 +986,16 @@ class DeclarativeConfigurationParseTest {
@Test
void read_WithEnvironmentVariables() {
String yaml =
"file_format: \"0.3\"\n"
"file_format: \"0.4\"\n"
+ "tracer_provider:\n"
+ " processors:\n"
+ " - batch:\n"
+ " exporter:\n"
+ " otlp:\n"
+ " otlp_http:\n"
+ " endpoint: ${OTEL_EXPORTER_OTLP_ENDPOINT}\n"
+ " - batch:\n"
+ " exporter:\n"
+ " otlp:\n"
+ " otlp_http:\n"
+ " endpoint: ${UNSET_ENV_VAR}\n";
Map<String, String> envVars = new HashMap<>();
envVars.put("OTEL_EXPORTER_OTLP_ENDPOINT", "http://collector:4317");
@ -720,7 +1005,7 @@ class DeclarativeConfigurationParseTest {
assertThat(model)
.isEqualTo(
new OpenTelemetryConfigurationModel()
.withFileFormat("0.3")
.withFileFormat("0.4")
.withTracerProvider(
new TracerProviderModel()
.withProcessors(
@ -730,8 +1015,8 @@ class DeclarativeConfigurationParseTest {
new BatchSpanProcessorModel()
.withExporter(
new SpanExporterModel()
.withOtlp(
new OtlpModel()
.withOtlpHttp(
new OtlpHttpExporterModel()
.withEndpoint(
"http://collector:4317")))),
new SpanProcessorModel()
@ -739,6 +1024,7 @@ class DeclarativeConfigurationParseTest {
new BatchSpanProcessorModel()
.withExporter(
new SpanExporterModel()
.withOtlp(new OtlpModel())))))));
.withOtlpHttp(
new OtlpHttpExporterModel())))))));
}
}

View File

@ -11,7 +11,7 @@ import static org.mockito.Mockito.mock;
import io.opentelemetry.api.incubator.config.DeclarativeConfigException;
import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SelectorModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ViewSelectorModel;
import io.opentelemetry.sdk.metrics.InstrumentSelector;
import io.opentelemetry.sdk.metrics.InstrumentType;
import java.util.Collections;
@ -24,7 +24,8 @@ class InstrumentSelectorFactoryTest {
assertThatThrownBy(
() ->
InstrumentSelectorFactory.getInstance()
.create(new SelectorModel(), mock(SpiHelper.class), Collections.emptyList()))
.create(
new ViewSelectorModel(), mock(SpiHelper.class), Collections.emptyList()))
.isInstanceOf(DeclarativeConfigException.class)
.hasMessage("Invalid selector");
}
@ -34,9 +35,9 @@ class InstrumentSelectorFactoryTest {
assertThat(
InstrumentSelectorFactory.getInstance()
.create(
new SelectorModel()
new ViewSelectorModel()
.withInstrumentName("instrument-name")
.withInstrumentType(SelectorModel.InstrumentType.COUNTER)
.withInstrumentType(ViewSelectorModel.InstrumentType.COUNTER)
.withMeterName("meter-name")
.withMeterSchemaUrl("https://opentelemetry.io/schemas/1.16.0")
.withMeterVersion("1.0.0"),

View File

@ -16,14 +16,18 @@ import com.google.common.collect.ImmutableMap;
import com.linecorp.armeria.testing.junit5.server.SelfSignedCertificateExtension;
import io.opentelemetry.api.incubator.config.DeclarativeConfigException;
import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties;
import io.opentelemetry.exporter.logging.otlp.internal.logs.OtlpStdoutLogRecordExporter;
import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporter;
import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporter;
import io.opentelemetry.internal.testing.CleanupExtension;
import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper;
import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider;
import io.opentelemetry.sdk.extension.incubator.fileconfig.component.LogRecordExporterComponentProvider;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalOtlpFileExporterModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordExporterModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.NameStringValuePairModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpGrpcExporterModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpHttpExporterModel;
import io.opentelemetry.sdk.logs.export.LogRecordExporter;
import java.io.Closeable;
import java.io.IOException;
@ -87,7 +91,7 @@ class LogRecordExporterFactoryTest {
}
@Test
void create_OtlpDefaults() {
void create_OtlpHttpDefaults() {
List<Closeable> closeables = new ArrayList<>();
OtlpHttpLogRecordExporter expectedExporter = OtlpHttpLogRecordExporter.getDefault();
cleanup.addCloseable(expectedExporter);
@ -95,9 +99,7 @@ class LogRecordExporterFactoryTest {
LogRecordExporter exporter =
LogRecordExporterFactory.getInstance()
.create(
new io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model
.LogRecordExporterModel()
.withOtlp(new OtlpModel()),
new LogRecordExporterModel().withOtlpHttp(new OtlpHttpExporterModel()),
spiHelper,
closeables);
cleanup.addCloseable(exporter);
@ -109,7 +111,8 @@ class LogRecordExporterFactoryTest {
ArgumentCaptor<DeclarativeConfigProperties> configCaptor =
ArgumentCaptor.forClass(DeclarativeConfigProperties.class);
ComponentProvider<?> componentProvider = getComponentProvider("otlp", LogRecordExporter.class);
ComponentProvider<?> componentProvider =
getComponentProvider("otlp_http", LogRecordExporter.class);
verify(componentProvider).create(configCaptor.capture());
DeclarativeConfigProperties configProperties = configCaptor.getValue();
assertThat(configProperties.getString("protocol")).isNull();
@ -117,13 +120,13 @@ class LogRecordExporterFactoryTest {
assertThat(configProperties.getStructured("headers")).isNull();
assertThat(configProperties.getString("compression")).isNull();
assertThat(configProperties.getInt("timeout")).isNull();
assertThat(configProperties.getString("certificate")).isNull();
assertThat(configProperties.getString("client_key")).isNull();
assertThat(configProperties.getString("client_certificate")).isNull();
assertThat(configProperties.getString("certificate_file")).isNull();
assertThat(configProperties.getString("client_key_file")).isNull();
assertThat(configProperties.getString("client_certificate_file")).isNull();
}
@Test
void create_OtlpConfigured(@TempDir Path tempDir)
void create_OtlpHttpConfigured(@TempDir Path tempDir)
throws CertificateEncodingException, IOException {
List<Closeable> closeables = new ArrayList<>();
OtlpHttpLogRecordExporter expectedExporter =
@ -149,11 +152,9 @@ class LogRecordExporterFactoryTest {
LogRecordExporter exporter =
LogRecordExporterFactory.getInstance()
.create(
new io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model
.LogRecordExporterModel()
.withOtlp(
new OtlpModel()
.withProtocol("http/protobuf")
new LogRecordExporterModel()
.withOtlpHttp(
new OtlpHttpExporterModel()
.withEndpoint("http://example:4318/v1/logs")
.withHeaders(
Arrays.asList(
@ -165,9 +166,9 @@ class LogRecordExporterFactoryTest {
.withValue("value2")))
.withCompression("gzip")
.withTimeout(15_000)
.withCertificate(certificatePath)
.withClientKey(clientKeyPath)
.withClientCertificate(clientCertificatePath)),
.withCertificateFile(certificatePath)
.withClientKeyFile(clientKeyPath)
.withClientCertificateFile(clientCertificatePath)),
spiHelper,
closeables);
cleanup.addCloseable(exporter);
@ -177,10 +178,10 @@ class LogRecordExporterFactoryTest {
ArgumentCaptor<DeclarativeConfigProperties> configCaptor =
ArgumentCaptor.forClass(DeclarativeConfigProperties.class);
ComponentProvider<?> componentProvider = getComponentProvider("otlp", LogRecordExporter.class);
ComponentProvider<?> componentProvider =
getComponentProvider("otlp_http", LogRecordExporter.class);
verify(componentProvider).create(configCaptor.capture());
DeclarativeConfigProperties configProperties = configCaptor.getValue();
assertThat(configProperties.getString("protocol")).isEqualTo("http/protobuf");
assertThat(configProperties.getString("endpoint")).isEqualTo("http://example:4318/v1/logs");
List<DeclarativeConfigProperties> headers = configProperties.getStructuredList("headers");
assertThat(headers)
@ -196,9 +197,147 @@ class LogRecordExporterFactoryTest {
});
assertThat(configProperties.getString("compression")).isEqualTo("gzip");
assertThat(configProperties.getInt("timeout")).isEqualTo(Duration.ofSeconds(15).toMillis());
assertThat(configProperties.getString("certificate")).isEqualTo(certificatePath);
assertThat(configProperties.getString("client_key")).isEqualTo(clientKeyPath);
assertThat(configProperties.getString("client_certificate")).isEqualTo(clientCertificatePath);
assertThat(configProperties.getString("certificate_file")).isEqualTo(certificatePath);
assertThat(configProperties.getString("client_key_file")).isEqualTo(clientKeyPath);
assertThat(configProperties.getString("client_certificate_file"))
.isEqualTo(clientCertificatePath);
}
@Test
void create_OtlpGrpcDefaults() {
List<Closeable> closeables = new ArrayList<>();
OtlpGrpcLogRecordExporter expectedExporter = OtlpGrpcLogRecordExporter.getDefault();
cleanup.addCloseable(expectedExporter);
LogRecordExporter exporter =
LogRecordExporterFactory.getInstance()
.create(
new LogRecordExporterModel().withOtlpGrpc(new OtlpGrpcExporterModel()),
spiHelper,
closeables);
cleanup.addCloseable(exporter);
cleanup.addCloseables(closeables);
assertThat(exporter.toString()).isEqualTo(expectedExporter.toString());
assertThat(exporter.toString()).isEqualTo(expectedExporter.toString());
ArgumentCaptor<DeclarativeConfigProperties> configCaptor =
ArgumentCaptor.forClass(DeclarativeConfigProperties.class);
ComponentProvider<?> componentProvider =
getComponentProvider("otlp_grpc", LogRecordExporter.class);
verify(componentProvider).create(configCaptor.capture());
DeclarativeConfigProperties configProperties = configCaptor.getValue();
assertThat(configProperties.getString("endpoint")).isNull();
assertThat(configProperties.getStructured("headers")).isNull();
assertThat(configProperties.getString("compression")).isNull();
assertThat(configProperties.getInt("timeout")).isNull();
assertThat(configProperties.getString("certificate_file")).isNull();
assertThat(configProperties.getString("client_key_file")).isNull();
assertThat(configProperties.getString("client_certificate_file")).isNull();
}
@Test
void create_OtlpGrpcConfigured(@TempDir Path tempDir)
throws CertificateEncodingException, IOException {
List<Closeable> closeables = new ArrayList<>();
OtlpGrpcLogRecordExporter expectedExporter =
OtlpGrpcLogRecordExporter.builder()
.setEndpoint("http://example:4317")
.addHeader("key1", "value1")
.addHeader("key2", "value2")
.setTimeout(Duration.ofSeconds(15))
.setCompression("gzip")
.build();
cleanup.addCloseable(expectedExporter);
// Write certificates to temp files
String certificatePath =
createTempFileWithContent(
tempDir, "certificate.cert", serverTls.certificate().getEncoded());
String clientKeyPath =
createTempFileWithContent(tempDir, "clientKey.key", clientTls.privateKey().getEncoded());
String clientCertificatePath =
createTempFileWithContent(
tempDir, "clientCertificate.cert", clientTls.certificate().getEncoded());
LogRecordExporter exporter =
LogRecordExporterFactory.getInstance()
.create(
new LogRecordExporterModel()
.withOtlpGrpc(
new OtlpGrpcExporterModel()
.withEndpoint("http://example:4317")
.withHeaders(
Arrays.asList(
new NameStringValuePairModel()
.withName("key1")
.withValue("value1"),
new NameStringValuePairModel()
.withName("key2")
.withValue("value2")))
.withCompression("gzip")
.withTimeout(15_000)
.withCertificateFile(certificatePath)
.withClientKeyFile(clientKeyPath)
.withClientCertificateFile(clientCertificatePath)),
spiHelper,
closeables);
cleanup.addCloseable(exporter);
cleanup.addCloseables(closeables);
assertThat(exporter.toString()).isEqualTo(expectedExporter.toString());
ArgumentCaptor<DeclarativeConfigProperties> configCaptor =
ArgumentCaptor.forClass(DeclarativeConfigProperties.class);
ComponentProvider<?> componentProvider =
getComponentProvider("otlp_grpc", LogRecordExporter.class);
verify(componentProvider).create(configCaptor.capture());
DeclarativeConfigProperties configProperties = configCaptor.getValue();
assertThat(configProperties.getString("endpoint")).isEqualTo("http://example:4317");
List<DeclarativeConfigProperties> headers = configProperties.getStructuredList("headers");
assertThat(headers)
.isNotNull()
.satisfiesExactly(
header -> {
assertThat(header.getString("name")).isEqualTo("key1");
assertThat(header.getString("value")).isEqualTo("value1");
},
header -> {
assertThat(header.getString("name")).isEqualTo("key2");
assertThat(header.getString("value")).isEqualTo("value2");
});
assertThat(configProperties.getString("compression")).isEqualTo("gzip");
assertThat(configProperties.getInt("timeout")).isEqualTo(Duration.ofSeconds(15).toMillis());
assertThat(configProperties.getString("certificate_file")).isEqualTo(certificatePath);
assertThat(configProperties.getString("client_key_file")).isEqualTo(clientKeyPath);
assertThat(configProperties.getString("client_certificate_file"))
.isEqualTo(clientCertificatePath);
}
@Test
void create_OtlpFile() {
List<Closeable> closeables = new ArrayList<>();
OtlpStdoutLogRecordExporter expectedExporter = OtlpStdoutLogRecordExporter.builder().build();
cleanup.addCloseable(expectedExporter);
LogRecordExporter exporter =
LogRecordExporterFactory.getInstance()
.create(
new LogRecordExporterModel()
.withOtlpFileDevelopment(new ExperimentalOtlpFileExporterModel()),
spiHelper,
closeables);
cleanup.addCloseable(exporter);
cleanup.addCloseables(closeables);
assertThat(exporter.toString()).isEqualTo(expectedExporter.toString());
ArgumentCaptor<DeclarativeConfigProperties> configCaptor =
ArgumentCaptor.forClass(DeclarativeConfigProperties.class);
ComponentProvider<?> componentProvider =
getComponentProvider("otlp_file/development", LogRecordExporter.class);
verify(componentProvider).create(configCaptor.capture());
}
@Test
@ -209,8 +348,7 @@ class LogRecordExporterFactoryTest {
() ->
LogRecordExporterFactory.getInstance()
.create(
new io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model
.LogRecordExporterModel()
new LogRecordExporterModel()
.withAdditionalProperty(
"unknown_key", ImmutableMap.of("key1", "value1")),
spiHelper,

View File

@ -17,7 +17,7 @@ import io.opentelemetry.sdk.extension.incubator.fileconfig.component.LogRecordPr
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;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpHttpExporterModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SimpleLogRecordProcessorModel;
import java.io.Closeable;
import java.time.Duration;
@ -63,7 +63,9 @@ class LogRecordProcessorFactoryTest {
new LogRecordProcessorModel()
.withBatch(
new BatchLogRecordProcessorModel()
.withExporter(new LogRecordExporterModel().withOtlp(new OtlpModel()))),
.withExporter(
new LogRecordExporterModel()
.withOtlpHttp(new OtlpHttpExporterModel()))),
spiHelper,
closeables);
cleanup.addCloseable(processor);
@ -90,7 +92,9 @@ class LogRecordProcessorFactoryTest {
new LogRecordProcessorModel()
.withBatch(
new BatchLogRecordProcessorModel()
.withExporter(new LogRecordExporterModel().withOtlp(new OtlpModel()))
.withExporter(
new LogRecordExporterModel()
.withOtlpHttp(new OtlpHttpExporterModel()))
.withScheduleDelay(1)
.withMaxExportBatchSize(2)
.withExportTimeout(3)),
@ -130,7 +134,9 @@ class LogRecordProcessorFactoryTest {
new LogRecordProcessorModel()
.withSimple(
new SimpleLogRecordProcessorModel()
.withExporter(new LogRecordExporterModel().withOtlp(new OtlpModel()))),
.withExporter(
new LogRecordExporterModel()
.withOtlpHttp(new OtlpHttpExporterModel()))),
spiHelper,
closeables);
cleanup.addCloseable(processor);

View File

@ -5,6 +5,7 @@
package io.opentelemetry.sdk.extension.incubator.fileconfig;
import static io.opentelemetry.sdk.logs.internal.SdkLoggerProviderUtil.setLoggerConfigurator;
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat;
import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporter;
@ -12,13 +13,19 @@ import io.opentelemetry.internal.testing.CleanupExtension;
import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributeLimitsModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.BatchLogRecordProcessorModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalLoggerConfigModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalLoggerConfiguratorModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalLoggerMatcherAndConfigModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordExporterModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordLimitsModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordProcessorModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LoggerProviderModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpHttpExporterModel;
import io.opentelemetry.sdk.internal.ScopeConfigurator;
import io.opentelemetry.sdk.internal.ScopeConfiguratorBuilder;
import io.opentelemetry.sdk.logs.LogLimits;
import io.opentelemetry.sdk.logs.SdkLoggerProvider;
import io.opentelemetry.sdk.logs.internal.LoggerConfig;
import java.io.Closeable;
import java.util.ArrayList;
import java.util.Collections;
@ -74,8 +81,25 @@ class LoggerProviderFactoryTest {
new BatchLogRecordProcessorModel()
.withExporter(
new LogRecordExporterModel()
.withOtlp(new OtlpModel())))))),
SdkLoggerProvider.builder()
.withOtlpHttp(new OtlpHttpExporterModel())))))
.withLoggerConfiguratorDevelopment(
new ExperimentalLoggerConfiguratorModel()
.withDefaultConfig(
new ExperimentalLoggerConfigModel().withDisabled(true))
.withLoggers(
Collections.singletonList(
new ExperimentalLoggerMatcherAndConfigModel()
.withName("foo")
.withConfig(
new ExperimentalLoggerConfigModel()
.withDisabled(false)))))),
setLoggerConfigurator(
SdkLoggerProvider.builder(),
ScopeConfigurator.<LoggerConfig>builder()
.setDefault(LoggerConfig.disabled())
.addCondition(
ScopeConfiguratorBuilder.nameMatchesGlob("foo"), LoggerConfig.enabled())
.build())
.setLogLimits(
() ->
LogLimits.builder()

View File

@ -5,27 +5,39 @@
package io.opentelemetry.sdk.extension.incubator.fileconfig;
import static io.opentelemetry.sdk.metrics.internal.SdkMeterProviderUtil.setMeterConfigurator;
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat;
import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporter;
import io.opentelemetry.internal.testing.CleanupExtension;
import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalMeterConfigModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalMeterConfiguratorModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalMeterMatcherAndConfigModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MeterProviderModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricReaderModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpMetricModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpHttpMetricExporterModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PeriodicMetricReaderModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PushMetricExporterModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SelectorModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.StreamModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ViewModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ViewSelectorModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ViewStreamModel;
import io.opentelemetry.sdk.internal.ScopeConfigurator;
import io.opentelemetry.sdk.internal.ScopeConfiguratorBuilder;
import io.opentelemetry.sdk.metrics.InstrumentSelector;
import io.opentelemetry.sdk.metrics.SdkMeterProvider;
import io.opentelemetry.sdk.metrics.View;
import io.opentelemetry.sdk.metrics.export.PeriodicMetricReader;
import io.opentelemetry.sdk.metrics.internal.MeterConfig;
import java.io.Closeable;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import org.junit.jupiter.api.Test;
import java.util.stream.Stream;
import org.junit.jupiter.api.extension.RegisterExtension;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
class MeterProviderFactoryTest {
@ -34,65 +46,63 @@ class MeterProviderFactoryTest {
private final SpiHelper spiHelper =
SpiHelper.create(MeterProviderFactoryTest.class.getClassLoader());
@Test
void create_Defaults() {
@ParameterizedTest
@MethodSource("createArguments")
void create(MeterProviderModel model, SdkMeterProvider expectedProvider) {
List<Closeable> closeables = new ArrayList<>();
SdkMeterProvider expectedProvider = SdkMeterProvider.builder().build();
cleanup.addCloseable(expectedProvider);
SdkMeterProvider provider =
MeterProviderFactory.getInstance()
.create(new MeterProviderModel(), spiHelper, closeables)
.build();
MeterProviderFactory.getInstance().create(model, spiHelper, closeables).build();
cleanup.addCloseable(provider);
cleanup.addCloseables(closeables);
assertThat(provider.toString()).isEqualTo(expectedProvider.toString());
}
@Test
void create_Configured() {
List<Closeable> closeables = new ArrayList<>();
SdkMeterProvider expectedProvider =
SdkMeterProvider.builder()
.registerMetricReader(
io.opentelemetry.sdk.metrics.export.PeriodicMetricReader.builder(
OtlpHttpMetricExporter.getDefault())
.build())
.registerView(
InstrumentSelector.builder().setName("instrument-name").build(),
View.builder().setName("stream-name").build())
.build();
cleanup.addCloseable(expectedProvider);
SdkMeterProvider provider =
MeterProviderFactory.getInstance()
.create(
new MeterProviderModel()
.withReaders(
Collections.singletonList(
new MetricReaderModel()
.withPeriodic(
new PeriodicMetricReaderModel()
.withExporter(
new PushMetricExporterModel()
.withOtlp(new OtlpMetricModel())))))
.withViews(
Collections.singletonList(
new io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model
.ViewModel()
.withSelector(
new SelectorModel().withInstrumentName("instrument-name"))
.withStream(
new StreamModel()
.withName("stream-name")
.withAttributeKeys(null)))),
spiHelper,
closeables)
.build();
cleanup.addCloseable(provider);
cleanup.addCloseables(closeables);
assertThat(provider.toString()).isEqualTo(expectedProvider.toString());
private static Stream<Arguments> createArguments() {
return Stream.of(
Arguments.of(new MeterProviderModel(), SdkMeterProvider.builder().build()),
Arguments.of(
new MeterProviderModel()
.withReaders(
Collections.singletonList(
new MetricReaderModel()
.withPeriodic(
new PeriodicMetricReaderModel()
.withExporter(
new PushMetricExporterModel()
.withOtlpHttp(new OtlpHttpMetricExporterModel())))))
.withViews(
Collections.singletonList(
new ViewModel()
.withSelector(
new ViewSelectorModel().withInstrumentName("instrument-name"))
.withStream(
new ViewStreamModel()
.withName("stream-name")
.withAttributeKeys(null))))
.withMeterConfiguratorDevelopment(
new ExperimentalMeterConfiguratorModel()
.withDefaultConfig(new ExperimentalMeterConfigModel().withDisabled(true))
.withMeters(
Collections.singletonList(
new ExperimentalMeterMatcherAndConfigModel()
.withName("foo")
.withConfig(
new ExperimentalMeterConfigModel().withDisabled(false))))),
setMeterConfigurator(
SdkMeterProvider.builder(),
ScopeConfigurator.<MeterConfig>builder()
.setDefault(MeterConfig.disabled())
.addCondition(
ScopeConfiguratorBuilder.nameMatchesGlob("foo"), MeterConfig.enabled())
.build())
.registerMetricReader(
PeriodicMetricReader.builder(OtlpHttpMetricExporter.getDefault()).build())
.registerView(
InstrumentSelector.builder().setName("instrument-name").build(),
View.builder().setName("stream-name").build())
.build()));
}
}

View File

@ -17,14 +17,19 @@ import com.linecorp.armeria.testing.junit5.server.SelfSignedCertificateExtension
import io.opentelemetry.api.incubator.config.DeclarativeConfigException;
import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties;
import io.opentelemetry.exporter.logging.LoggingMetricExporter;
import io.opentelemetry.exporter.logging.otlp.internal.metrics.OtlpStdoutMetricExporter;
import io.opentelemetry.exporter.otlp.http.metrics.OtlpHttpMetricExporter;
import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporter;
import io.opentelemetry.internal.testing.CleanupExtension;
import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper;
import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider;
import io.opentelemetry.sdk.extension.incubator.fileconfig.component.MetricExporterComponentProvider;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ConsoleModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ConsoleExporterModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalOtlpFileMetricExporterModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.NameStringValuePairModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpMetricModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpGrpcMetricExporterModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpHttpMetricExporterModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PushMetricExporterModel;
import io.opentelemetry.sdk.metrics.Aggregation;
import io.opentelemetry.sdk.metrics.InstrumentType;
import io.opentelemetry.sdk.metrics.export.AggregationTemporalitySelector;
@ -92,7 +97,7 @@ class MetricExporterFactoryTest {
}
@Test
void create_OtlpDefaults() {
void create_OtlpHttpDefaults() {
List<Closeable> closeables = new ArrayList<>();
OtlpHttpMetricExporter expectedExporter = OtlpHttpMetricExporter.getDefault();
cleanup.addCloseable(expectedExporter);
@ -100,9 +105,7 @@ class MetricExporterFactoryTest {
MetricExporter exporter =
MetricExporterFactory.getInstance()
.create(
new io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model
.PushMetricExporterModel()
.withOtlp(new OtlpMetricModel()),
new PushMetricExporterModel().withOtlpHttp(new OtlpHttpMetricExporterModel()),
spiHelper,
closeables);
cleanup.addCloseable(exporter);
@ -112,7 +115,8 @@ class MetricExporterFactoryTest {
ArgumentCaptor<DeclarativeConfigProperties> configCaptor =
ArgumentCaptor.forClass(DeclarativeConfigProperties.class);
ComponentProvider<?> componentProvider = getComponentProvider("otlp", MetricExporter.class);
ComponentProvider<?> componentProvider =
getComponentProvider("otlp_http", MetricExporter.class);
verify(componentProvider).create(configCaptor.capture());
DeclarativeConfigProperties configProperties = configCaptor.getValue();
assertThat(configProperties.getString("protocol")).isNull();
@ -120,15 +124,15 @@ class MetricExporterFactoryTest {
assertThat(configProperties.getStructured("headers")).isNull();
assertThat(configProperties.getString("compression")).isNull();
assertThat(configProperties.getInt("timeout")).isNull();
assertThat(configProperties.getString("certificate")).isNull();
assertThat(configProperties.getString("client_key")).isNull();
assertThat(configProperties.getString("client_certificate")).isNull();
assertThat(configProperties.getString("certificate_file")).isNull();
assertThat(configProperties.getString("client_key_file")).isNull();
assertThat(configProperties.getString("client_certificate_file")).isNull();
assertThat(configProperties.getString("temporality_preference")).isNull();
assertThat(configProperties.getString("default_histogram_aggregation")).isNull();
}
@Test
void create_OtlpConfigured(@TempDir Path tempDir)
void create_OtlpHttpConfigured(@TempDir Path tempDir)
throws CertificateEncodingException, IOException {
List<Closeable> closeables = new ArrayList<>();
OtlpHttpMetricExporter expectedExporter =
@ -158,11 +162,9 @@ class MetricExporterFactoryTest {
MetricExporter exporter =
MetricExporterFactory.getInstance()
.create(
new io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model
.PushMetricExporterModel()
.withOtlp(
new OtlpMetricModel()
.withProtocol("http/protobuf")
new PushMetricExporterModel()
.withOtlpHttp(
new OtlpHttpMetricExporterModel()
.withEndpoint("http://example:4318/v1/metrics")
.withHeaders(
Arrays.asList(
@ -174,12 +176,13 @@ class MetricExporterFactoryTest {
.withValue("value2")))
.withCompression("gzip")
.withTimeout(15_000)
.withCertificate(certificatePath)
.withClientKey(clientKeyPath)
.withClientCertificate(clientCertificatePath)
.withTemporalityPreference("delta")
.withCertificateFile(certificatePath)
.withClientKeyFile(clientKeyPath)
.withClientCertificateFile(clientCertificatePath)
.withTemporalityPreference(
OtlpHttpMetricExporterModel.ExporterTemporalityPreference.DELTA)
.withDefaultHistogramAggregation(
OtlpMetricModel.DefaultHistogramAggregation
OtlpHttpMetricExporterModel.ExporterDefaultHistogramAggregation
.BASE_2_EXPONENTIAL_BUCKET_HISTOGRAM)),
spiHelper,
closeables);
@ -190,10 +193,10 @@ class MetricExporterFactoryTest {
ArgumentCaptor<DeclarativeConfigProperties> configCaptor =
ArgumentCaptor.forClass(DeclarativeConfigProperties.class);
ComponentProvider<?> componentProvider = getComponentProvider("otlp", MetricExporter.class);
ComponentProvider<?> componentProvider =
getComponentProvider("otlp_http", MetricExporter.class);
verify(componentProvider).create(configCaptor.capture());
DeclarativeConfigProperties configProperties = configCaptor.getValue();
assertThat(configProperties.getString("protocol")).isEqualTo("http/protobuf");
assertThat(configProperties.getString("endpoint")).isEqualTo("http://example:4318/v1/metrics");
List<DeclarativeConfigProperties> headers = configProperties.getStructuredList("headers");
assertThat(headers)
@ -209,9 +212,134 @@ class MetricExporterFactoryTest {
});
assertThat(configProperties.getString("compression")).isEqualTo("gzip");
assertThat(configProperties.getInt("timeout")).isEqualTo(Duration.ofSeconds(15).toMillis());
assertThat(configProperties.getString("certificate")).isEqualTo(certificatePath);
assertThat(configProperties.getString("client_key")).isEqualTo(clientKeyPath);
assertThat(configProperties.getString("client_certificate")).isEqualTo(clientCertificatePath);
assertThat(configProperties.getString("certificate_file")).isEqualTo(certificatePath);
assertThat(configProperties.getString("client_key_file")).isEqualTo(clientKeyPath);
assertThat(configProperties.getString("client_certificate_file"))
.isEqualTo(clientCertificatePath);
assertThat(configProperties.getString("temporality_preference")).isEqualTo("delta");
assertThat(configProperties.getString("default_histogram_aggregation"))
.isEqualTo("base2_exponential_bucket_histogram");
}
@Test
void create_OtlpGrpcDefaults() {
List<Closeable> closeables = new ArrayList<>();
OtlpGrpcMetricExporter expectedExporter = OtlpGrpcMetricExporter.getDefault();
cleanup.addCloseable(expectedExporter);
MetricExporter exporter =
MetricExporterFactory.getInstance()
.create(
new PushMetricExporterModel().withOtlpGrpc(new OtlpGrpcMetricExporterModel()),
spiHelper,
closeables);
cleanup.addCloseable(exporter);
cleanup.addCloseables(closeables);
assertThat(exporter.toString()).isEqualTo(expectedExporter.toString());
ArgumentCaptor<DeclarativeConfigProperties> configCaptor =
ArgumentCaptor.forClass(DeclarativeConfigProperties.class);
ComponentProvider<?> componentProvider =
getComponentProvider("otlp_grpc", MetricExporter.class);
verify(componentProvider).create(configCaptor.capture());
DeclarativeConfigProperties configProperties = configCaptor.getValue();
assertThat(configProperties.getString("endpoint")).isNull();
assertThat(configProperties.getStructured("headers")).isNull();
assertThat(configProperties.getString("compression")).isNull();
assertThat(configProperties.getInt("timeout")).isNull();
assertThat(configProperties.getString("certificate_file")).isNull();
assertThat(configProperties.getString("client_key_file")).isNull();
assertThat(configProperties.getString("client_certificate_file")).isNull();
assertThat(configProperties.getString("temporality_preference")).isNull();
assertThat(configProperties.getString("default_histogram_aggregation")).isNull();
}
@Test
void create_OtlpGrpcConfigured(@TempDir Path tempDir)
throws CertificateEncodingException, IOException {
List<Closeable> closeables = new ArrayList<>();
OtlpGrpcMetricExporter expectedExporter =
OtlpGrpcMetricExporter.builder()
.setEndpoint("http://example:4317")
.addHeader("key1", "value1")
.addHeader("key2", "value2")
.setTimeout(Duration.ofSeconds(15))
.setCompression("gzip")
.setAggregationTemporalitySelector(AggregationTemporalitySelector.deltaPreferred())
.setDefaultAggregationSelector(
DefaultAggregationSelector.getDefault()
.with(InstrumentType.HISTOGRAM, Aggregation.base2ExponentialBucketHistogram()))
.build();
cleanup.addCloseable(expectedExporter);
// Write certificates to temp files
String certificatePath =
createTempFileWithContent(
tempDir, "certificate.cert", serverTls.certificate().getEncoded());
String clientKeyPath =
createTempFileWithContent(tempDir, "clientKey.key", clientTls.privateKey().getEncoded());
String clientCertificatePath =
createTempFileWithContent(
tempDir, "clientCertificate.cert", clientTls.certificate().getEncoded());
MetricExporter exporter =
MetricExporterFactory.getInstance()
.create(
new PushMetricExporterModel()
.withOtlpGrpc(
new OtlpGrpcMetricExporterModel()
.withEndpoint("http://example:4317")
.withHeaders(
Arrays.asList(
new NameStringValuePairModel()
.withName("key1")
.withValue("value1"),
new NameStringValuePairModel()
.withName("key2")
.withValue("value2")))
.withCompression("gzip")
.withTimeout(15_000)
.withCertificateFile(certificatePath)
.withClientKeyFile(clientKeyPath)
.withClientCertificateFile(clientCertificatePath)
.withTemporalityPreference(
OtlpHttpMetricExporterModel.ExporterTemporalityPreference.DELTA)
.withDefaultHistogramAggregation(
OtlpHttpMetricExporterModel.ExporterDefaultHistogramAggregation
.BASE_2_EXPONENTIAL_BUCKET_HISTOGRAM)),
spiHelper,
closeables);
cleanup.addCloseable(exporter);
cleanup.addCloseables(closeables);
assertThat(exporter.toString()).isEqualTo(expectedExporter.toString());
ArgumentCaptor<DeclarativeConfigProperties> configCaptor =
ArgumentCaptor.forClass(DeclarativeConfigProperties.class);
ComponentProvider<?> componentProvider =
getComponentProvider("otlp_grpc", MetricExporter.class);
verify(componentProvider).create(configCaptor.capture());
DeclarativeConfigProperties configProperties = configCaptor.getValue();
assertThat(configProperties.getString("endpoint")).isEqualTo("http://example:4317");
List<DeclarativeConfigProperties> headers = configProperties.getStructuredList("headers");
assertThat(headers)
.isNotNull()
.satisfiesExactly(
header -> {
assertThat(header.getString("name")).isEqualTo("key1");
assertThat(header.getString("value")).isEqualTo("value1");
},
header -> {
assertThat(header.getString("name")).isEqualTo("key2");
assertThat(header.getString("value")).isEqualTo("value2");
});
assertThat(configProperties.getString("compression")).isEqualTo("gzip");
assertThat(configProperties.getInt("timeout")).isEqualTo(Duration.ofSeconds(15).toMillis());
assertThat(configProperties.getString("certificate_file")).isEqualTo(certificatePath);
assertThat(configProperties.getString("client_key_file")).isEqualTo(clientKeyPath);
assertThat(configProperties.getString("client_certificate_file"))
.isEqualTo(clientCertificatePath);
assertThat(configProperties.getString("temporality_preference")).isEqualTo("delta");
assertThat(configProperties.getString("default_histogram_aggregation"))
.isEqualTo("base2_exponential_bucket_histogram");
@ -226,9 +354,7 @@ class MetricExporterFactoryTest {
io.opentelemetry.sdk.metrics.export.MetricExporter exporter =
MetricExporterFactory.getInstance()
.create(
new io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model
.PushMetricExporterModel()
.withConsole(new ConsoleModel()),
new PushMetricExporterModel().withConsole(new ConsoleExporterModel()),
spiHelper,
closeables);
cleanup.addCloseable(exporter);
@ -237,14 +363,38 @@ class MetricExporterFactoryTest {
assertThat(exporter.toString()).isEqualTo(expectedExporter.toString());
}
@Test
void create_OtlpFile() {
List<Closeable> closeables = new ArrayList<>();
OtlpStdoutMetricExporter expectedExporter = OtlpStdoutMetricExporter.builder().build();
cleanup.addCloseable(expectedExporter);
MetricExporter exporter =
MetricExporterFactory.getInstance()
.create(
new PushMetricExporterModel()
.withOtlpFileDevelopment(new ExperimentalOtlpFileMetricExporterModel()),
spiHelper,
closeables);
cleanup.addCloseable(exporter);
cleanup.addCloseables(closeables);
assertThat(exporter.toString()).isEqualTo(expectedExporter.toString());
ArgumentCaptor<DeclarativeConfigProperties> configCaptor =
ArgumentCaptor.forClass(DeclarativeConfigProperties.class);
ComponentProvider<?> componentProvider =
getComponentProvider("otlp_file/development", MetricExporter.class);
verify(componentProvider).create(configCaptor.capture());
}
@Test
void create_SpiExporter_Unknown() {
assertThatThrownBy(
() ->
MetricExporterFactory.getInstance()
.create(
new io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model
.PushMetricExporterModel()
new PushMetricExporterModel()
.withAdditionalProperty(
"unknown_key", ImmutableMap.of("key1", "value1")),
spiHelper,
@ -259,8 +409,7 @@ class MetricExporterFactoryTest {
MetricExporter metricExporter =
MetricExporterFactory.getInstance()
.create(
new io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model
.PushMetricExporterModel()
new PushMetricExporterModel()
.withAdditionalProperty("test", ImmutableMap.of("key1", "value1")),
spiHelper,
new ArrayList<>());

View File

@ -17,13 +17,16 @@ import io.opentelemetry.exporter.prometheus.PrometheusHttpServer;
import io.opentelemetry.internal.testing.CleanupExtension;
import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper;
import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.CardinalityLimitsModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalPrometheusMetricExporterModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricReaderModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpMetricModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpHttpMetricExporterModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PeriodicMetricReaderModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PrometheusModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PullMetricExporterModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PullMetricReaderModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PushMetricExporterModel;
import io.opentelemetry.sdk.metrics.InstrumentType;
import io.opentelemetry.sdk.metrics.export.MetricReader;
import java.io.Closeable;
import java.io.IOException;
import java.net.ServerSocket;
@ -66,20 +69,23 @@ class MetricReaderFactoryTest {
.build();
cleanup.addCloseable(expectedReader);
io.opentelemetry.sdk.metrics.export.MetricReader reader =
MetricReaderAndCardinalityLimits readerAndCardinalityLimits =
MetricReaderFactory.getInstance()
.create(
new MetricReaderModel()
.withPeriodic(
new PeriodicMetricReaderModel()
.withExporter(
new PushMetricExporterModel().withOtlp(new OtlpMetricModel()))),
new PushMetricExporterModel()
.withOtlpHttp(new OtlpHttpMetricExporterModel()))),
spiHelper,
closeables);
MetricReader reader = readerAndCardinalityLimits.getMetricReader();
cleanup.addCloseable(reader);
cleanup.addCloseables(closeables);
assertThat(reader.toString()).isEqualTo(expectedReader.toString());
assertThat(readerAndCardinalityLimits.getCardinalityLimitsSelector()).isNull();
}
@Test
@ -92,21 +98,29 @@ class MetricReaderFactoryTest {
.build();
cleanup.addCloseable(expectedReader);
io.opentelemetry.sdk.metrics.export.MetricReader reader =
MetricReaderAndCardinalityLimits readerAndCardinalityLimits =
MetricReaderFactory.getInstance()
.create(
new MetricReaderModel()
.withPeriodic(
new PeriodicMetricReaderModel()
.withExporter(
new PushMetricExporterModel().withOtlp(new OtlpMetricModel()))
.withInterval(1)),
new PushMetricExporterModel()
.withOtlpHttp(new OtlpHttpMetricExporterModel()))
.withInterval(1)
.withCardinalityLimits(new CardinalityLimitsModel().withDefault(100))),
spiHelper,
closeables);
MetricReader reader = readerAndCardinalityLimits.getMetricReader();
cleanup.addCloseable(reader);
cleanup.addCloseables(closeables);
assertThat(reader.toString()).isEqualTo(expectedReader.toString());
assertThat(
readerAndCardinalityLimits
.getCardinalityLimitsSelector()
.getCardinalityLimit(InstrumentType.COUNTER))
.isEqualTo(100);
}
@Test
@ -118,7 +132,7 @@ class MetricReaderFactoryTest {
// Close the reader to avoid port conflict with the new instance created by MetricReaderFactory
expectedReader.close();
io.opentelemetry.sdk.metrics.export.MetricReader reader =
MetricReaderAndCardinalityLimits readerAndCardinalityLimits =
MetricReaderFactory.getInstance()
.create(
new MetricReaderModel()
@ -126,13 +140,18 @@ class MetricReaderFactoryTest {
new PullMetricReaderModel()
.withExporter(
new PullMetricExporterModel()
.withPrometheus(new PrometheusModel().withPort(port)))),
.withPrometheusDevelopment(
new ExperimentalPrometheusMetricExporterModel()
.withPort(port)))),
spiHelper,
closeables);
io.opentelemetry.sdk.metrics.export.MetricReader reader =
readerAndCardinalityLimits.getMetricReader();
cleanup.addCloseable(reader);
cleanup.addCloseables(closeables);
assertThat(reader.toString()).isEqualTo(expectedReader.toString());
assertThat(readerAndCardinalityLimits.getCardinalityLimitsSelector()).isNull();
// TODO(jack-berg): validate prometheus component provider was invoked with correct arguments
verify(spiHelper).load(ComponentProvider.class);
}
@ -148,7 +167,7 @@ class MetricReaderFactoryTest {
// Close the reader to avoid port conflict with the new instance created by MetricReaderFactory
expectedReader.close();
io.opentelemetry.sdk.metrics.export.MetricReader reader =
MetricReaderAndCardinalityLimits readerAndCardinalityLimits =
MetricReaderFactory.getInstance()
.create(
new MetricReaderModel()
@ -156,16 +175,24 @@ class MetricReaderFactoryTest {
new PullMetricReaderModel()
.withExporter(
new PullMetricExporterModel()
.withPrometheus(
new PrometheusModel()
.withPrometheusDevelopment(
new ExperimentalPrometheusMetricExporterModel()
.withHost("localhost")
.withPort(port)))),
.withPort(port)))
.withCardinalityLimits(new CardinalityLimitsModel().withDefault(100))),
spiHelper,
closeables);
io.opentelemetry.sdk.metrics.export.MetricReader reader =
readerAndCardinalityLimits.getMetricReader();
cleanup.addCloseable(reader);
cleanup.addCloseables(closeables);
assertThat(reader.toString()).isEqualTo(expectedReader.toString());
assertThat(
readerAndCardinalityLimits
.getCardinalityLimitsSelector()
.getCardinalityLimit(InstrumentType.COUNTER))
.isEqualTo(100);
// TODO(jack-berg): validate prometheus component provider was invoked with correct arguments
verify(spiHelper).load(ComponentProvider.class);
}

View File

@ -23,10 +23,12 @@ import io.opentelemetry.extension.trace.propagation.OtTracePropagator;
import io.opentelemetry.internal.testing.CleanupExtension;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AlwaysOnModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AlwaysOnSamplerModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributeNameValueModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.BatchLogRecordProcessorModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.BatchSpanProcessorModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalResourceDetectionModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalResourceDetectorModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordExporterModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordLimitsModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.LogRecordProcessorModel;
@ -34,19 +36,21 @@ import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.Logger
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MeterProviderModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.MetricReaderModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTelemetryConfigurationModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpMetricModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpHttpExporterModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpHttpMetricExporterModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PeriodicMetricReaderModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PropagatorModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PushMetricExporterModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ResourceModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SamplerModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SelectorModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SimpleLogRecordProcessorModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanExporterModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanLimitsModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanProcessorModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.StreamModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.TracerProviderModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ViewModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ViewSelectorModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ViewStreamModel;
import io.opentelemetry.sdk.logs.LogLimits;
import io.opentelemetry.sdk.logs.SdkLoggerProvider;
import io.opentelemetry.sdk.metrics.InstrumentSelector;
@ -83,7 +87,7 @@ class OpenTelemetryConfigurationFactoryTest {
OpenTelemetryConfigurationFactory.getInstance()
.create(testCase, spiHelper, closeables))
.isInstanceOf(DeclarativeConfigException.class)
.hasMessage("Unsupported file format. Supported formats include: 0.3");
.hasMessage("Unsupported file format. Supported formats include: 0.4");
cleanup.addCloseables(closeables);
}
}
@ -97,7 +101,7 @@ class OpenTelemetryConfigurationFactoryTest {
OpenTelemetrySdk sdk =
OpenTelemetryConfigurationFactory.getInstance()
.create(
new OpenTelemetryConfigurationModel().withFileFormat("0.3"), spiHelper, closeables);
new OpenTelemetryConfigurationModel().withFileFormat("0.4"), spiHelper, closeables);
cleanup.addCloseable(sdk);
cleanup.addCloseables(closeables);
@ -114,7 +118,7 @@ class OpenTelemetryConfigurationFactoryTest {
OpenTelemetryConfigurationFactory.getInstance()
.create(
new OpenTelemetryConfigurationModel()
.withFileFormat("0.3")
.withFileFormat("0.4")
.withDisabled(true)
// Logger provider configuration should be ignored since SDK is disabled
.withLoggerProvider(
@ -126,7 +130,8 @@ class OpenTelemetryConfigurationFactoryTest {
new SimpleLogRecordProcessorModel()
.withExporter(
new LogRecordExporterModel()
.withOtlp(new OtlpModel())))))),
.withOtlpHttp(
new OtlpHttpExporterModel())))))),
spiHelper,
closeables);
cleanup.addCloseable(sdk);
@ -208,19 +213,22 @@ class OpenTelemetryConfigurationFactoryTest {
OpenTelemetryConfigurationFactory.getInstance()
.create(
new OpenTelemetryConfigurationModel()
.withFileFormat("0.3")
.withFileFormat("0.4")
.withPropagator(
new PropagatorModel()
.withComposite(
Arrays.asList(
"tracecontext",
"baggage",
"ottrace",
"b3multi",
"b3",
"jaeger")))
.withCompositeList("tracecontext,baggage,ottrace,b3multi,b3,jaeger"))
.withResource(
new ResourceModel()
.withDetectionDevelopment(
new ExperimentalResourceDetectionModel()
.withDetectors(
Arrays.asList(
new ExperimentalResourceDetectorModel()
.withAdditionalProperty("order_first", null),
new ExperimentalResourceDetectorModel()
.withAdditionalProperty("order_second", null),
new ExperimentalResourceDetectorModel()
.withAdditionalProperty("shape_color", null))))
.withAttributes(
Arrays.asList(
new AttributeNameValueModel()
@ -242,19 +250,20 @@ class OpenTelemetryConfigurationFactoryTest {
new BatchLogRecordProcessorModel()
.withExporter(
new LogRecordExporterModel()
.withOtlp(new OtlpModel()))))))
.withOtlpHttp(
new OtlpHttpExporterModel()))))))
.withTracerProvider(
new TracerProviderModel()
.withLimits(
new io.opentelemetry.sdk.extension.incubator.fileconfig.internal
.model.SpanLimitsModel()
new SpanLimitsModel()
.withAttributeCountLimit(1)
.withAttributeValueLengthLimit(2)
.withEventCountLimit(3)
.withLinkCountLimit(4)
.withEventAttributeCountLimit(5)
.withLinkAttributeCountLimit(6))
.withSampler(new SamplerModel().withAlwaysOn(new AlwaysOnModel()))
.withSampler(
new SamplerModel().withAlwaysOn(new AlwaysOnSamplerModel()))
.withProcessors(
Collections.singletonList(
new SpanProcessorModel()
@ -262,7 +271,8 @@ class OpenTelemetryConfigurationFactoryTest {
new BatchSpanProcessorModel()
.withExporter(
new SpanExporterModel()
.withOtlp(new OtlpModel()))))))
.withOtlpHttp(
new OtlpHttpExporterModel()))))))
.withMeterProvider(
new MeterProviderModel()
.withReaders(
@ -272,16 +282,16 @@ class OpenTelemetryConfigurationFactoryTest {
new PeriodicMetricReaderModel()
.withExporter(
new PushMetricExporterModel()
.withOtlp(new OtlpMetricModel())))))
.withOtlpHttp(
new OtlpHttpMetricExporterModel())))))
.withViews(
Collections.singletonList(
new io.opentelemetry.sdk.extension.incubator.fileconfig.internal
.model.ViewModel()
new ViewModel()
.withSelector(
new SelectorModel()
new ViewSelectorModel()
.withInstrumentName("instrument-name"))
.withStream(
new StreamModel()
new ViewStreamModel()
.withName("stream-name")
.withAttributeKeys(null))))),
spiHelper,

View File

@ -6,8 +6,11 @@
package io.opentelemetry.sdk.extension.incubator.fileconfig;
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import io.opentelemetry.api.baggage.propagation.W3CBaggagePropagator;
import io.opentelemetry.api.incubator.config.DeclarativeConfigException;
import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties;
import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator;
import io.opentelemetry.context.propagation.ContextPropagators;
import io.opentelemetry.context.propagation.TextMapPropagator;
@ -15,10 +18,19 @@ import io.opentelemetry.extension.trace.propagation.B3Propagator;
import io.opentelemetry.extension.trace.propagation.JaegerPropagator;
import io.opentelemetry.extension.trace.propagation.OtTracePropagator;
import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper;
import io.opentelemetry.sdk.extension.incubator.fileconfig.component.TextMapPropagatorComponentProvider;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.B3MultiPropagatorModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.B3PropagatorModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.BaggagePropagatorModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.JaegerPropagatorModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OpenTracingPropagatorModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.PropagatorModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.TextMapPropagatorModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.TraceContextPropagatorModel;
import java.util.Arrays;
import java.util.Collections;
import java.util.stream.Stream;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
@ -39,10 +51,18 @@ class PropagatorFactoryTest {
private static Stream<Arguments> createArguments() {
return Stream.of(
// structured list
Arguments.of(
new PropagatorModel()
.withComposite(
Arrays.asList("tracecontext", "baggage", "ottrace", "b3multi", "b3", "jaeger")),
Arrays.asList(
new TextMapPropagatorModel()
.withTracecontext(new TraceContextPropagatorModel()),
new TextMapPropagatorModel().withBaggage(new BaggagePropagatorModel()),
new TextMapPropagatorModel().withOttrace(new OpenTracingPropagatorModel()),
new TextMapPropagatorModel().withB3multi(new B3MultiPropagatorModel()),
new TextMapPropagatorModel().withB3(new B3PropagatorModel()),
new TextMapPropagatorModel().withJaeger(new JaegerPropagatorModel()))),
ContextPropagators.create(
TextMapPropagator.composite(
W3CTraceContextPropagator.getInstance(),
@ -50,6 +70,82 @@ class PropagatorFactoryTest {
OtTracePropagator.getInstance(),
B3Propagator.injectingMultiHeaders(),
B3Propagator.injectingSingleHeader(),
JaegerPropagator.getInstance()))));
JaegerPropagator.getInstance()))),
// string list
Arguments.of(
new PropagatorModel()
.withCompositeList("tracecontext,baggage,ottrace,b3multi,b3,jaeger ,none"),
ContextPropagators.create(
TextMapPropagator.composite(
W3CTraceContextPropagator.getInstance(),
W3CBaggagePropagator.getInstance(),
OtTracePropagator.getInstance(),
B3Propagator.injectingMultiHeaders(),
B3Propagator.injectingSingleHeader(),
JaegerPropagator.getInstance()))),
// structured list and string list
Arguments.of(
new PropagatorModel()
.withComposite(
Arrays.asList(
new TextMapPropagatorModel()
.withTracecontext(new TraceContextPropagatorModel()),
new TextMapPropagatorModel().withBaggage(new BaggagePropagatorModel())))
.withCompositeList("ottrace,b3multi,b3,jaeger"),
ContextPropagators.create(
TextMapPropagator.composite(
W3CTraceContextPropagator.getInstance(),
W3CBaggagePropagator.getInstance(),
OtTracePropagator.getInstance(),
B3Propagator.injectingMultiHeaders(),
B3Propagator.injectingSingleHeader(),
JaegerPropagator.getInstance()))),
// structured list and string list with overlap
Arguments.of(
new PropagatorModel()
.withComposite(
Arrays.asList(
new TextMapPropagatorModel()
.withTracecontext(new TraceContextPropagatorModel()),
new TextMapPropagatorModel().withBaggage(new BaggagePropagatorModel())))
.withCompositeList("tracecontext,ottrace,b3multi,b3,jaeger"),
ContextPropagators.create(
TextMapPropagator.composite(
W3CTraceContextPropagator.getInstance(),
W3CBaggagePropagator.getInstance(),
OtTracePropagator.getInstance(),
B3Propagator.injectingMultiHeaders(),
B3Propagator.injectingSingleHeader(),
JaegerPropagator.getInstance()))),
// spi
Arguments.of(
new PropagatorModel()
.withComposite(
Collections.singletonList(
new TextMapPropagatorModel().withAdditionalProperty("test", null))),
ContextPropagators.create(
TextMapPropagator.composite(
new TextMapPropagatorComponentProvider.TestTextMapPropagator(
DeclarativeConfigProperties.empty())))),
Arguments.of(
new PropagatorModel().withCompositeList("test"),
ContextPropagators.create(
TextMapPropagator.composite(
new TextMapPropagatorComponentProvider.TestTextMapPropagator(
DeclarativeConfigProperties.empty())))));
}
@Test
void create_SpiPropagator_Unknown() {
assertThatThrownBy(
() ->
PropagatorFactory.getInstance()
.create(
new PropagatorModel().withCompositeList("foo"),
spiHelper,
Collections.emptyList()))
.isInstanceOf(DeclarativeConfigException.class)
.hasMessage(
"No component provider detected for io.opentelemetry.context.propagation.TextMapPropagator with name \"foo\".");
}
}

View File

@ -6,12 +6,15 @@
package io.opentelemetry.sdk.extension.incubator.fileconfig;
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import static org.mockito.Mockito.spy;
import io.opentelemetry.api.incubator.config.DeclarativeConfigException;
import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributeNameValueModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.DetectorAttributesModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.DetectorsModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalResourceDetectionModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalResourceDetectorModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.IncludeExcludeModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ResourceModel;
import io.opentelemetry.sdk.resources.Resource;
import java.util.Arrays;
@ -48,14 +51,9 @@ class ResourceFactoryTest {
Collections.emptyList()))
.isEqualTo(
Resource.getDefault().toBuilder()
.put("shape", "circle")
.put("service.name", "my-service")
.put("key", "val")
.put("shape", "circle")
// From ResourceComponentProvider
.put("color", "red")
// From ResourceOrderedSecondComponentProvider, which takes priority over
// ResourceOrderedFirstComponentProvider
.put("order", "second")
.build());
}
@ -65,12 +63,18 @@ class ResourceFactoryTest {
@Nullable List<String> included, @Nullable List<String> excluded, Resource expectedResource) {
ResourceModel resourceModel =
new ResourceModel()
.withDetectors(
new DetectorsModel()
.withDetectionDevelopment(
new ExperimentalResourceDetectionModel()
.withDetectors(
Arrays.asList(
new ExperimentalResourceDetectorModel()
.withAdditionalProperty("order_first", null),
new ExperimentalResourceDetectorModel()
.withAdditionalProperty("order_second", null),
new ExperimentalResourceDetectorModel()
.withAdditionalProperty("shape_color", null)))
.withAttributes(
new DetectorAttributesModel()
.withIncluded(included)
.withExcluded(excluded)));
new IncludeExcludeModel().withIncluded(included).withExcluded(excluded)));
Resource resource =
ResourceFactory.getInstance().create(resourceModel, spiHelper, Collections.emptyList());
assertThat(resource).isEqualTo(expectedResource);
@ -140,4 +144,43 @@ class ResourceFactoryTest {
Collections.singletonList("order"),
Resource.getDefault().toBuilder().put("color", "red").build()));
}
@ParameterizedTest
@MethodSource("createInvalidDetectorsArgs")
void createWithDetectors_Invalid(ResourceModel model, String expectedMessage) {
assertThatThrownBy(
() -> ResourceFactory.getInstance().create(model, spiHelper, Collections.emptyList()))
.isInstanceOf(DeclarativeConfigException.class)
.hasMessage(expectedMessage);
}
private static Stream<Arguments> createInvalidDetectorsArgs() {
return Stream.of(
Arguments.of(
new ResourceModel()
.withDetectionDevelopment(
new ExperimentalResourceDetectionModel()
.withDetectors(
Collections.singletonList(
new ExperimentalResourceDetectorModel()
.withAdditionalProperty("foo", null)))),
"No component provider detected for io.opentelemetry.sdk.resources.Resource with name \"foo\"."),
Arguments.of(
new ResourceModel()
.withDetectionDevelopment(
new ExperimentalResourceDetectionModel()
.withDetectors(
Collections.singletonList(
new ExperimentalResourceDetectorModel()
.withAdditionalProperty("foo", null)
.withAdditionalProperty("bar", null)))),
"Invalid configuration - multiple resource detectors set: [foo,bar]"),
Arguments.of(
new ResourceModel()
.withDetectionDevelopment(
new ExperimentalResourceDetectionModel()
.withDetectors(
Collections.singletonList(new ExperimentalResourceDetectorModel()))),
"resource detector must be set"));
}
}

View File

@ -14,12 +14,12 @@ import io.opentelemetry.internal.testing.CleanupExtension;
import io.opentelemetry.internal.testing.slf4j.SuppressLogger;
import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper;
import io.opentelemetry.sdk.extension.incubator.fileconfig.component.SamplerComponentProvider;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AlwaysOffModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AlwaysOnModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.JaegerRemoteModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ParentBasedModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AlwaysOffSamplerModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AlwaysOnSamplerModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.JaegerRemoteSamplerModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ParentBasedSamplerModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SamplerModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.TraceIdRatioBasedModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.TraceIdRatioBasedSamplerModel;
import io.opentelemetry.sdk.extension.trace.jaeger.sampler.JaegerRemoteSampler;
import java.io.Closeable;
import java.time.Duration;
@ -62,45 +62,46 @@ class SamplerFactoryTest {
private static Stream<Arguments> createArguments() {
return Stream.of(
Arguments.of(
new SamplerModel().withAlwaysOn(new AlwaysOnModel()),
new SamplerModel().withAlwaysOn(new AlwaysOnSamplerModel()),
io.opentelemetry.sdk.trace.samplers.Sampler.alwaysOn()),
Arguments.of(
new SamplerModel().withAlwaysOff(new AlwaysOffModel()),
new SamplerModel().withAlwaysOff(new AlwaysOffSamplerModel()),
io.opentelemetry.sdk.trace.samplers.Sampler.alwaysOff()),
Arguments.of(
new SamplerModel().withTraceIdRatioBased(new TraceIdRatioBasedModel()),
new SamplerModel().withTraceIdRatioBased(new TraceIdRatioBasedSamplerModel()),
io.opentelemetry.sdk.trace.samplers.Sampler.traceIdRatioBased(1.0d)),
Arguments.of(
new SamplerModel().withTraceIdRatioBased(new TraceIdRatioBasedModel().withRatio(0.5d)),
new SamplerModel()
.withTraceIdRatioBased(new TraceIdRatioBasedSamplerModel().withRatio(0.5d)),
io.opentelemetry.sdk.trace.samplers.Sampler.traceIdRatioBased(0.5)),
Arguments.of(
new SamplerModel().withParentBased(new ParentBasedModel()),
new SamplerModel().withParentBased(new ParentBasedSamplerModel()),
io.opentelemetry.sdk.trace.samplers.Sampler.parentBased(
io.opentelemetry.sdk.trace.samplers.Sampler.alwaysOn())),
Arguments.of(
new SamplerModel()
.withParentBased(
new ParentBasedModel()
new ParentBasedSamplerModel()
.withRoot(
new SamplerModel()
.withTraceIdRatioBased(
new TraceIdRatioBasedModel().withRatio(0.1d)))
new TraceIdRatioBasedSamplerModel().withRatio(0.1d)))
.withRemoteParentSampled(
new SamplerModel()
.withTraceIdRatioBased(
new TraceIdRatioBasedModel().withRatio(0.2d)))
new TraceIdRatioBasedSamplerModel().withRatio(0.2d)))
.withRemoteParentNotSampled(
new SamplerModel()
.withTraceIdRatioBased(
new TraceIdRatioBasedModel().withRatio(0.3d)))
new TraceIdRatioBasedSamplerModel().withRatio(0.3d)))
.withLocalParentSampled(
new SamplerModel()
.withTraceIdRatioBased(
new TraceIdRatioBasedModel().withRatio(0.4d)))
new TraceIdRatioBasedSamplerModel().withRatio(0.4d)))
.withLocalParentNotSampled(
new SamplerModel()
.withTraceIdRatioBased(
new TraceIdRatioBasedModel().withRatio(0.5d)))),
new TraceIdRatioBasedSamplerModel().withRatio(0.5d)))),
io.opentelemetry.sdk.trace.samplers.Sampler.parentBasedBuilder(
io.opentelemetry.sdk.trace.samplers.Sampler.traceIdRatioBased(0.1d))
.setRemoteParentSampled(
@ -115,11 +116,11 @@ class SamplerFactoryTest {
Arguments.of(
new SamplerModel()
.withJaegerRemote(
new JaegerRemoteModel()
new JaegerRemoteSamplerModel()
.withEndpoint("http://jaeger-remote-endpoint")
.withInterval(10_000)
.withInitialSampler(
new SamplerModel().withAlwaysOff(new AlwaysOffModel()))),
new SamplerModel().withAlwaysOff(new AlwaysOffSamplerModel()))),
JaegerRemoteSampler.builder()
.setEndpoint("http://jaeger-remote-endpoint")
.setPollingInterval(Duration.ofSeconds(10))

View File

@ -17,16 +17,21 @@ import com.linecorp.armeria.testing.junit5.server.SelfSignedCertificateExtension
import io.opentelemetry.api.incubator.config.DeclarativeConfigException;
import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties;
import io.opentelemetry.exporter.logging.LoggingSpanExporter;
import io.opentelemetry.exporter.logging.otlp.internal.traces.OtlpStdoutSpanExporter;
import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporter;
import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter;
import io.opentelemetry.exporter.zipkin.ZipkinSpanExporter;
import io.opentelemetry.internal.testing.CleanupExtension;
import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper;
import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider;
import io.opentelemetry.sdk.extension.incubator.fileconfig.component.SpanExporterComponentProvider;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ConsoleModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ConsoleExporterModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalOtlpFileExporterModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.NameStringValuePairModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ZipkinModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpGrpcExporterModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpHttpExporterModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanExporterModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ZipkinSpanExporterModel;
import io.opentelemetry.sdk.trace.export.SpanExporter;
import java.io.Closeable;
import java.io.IOException;
@ -90,7 +95,7 @@ class SpanExporterFactoryTest {
}
@Test
void create_OtlpDefaults() {
void create_OtlpHttpDefaults() {
List<Closeable> closeables = new ArrayList<>();
OtlpHttpSpanExporter expectedExporter = OtlpHttpSpanExporter.getDefault();
cleanup.addCloseable(expectedExporter);
@ -98,9 +103,7 @@ class SpanExporterFactoryTest {
SpanExporter exporter =
SpanExporterFactory.getInstance()
.create(
new io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model
.SpanExporterModel()
.withOtlp(new OtlpModel()),
new SpanExporterModel().withOtlpHttp(new OtlpHttpExporterModel()),
spiHelper,
closeables);
cleanup.addCloseable(exporter);
@ -110,7 +113,7 @@ class SpanExporterFactoryTest {
ArgumentCaptor<DeclarativeConfigProperties> configCaptor =
ArgumentCaptor.forClass(DeclarativeConfigProperties.class);
ComponentProvider<?> componentProvider = getComponentProvider("otlp", SpanExporter.class);
ComponentProvider<?> componentProvider = getComponentProvider("otlp_http", SpanExporter.class);
verify(componentProvider).create(configCaptor.capture());
DeclarativeConfigProperties configProperties = configCaptor.getValue();
assertThat(configProperties.getString("protocol")).isNull();
@ -118,13 +121,13 @@ class SpanExporterFactoryTest {
assertThat(configProperties.getStructured("headers")).isNull();
assertThat(configProperties.getString("compression")).isNull();
assertThat(configProperties.getInt("timeout")).isNull();
assertThat(configProperties.getString("certificate")).isNull();
assertThat(configProperties.getString("client_key")).isNull();
assertThat(configProperties.getString("client_certificate")).isNull();
assertThat(configProperties.getString("certificate_file")).isNull();
assertThat(configProperties.getString("client_key_file")).isNull();
assertThat(configProperties.getString("client_certificate_file")).isNull();
}
@Test
void create_OtlpConfigured(@TempDir Path tempDir)
void create_OtlpHttpConfigured(@TempDir Path tempDir)
throws CertificateEncodingException, IOException {
List<Closeable> closeables = new ArrayList<>();
OtlpHttpSpanExporter expectedExporter =
@ -150,11 +153,9 @@ class SpanExporterFactoryTest {
SpanExporter exporter =
SpanExporterFactory.getInstance()
.create(
new io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model
.SpanExporterModel()
.withOtlp(
new OtlpModel()
.withProtocol("http/protobuf")
new SpanExporterModel()
.withOtlpHttp(
new OtlpHttpExporterModel()
.withEndpoint("http://example:4318/v1/traces")
.withHeaders(
Arrays.asList(
@ -166,9 +167,9 @@ class SpanExporterFactoryTest {
.withValue("value2")))
.withCompression("gzip")
.withTimeout(15_000)
.withCertificate(certificatePath)
.withClientKey(clientKeyPath)
.withClientCertificate(clientCertificatePath)),
.withCertificateFile(certificatePath)
.withClientKeyFile(clientKeyPath)
.withClientCertificateFile(clientCertificatePath)),
spiHelper,
closeables);
cleanup.addCloseable(exporter);
@ -178,10 +179,9 @@ class SpanExporterFactoryTest {
ArgumentCaptor<DeclarativeConfigProperties> configCaptor =
ArgumentCaptor.forClass(DeclarativeConfigProperties.class);
ComponentProvider<?> componentProvider = getComponentProvider("otlp", SpanExporter.class);
ComponentProvider<?> componentProvider = getComponentProvider("otlp_http", SpanExporter.class);
verify(componentProvider).create(configCaptor.capture());
DeclarativeConfigProperties configProperties = configCaptor.getValue();
assertThat(configProperties.getString("protocol")).isEqualTo("http/protobuf");
assertThat(configProperties.getString("endpoint")).isEqualTo("http://example:4318/v1/traces");
List<DeclarativeConfigProperties> headers = configProperties.getStructuredList("headers");
assertThat(headers)
@ -197,9 +197,118 @@ class SpanExporterFactoryTest {
});
assertThat(configProperties.getString("compression")).isEqualTo("gzip");
assertThat(configProperties.getInt("timeout")).isEqualTo(Duration.ofSeconds(15).toMillis());
assertThat(configProperties.getString("certificate")).isEqualTo(certificatePath);
assertThat(configProperties.getString("client_key")).isEqualTo(clientKeyPath);
assertThat(configProperties.getString("client_certificate")).isEqualTo(clientCertificatePath);
assertThat(configProperties.getString("certificate_file")).isEqualTo(certificatePath);
assertThat(configProperties.getString("client_key_file")).isEqualTo(clientKeyPath);
assertThat(configProperties.getString("client_certificate_file"))
.isEqualTo(clientCertificatePath);
}
@Test
void create_OtlpGrpcDefaults() {
List<Closeable> closeables = new ArrayList<>();
OtlpGrpcSpanExporter expectedExporter = OtlpGrpcSpanExporter.getDefault();
cleanup.addCloseable(expectedExporter);
SpanExporter exporter =
SpanExporterFactory.getInstance()
.create(
new SpanExporterModel().withOtlpGrpc(new OtlpGrpcExporterModel()),
spiHelper,
closeables);
cleanup.addCloseable(exporter);
cleanup.addCloseables(closeables);
assertThat(exporter.toString()).isEqualTo(expectedExporter.toString());
ArgumentCaptor<DeclarativeConfigProperties> configCaptor =
ArgumentCaptor.forClass(DeclarativeConfigProperties.class);
ComponentProvider<?> componentProvider = getComponentProvider("otlp_grpc", SpanExporter.class);
verify(componentProvider).create(configCaptor.capture());
DeclarativeConfigProperties configProperties = configCaptor.getValue();
assertThat(configProperties.getString("endpoint")).isNull();
assertThat(configProperties.getStructured("headers")).isNull();
assertThat(configProperties.getString("compression")).isNull();
assertThat(configProperties.getInt("timeout")).isNull();
assertThat(configProperties.getString("certificate_file")).isNull();
assertThat(configProperties.getString("client_key_file")).isNull();
assertThat(configProperties.getString("client_certificate_file")).isNull();
}
@Test
void create_OtlpGrpcConfigured(@TempDir Path tempDir)
throws CertificateEncodingException, IOException {
List<Closeable> closeables = new ArrayList<>();
OtlpGrpcSpanExporter expectedExporter =
OtlpGrpcSpanExporter.builder()
.setEndpoint("http://example:4317")
.addHeader("key1", "value1")
.addHeader("key2", "value2")
.setTimeout(Duration.ofSeconds(15))
.setCompression("gzip")
.build();
cleanup.addCloseable(expectedExporter);
// Write certificates to temp files
String certificatePath =
createTempFileWithContent(
tempDir, "certificate.cert", serverTls.certificate().getEncoded());
String clientKeyPath =
createTempFileWithContent(tempDir, "clientKey.key", clientTls.privateKey().getEncoded());
String clientCertificatePath =
createTempFileWithContent(
tempDir, "clientCertificate.cert", clientTls.certificate().getEncoded());
SpanExporter exporter =
SpanExporterFactory.getInstance()
.create(
new SpanExporterModel()
.withOtlpGrpc(
new OtlpGrpcExporterModel()
.withEndpoint("http://example:4317")
.withHeaders(
Arrays.asList(
new NameStringValuePairModel()
.withName("key1")
.withValue("value1"),
new NameStringValuePairModel()
.withName("key2")
.withValue("value2")))
.withCompression("gzip")
.withTimeout(15_000)
.withCertificateFile(certificatePath)
.withClientKeyFile(clientKeyPath)
.withClientCertificateFile(clientCertificatePath)),
spiHelper,
closeables);
cleanup.addCloseable(exporter);
cleanup.addCloseables(closeables);
assertThat(exporter.toString()).isEqualTo(expectedExporter.toString());
ArgumentCaptor<DeclarativeConfigProperties> configCaptor =
ArgumentCaptor.forClass(DeclarativeConfigProperties.class);
ComponentProvider<?> componentProvider = getComponentProvider("otlp_grpc", SpanExporter.class);
verify(componentProvider).create(configCaptor.capture());
DeclarativeConfigProperties configProperties = configCaptor.getValue();
assertThat(configProperties.getString("endpoint")).isEqualTo("http://example:4317");
List<DeclarativeConfigProperties> headers = configProperties.getStructuredList("headers");
assertThat(headers)
.isNotNull()
.satisfiesExactly(
header -> {
assertThat(header.getString("name")).isEqualTo("key1");
assertThat(header.getString("value")).isEqualTo("value1");
},
header -> {
assertThat(header.getString("name")).isEqualTo("key2");
assertThat(header.getString("value")).isEqualTo("value2");
});
assertThat(configProperties.getString("compression")).isEqualTo("gzip");
assertThat(configProperties.getInt("timeout")).isEqualTo(Duration.ofSeconds(15).toMillis());
assertThat(configProperties.getString("certificate_file")).isEqualTo(certificatePath);
assertThat(configProperties.getString("client_key_file")).isEqualTo(clientKeyPath);
assertThat(configProperties.getString("client_certificate_file"))
.isEqualTo(clientCertificatePath);
}
@Test
@ -211,9 +320,7 @@ class SpanExporterFactoryTest {
SpanExporter exporter =
SpanExporterFactory.getInstance()
.create(
new io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model
.SpanExporterModel()
.withConsole(new ConsoleModel()),
new SpanExporterModel().withConsole(new ConsoleExporterModel()),
spiHelper,
closeables);
cleanup.addCloseable(exporter);
@ -232,9 +339,7 @@ class SpanExporterFactoryTest {
SpanExporter exporter =
SpanExporterFactory.getInstance()
.create(
new io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model
.SpanExporterModel()
.withZipkin(new ZipkinModel()),
new SpanExporterModel().withZipkin(new ZipkinSpanExporterModel()),
spiHelper,
closeables);
cleanup.addCloseable(exporter);
@ -264,10 +369,9 @@ class SpanExporterFactoryTest {
SpanExporter exporter =
SpanExporterFactory.getInstance()
.create(
new io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model
.SpanExporterModel()
new SpanExporterModel()
.withZipkin(
new ZipkinModel()
new ZipkinSpanExporterModel()
.withEndpoint("http://zipkin:9411/v1/v2/spans")
.withTimeout(15_000)),
spiHelper,
@ -286,6 +390,31 @@ class SpanExporterFactoryTest {
assertThat(configProperties.getLong("timeout")).isEqualTo(15_000);
}
@Test
void create_OtlpFile() {
List<Closeable> closeables = new ArrayList<>();
OtlpStdoutSpanExporter expectedExporter = OtlpStdoutSpanExporter.builder().build();
cleanup.addCloseable(expectedExporter);
SpanExporter exporter =
SpanExporterFactory.getInstance()
.create(
new SpanExporterModel()
.withOtlpFileDevelopment(new ExperimentalOtlpFileExporterModel()),
spiHelper,
closeables);
cleanup.addCloseable(exporter);
cleanup.addCloseables(closeables);
assertThat(exporter.toString()).isEqualTo(expectedExporter.toString());
ArgumentCaptor<DeclarativeConfigProperties> configCaptor =
ArgumentCaptor.forClass(DeclarativeConfigProperties.class);
ComponentProvider<?> componentProvider =
getComponentProvider("otlp_file/development", SpanExporter.class);
verify(componentProvider).create(configCaptor.capture());
}
@Test
void create_SpiExporter_Unknown() {
List<Closeable> closeables = new ArrayList<>();
@ -294,8 +423,7 @@ class SpanExporterFactoryTest {
() ->
SpanExporterFactory.getInstance()
.create(
new io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model
.SpanExporterModel()
new SpanExporterModel()
.withAdditionalProperty(
"unknown_key", ImmutableMap.of("key1", "value1")),
spiHelper,
@ -311,8 +439,7 @@ class SpanExporterFactoryTest {
SpanExporter spanExporter =
SpanExporterFactory.getInstance()
.create(
new io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model
.SpanExporterModel()
new SpanExporterModel()
.withAdditionalProperty("test", ImmutableMap.of("key1", "value1")),
spiHelper,
new ArrayList<>());

View File

@ -15,7 +15,7 @@ import io.opentelemetry.internal.testing.CleanupExtension;
import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper;
import io.opentelemetry.sdk.extension.incubator.fileconfig.component.SpanProcessorComponentProvider;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.BatchSpanProcessorModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpHttpExporterModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SimpleSpanProcessorModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanExporterModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanProcessorModel;
@ -63,7 +63,8 @@ class SpanProcessorFactoryTest {
new SpanProcessorModel()
.withBatch(
new BatchSpanProcessorModel()
.withExporter(new SpanExporterModel().withOtlp(new OtlpModel()))),
.withExporter(
new SpanExporterModel().withOtlpHttp(new OtlpHttpExporterModel()))),
spiHelper,
closeables);
cleanup.addCloseable(processor);
@ -90,7 +91,8 @@ class SpanProcessorFactoryTest {
new SpanProcessorModel()
.withBatch(
new BatchSpanProcessorModel()
.withExporter(new SpanExporterModel().withOtlp(new OtlpModel()))
.withExporter(
new SpanExporterModel().withOtlpHttp(new OtlpHttpExporterModel()))
.withScheduleDelay(1)
.withMaxExportBatchSize(2)
.withExportTimeout(3)),
@ -129,7 +131,8 @@ class SpanProcessorFactoryTest {
new SpanProcessorModel()
.withSimple(
new SimpleSpanProcessorModel()
.withExporter(new SpanExporterModel().withOtlp(new OtlpModel()))),
.withExporter(
new SpanExporterModel().withOtlpHttp(new OtlpHttpExporterModel()))),
spiHelper,
closeables);
cleanup.addCloseable(processor);

View File

@ -29,12 +29,12 @@ public class TestDeclarativeConfigurationCustomizerProvider
attributes.add(
new AttributeNameValueModel()
.withName("foo")
.withType(AttributeNameValueModel.Type.STRING)
.withType(AttributeNameValueModel.AttributeType.STRING)
.withValue("bar"));
attributes.add(
new AttributeNameValueModel()
.withName("color")
.withType(AttributeNameValueModel.Type.STRING)
.withType(AttributeNameValueModel.AttributeType.STRING)
.withValue("blue"));
return model;
});

View File

@ -1,97 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.sdk.extension.incubator.fileconfig;
import static io.opentelemetry.sdk.testing.assertj.OpenTelemetryAssertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import io.opentelemetry.api.baggage.propagation.W3CBaggagePropagator;
import io.opentelemetry.api.incubator.config.DeclarativeConfigException;
import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator;
import io.opentelemetry.context.propagation.TextMapPropagator;
import io.opentelemetry.extension.trace.propagation.B3Propagator;
import io.opentelemetry.extension.trace.propagation.JaegerPropagator;
import io.opentelemetry.extension.trace.propagation.OtTracePropagator;
import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper;
import io.opentelemetry.sdk.extension.incubator.fileconfig.component.TextMapPropagatorComponentProvider;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.stream.Stream;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
class TextMapPropagatorFactoryTest {
private final SpiHelper spiHelper =
SpiHelper.create(TextMapPropagatorFactoryTest.class.getClassLoader());
@ParameterizedTest
@MethodSource("createArguments")
void create(List<String> model, TextMapPropagator expectedPropagator) {
TextMapPropagator propagator =
TextMapPropagatorFactory.getInstance().create(model, spiHelper, Collections.emptyList());
assertThat(propagator.toString()).isEqualTo(expectedPropagator.toString());
}
private static Stream<Arguments> createArguments() {
return Stream.of(
Arguments.of(
Collections.emptyList(),
TextMapPropagator.composite(
W3CTraceContextPropagator.getInstance(), W3CBaggagePropagator.getInstance())),
Arguments.of(Collections.singletonList("none"), TextMapPropagator.noop()),
Arguments.of(
Arrays.asList("tracecontext", "baggage", "ottrace", "b3multi", "b3", "jaeger"),
TextMapPropagator.composite(
W3CTraceContextPropagator.getInstance(),
W3CBaggagePropagator.getInstance(),
OtTracePropagator.getInstance(),
B3Propagator.injectingMultiHeaders(),
B3Propagator.injectingSingleHeader(),
JaegerPropagator.getInstance())));
}
@Test
void create_NoneAndOther() {
assertThatThrownBy(
() ->
TextMapPropagatorFactory.getInstance()
.create(Arrays.asList("none", "foo"), spiHelper, Collections.emptyList()))
.isInstanceOf(DeclarativeConfigException.class)
.hasMessage("propagators contains \"none\" along with other propagators");
}
@Test
void create_SpiPropagator_Unknown() {
assertThatThrownBy(
() ->
TextMapPropagatorFactory.getInstance()
.create(Collections.singletonList("foo"), spiHelper, Collections.emptyList()))
.isInstanceOf(DeclarativeConfigException.class)
.hasMessage(
"No component provider detected for io.opentelemetry.context.propagation.TextMapPropagator with name \"foo\".");
}
@Test
void create_SpiPropagator_Valid() {
TextMapPropagator textMapPropagator =
TextMapPropagatorFactory.getInstance()
.create(Collections.singletonList("test"), spiHelper, new ArrayList<>());
assertThat(textMapPropagator)
.isInstanceOfSatisfying(
TextMapPropagatorComponentProvider.TestTextMapPropagator.class,
testTextMapPropagator ->
assertThat(testTextMapPropagator.config)
.isInstanceOfSatisfying(
YamlDeclarativeConfigProperties.class,
config -> assertThat(config.getPropertyKeys()).isEmpty()));
}
}

View File

@ -11,16 +11,25 @@ import static io.opentelemetry.sdk.trace.samplers.Sampler.alwaysOn;
import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporter;
import io.opentelemetry.internal.testing.CleanupExtension;
import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AlwaysOnModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AlwaysOnSamplerModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AttributeLimitsModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.BatchSpanProcessorModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalTracerConfigModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalTracerConfiguratorModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExperimentalTracerMatcherAndConfigModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.OtlpHttpExporterModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SamplerModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanExporterModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanLimitsModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.SpanProcessorModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.TracerProviderModel;
import io.opentelemetry.sdk.internal.ScopeConfigurator;
import io.opentelemetry.sdk.internal.ScopeConfiguratorBuilder;
import io.opentelemetry.sdk.trace.SdkTracerProvider;
import io.opentelemetry.sdk.trace.SdkTracerProviderBuilder;
import io.opentelemetry.sdk.trace.SpanLimits;
import io.opentelemetry.sdk.trace.internal.SdkTracerProviderUtil;
import io.opentelemetry.sdk.trace.internal.TracerConfig;
import java.io.Closeable;
import java.util.ArrayList;
import java.util.Collections;
@ -66,23 +75,40 @@ class TracerProviderFactoryTest {
new AttributeLimitsModel(),
new TracerProviderModel()
.withLimits(
new io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model
.SpanLimitsModel()
new SpanLimitsModel()
.withAttributeCountLimit(1)
.withAttributeValueLengthLimit(2)
.withEventCountLimit(3)
.withLinkCountLimit(4)
.withEventAttributeCountLimit(5)
.withLinkAttributeCountLimit(6))
.withSampler(new SamplerModel().withAlwaysOn(new AlwaysOnModel()))
.withSampler(new SamplerModel().withAlwaysOn(new AlwaysOnSamplerModel()))
.withProcessors(
Collections.singletonList(
new SpanProcessorModel()
.withBatch(
new BatchSpanProcessorModel()
.withExporter(
new SpanExporterModel().withOtlp(new OtlpModel())))))),
SdkTracerProvider.builder()
new SpanExporterModel()
.withOtlpHttp(new OtlpHttpExporterModel())))))
.withTracerConfiguratorDevelopment(
new ExperimentalTracerConfiguratorModel()
.withDefaultConfig(
new ExperimentalTracerConfigModel().withDisabled(true))
.withTracers(
Collections.singletonList(
new ExperimentalTracerMatcherAndConfigModel()
.withName("foo")
.withConfig(
new ExperimentalTracerConfigModel()
.withDisabled(false)))))),
addTracerConfigurator(
SdkTracerProvider.builder(),
ScopeConfigurator.<TracerConfig>builder()
.setDefault(TracerConfig.disabled())
.addCondition(
ScopeConfiguratorBuilder.nameMatchesGlob("foo"), TracerConfig.enabled())
.build())
.setSpanLimits(
SpanLimits.builder()
.setMaxNumberOfAttributes(1)
@ -99,4 +125,10 @@ class TracerProviderFactoryTest {
.build())
.build()));
}
private static SdkTracerProviderBuilder addTracerConfigurator(
SdkTracerProviderBuilder builder, ScopeConfigurator<TracerConfig> tracerConfigurator) {
SdkTracerProviderUtil.setTracerConfigurator(builder, tracerConfigurator);
return builder;
}
}

View File

@ -10,9 +10,9 @@ import static org.mockito.Mockito.mock;
import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.AggregationModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExplicitBucketHistogramModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ExplicitBucketHistogramAggregationModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.IncludeExcludeModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.StreamModel;
import io.opentelemetry.sdk.extension.incubator.fileconfig.internal.model.ViewStreamModel;
import io.opentelemetry.sdk.metrics.View;
import java.util.Arrays;
import java.util.Collections;
@ -28,7 +28,7 @@ class ViewFactoryTest {
View view =
ViewFactory.getInstance()
.create(
new StreamModel().withAttributeKeys(null),
new ViewStreamModel().withAttributeKeys(null),
mock(SpiHelper.class),
Collections.emptyList());
@ -50,7 +50,7 @@ class ViewFactoryTest {
View view =
ViewFactory.getInstance()
.create(
new StreamModel()
new ViewStreamModel()
.withName("name")
.withDescription("description")
.withAttributeKeys(
@ -58,7 +58,7 @@ class ViewFactoryTest {
.withAggregation(
new AggregationModel()
.withExplicitBucketHistogram(
new ExplicitBucketHistogramModel()
new ExplicitBucketHistogramAggregationModel()
.withBoundaries(Arrays.asList(1.0, 2.0)))),
mock(SpiHelper.class),
Collections.emptyList());

View File

@ -22,7 +22,7 @@ import org.junit.jupiter.api.Test;
class YamlDeclarativeConfigPropertiesTest {
private static final String extendedSchema =
"file_format: \"0.3\"\n"
"file_format: \"0.4\"\n"
+ "disabled: false\n"
+ "\n"
+ "resource:\n"
@ -69,7 +69,7 @@ class YamlDeclarativeConfigPropertiesTest {
@Test
void configurationSchema() {
// Validate can read declarative configuration schema properties
assertThat(structuredConfigProps.getString("file_format")).isEqualTo("0.3");
assertThat(structuredConfigProps.getString("file_format")).isEqualTo("0.4");
DeclarativeConfigProperties resourceProps = structuredConfigProps.getStructured("resource");
assertThat(resourceProps).isNotNull();
List<DeclarativeConfigProperties> resourceAttributesList =

View File

@ -0,0 +1,30 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.sdk.extension.incubator.fileconfig.component;
import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties;
import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider;
import io.opentelemetry.sdk.resources.Resource;
// TODO(jack-berg): This allows DeclarativeConfigurationCreateTest to pass with kitchen-sink.yaml
// example. Delete after resource providers from opentelemetry-java-instrumentation are renamed to
// reflect declarative config naming
public class ContainerResourceProvider implements ComponentProvider<Resource> {
@Override
public Class<Resource> getType() {
return Resource.class;
}
@Override
public String getName() {
return "container";
}
@Override
public Resource create(DeclarativeConfigProperties config) {
return Resource.empty();
}
}

View File

@ -0,0 +1,30 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.sdk.extension.incubator.fileconfig.component;
import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties;
import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider;
import io.opentelemetry.sdk.resources.Resource;
// TODO(jack-berg): This allows DeclarativeConfigurationCreateTest to pass with kitchen-sink.yaml
// example. Delete after resource providers from opentelemetry-java-instrumentation are renamed to
// reflect declarative config naming
public class HostResourceProvider implements ComponentProvider<Resource> {
@Override
public Class<Resource> getType() {
return Resource.class;
}
@Override
public String getName() {
return "host";
}
@Override
public Resource create(DeclarativeConfigProperties config) {
return Resource.empty();
}
}

View File

@ -0,0 +1,30 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.sdk.extension.incubator.fileconfig.component;
import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties;
import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider;
import io.opentelemetry.sdk.resources.Resource;
// TODO(jack-berg): This allows DeclarativeConfigurationCreateTest to pass with kitchen-sink.yaml
// example. Delete after resource providers from opentelemetry-java-instrumentation are renamed to
// reflect declarative config naming
public class OsResourceProvider implements ComponentProvider<Resource> {
@Override
public Class<Resource> getType() {
return Resource.class;
}
@Override
public String getName() {
return "os";
}
@Override
public Resource create(DeclarativeConfigProperties config) {
return Resource.empty();
}
}

View File

@ -0,0 +1,30 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.sdk.extension.incubator.fileconfig.component;
import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties;
import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider;
import io.opentelemetry.sdk.resources.Resource;
// TODO(jack-berg): This allows DeclarativeConfigurationCreateTest to pass with kitchen-sink.yaml
// example. Delete after resource providers from opentelemetry-java-instrumentation are renamed to
// reflect declarative config naming
public class ProcessResourceProvider implements ComponentProvider<Resource> {
@Override
public Class<Resource> getType() {
return Resource.class;
}
@Override
public String getName() {
return "process";
}
@Override
public Resource create(DeclarativeConfigProperties config) {
return Resource.empty();
}
}

View File

@ -17,7 +17,7 @@ public class ResourceComponentProvider implements ComponentProvider<Resource> {
@Override
public String getName() {
return "unused";
return "shape_color";
}
@Override

View File

@ -6,11 +6,10 @@
package io.opentelemetry.sdk.extension.incubator.fileconfig.component;
import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties;
import io.opentelemetry.sdk.autoconfigure.spi.Ordered;
import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider;
import io.opentelemetry.sdk.resources.Resource;
public class ResourceOrderedFirstComponentProvider implements ComponentProvider<Resource>, Ordered {
public class ResourceFirstComponentProvider implements ComponentProvider<Resource> {
@Override
public Class<Resource> getType() {
return Resource.class;
@ -18,16 +17,11 @@ public class ResourceOrderedFirstComponentProvider implements ComponentProvider<
@Override
public String getName() {
return "unused";
return "order_first";
}
@Override
public Resource create(DeclarativeConfigProperties config) {
return Resource.builder().put("order", "first").build();
}
@Override
public int order() {
return 1;
}
}

View File

@ -6,12 +6,10 @@
package io.opentelemetry.sdk.extension.incubator.fileconfig.component;
import io.opentelemetry.api.incubator.config.DeclarativeConfigProperties;
import io.opentelemetry.sdk.autoconfigure.spi.Ordered;
import io.opentelemetry.sdk.autoconfigure.spi.internal.ComponentProvider;
import io.opentelemetry.sdk.resources.Resource;
public class ResourceOrderedSecondComponentProvider
implements ComponentProvider<Resource>, Ordered {
public class ResourceSecondComponentProvider implements ComponentProvider<Resource> {
@Override
public Class<Resource> getType() {
return Resource.class;
@ -19,16 +17,11 @@ public class ResourceOrderedSecondComponentProvider
@Override
public String getName() {
return "unused";
return "order_second";
}
@Override
public Resource create(DeclarativeConfigProperties config) {
return Resource.builder().put("order", "second").build();
}
@Override
public int order() {
return 2;
}
}

View File

@ -35,7 +35,7 @@ public class TextMapPropagatorComponentProvider implements ComponentProvider<Tex
public final DeclarativeConfigProperties config;
private TestTextMapPropagator(DeclarativeConfigProperties config) {
public TestTextMapPropagator(DeclarativeConfigProperties config) {
this.config = config;
}
@ -51,5 +51,10 @@ public class TextMapPropagatorComponentProvider implements ComponentProvider<Tex
public <C> Context extract(Context context, @Nullable C carrier, TextMapGetter<C> getter) {
return context;
}
@Override
public String toString() {
return "TestTextMapPropagator{}";
}
}
}

View File

@ -6,5 +6,9 @@ io.opentelemetry.sdk.extension.incubator.fileconfig.component.SamplerComponentPr
io.opentelemetry.sdk.extension.incubator.fileconfig.component.SpanProcessorComponentProvider
io.opentelemetry.sdk.extension.incubator.fileconfig.component.LogRecordProcessorComponentProvider
io.opentelemetry.sdk.extension.incubator.fileconfig.component.ResourceComponentProvider
io.opentelemetry.sdk.extension.incubator.fileconfig.component.ResourceOrderedFirstComponentProvider
io.opentelemetry.sdk.extension.incubator.fileconfig.component.ResourceOrderedSecondComponentProvider
io.opentelemetry.sdk.extension.incubator.fileconfig.component.ResourceFirstComponentProvider
io.opentelemetry.sdk.extension.incubator.fileconfig.component.ResourceSecondComponentProvider
io.opentelemetry.sdk.extension.incubator.fileconfig.component.ContainerResourceProvider
io.opentelemetry.sdk.extension.incubator.fileconfig.component.HostResourceProvider
io.opentelemetry.sdk.extension.incubator.fileconfig.component.OsResourceProvider
io.opentelemetry.sdk.extension.incubator.fileconfig.component.ProcessResourceProvider

View File

@ -415,20 +415,23 @@ class OpenTelemetrySdkTest {
+ "resource=Resource{schemaUrl=null, attributes={service.name=\"otel-test\"}}, "
+ "spanLimitsSupplier=SpanLimitsValue{maxNumberOfAttributes=128, maxNumberOfEvents=128, maxNumberOfLinks=128, maxNumberOfAttributesPerEvent=128, maxNumberOfAttributesPerLink=128, maxAttributeValueLength=2147483647}, "
+ "sampler=ParentBased{root:AlwaysOnSampler,remoteParentSampled:AlwaysOnSampler,remoteParentNotSampled:AlwaysOffSampler,localParentSampled:AlwaysOnSampler,localParentNotSampled:AlwaysOffSampler}, "
+ "spanProcessor=SimpleSpanProcessor{spanExporter=MultiSpanExporter{spanExporters=[MockSpanExporter{}, MockSpanExporter{}]}, exportUnsampledSpans=false}"
+ "spanProcessor=SimpleSpanProcessor{spanExporter=MultiSpanExporter{spanExporters=[MockSpanExporter{}, MockSpanExporter{}]}, exportUnsampledSpans=false}, "
+ "tracerConfigurator=ScopeConfiguratorImpl{conditions=[]}"
+ "}, "
+ "meterProvider=SdkMeterProvider{"
+ "clock=SystemClock{}, "
+ "resource=Resource{schemaUrl=null, attributes={service.name=\"otel-test\"}}, "
+ "metricReaders=[PeriodicMetricReader{exporter=MockMetricExporter{}, intervalNanos=60000000000}], "
+ "metricProducers=[], "
+ "views=[RegisteredView{instrumentSelector=InstrumentSelector{instrumentName=instrument}, view=View{name=new-instrument, aggregation=DefaultAggregation, attributesProcessor=NoopAttributesProcessor{}, cardinalityLimit=2000}}]"
+ "views=[RegisteredView{instrumentSelector=InstrumentSelector{instrumentName=instrument}, view=View{name=new-instrument, aggregation=DefaultAggregation, attributesProcessor=NoopAttributesProcessor{}, cardinalityLimit=2000}}], "
+ "meterConfigurator=ScopeConfiguratorImpl{conditions=[]}"
+ "}, "
+ "loggerProvider=SdkLoggerProvider{"
+ "clock=SystemClock{}, "
+ "resource=Resource{schemaUrl=null, attributes={service.name=\"otel-test\"}}, "
+ "logLimits=LogLimits{maxNumberOfAttributes=128, maxAttributeValueLength=2147483647}, "
+ "logRecordProcessor=SimpleLogRecordProcessor{logRecordExporter=MultiLogRecordExporter{logRecordExporters=[MockLogRecordExporter{}, MockLogRecordExporter{}]}}"
+ "logRecordProcessor=SimpleLogRecordProcessor{logRecordExporter=MultiLogRecordExporter{logRecordExporters=[MockLogRecordExporter{}, MockLogRecordExporter{}]}}, "
+ "loggerConfigurator=ScopeConfiguratorImpl{conditions=[]}"
+ "}, "
+ "propagators=DefaultContextPropagators{textMapPropagator=MockTextMapPropagator{}}"
+ "}");

View File

@ -7,6 +7,7 @@ package io.opentelemetry.sdk.internal;
import java.util.function.Predicate;
import java.util.regex.Pattern;
import javax.annotation.Nullable;
/**
* Utilities for glob pattern matching.
@ -29,23 +30,18 @@ public final class GlobUtil {
* <li>{@code ?} matches exactly one instance of any character
* </ul>
*/
public static Predicate<String> toGlobPatternPredicate(String globPattern) {
// Match all
if (globPattern.equals("*")) {
return unused -> true;
}
// If globPattern contains '*' or '?', convert it to a regex and return corresponding predicate
public static Predicate<String> createGlobPatternPredicate(String globPattern) {
// If globPattern contains '*' or '?', convert it to a regex and return corresponding
// predicate
Pattern pattern = null;
for (int i = 0; i < globPattern.length(); i++) {
char c = globPattern.charAt(i);
if (c == '*' || c == '?') {
Pattern pattern = toRegexPattern(globPattern);
return string -> pattern.matcher(string).matches();
pattern = toRegexPattern(globPattern);
break;
}
}
// Exact match, ignoring case
return globPattern::equalsIgnoreCase;
return new GlobPatternPredicate(globPattern, pattern);
}
/**
@ -79,4 +75,36 @@ public final class GlobUtil {
}
return Pattern.compile(patternBuilder.toString());
}
/**
* A predicate which evaluates if a test string matches the {@link #globPattern}, and which has a
* valid {@link #toString()} implementation.
*/
private static class GlobPatternPredicate implements Predicate<String> {
private final String globPattern;
@Nullable private final Pattern pattern;
private GlobPatternPredicate(String globPattern, @Nullable Pattern pattern) {
this.globPattern = globPattern;
this.pattern = pattern;
}
@Override
public boolean test(String s) {
// Match all
if (globPattern.equals("*")) {
return true;
}
if (pattern != null) {
return pattern.matcher(s).matches();
}
// Exact match, ignoring case
return globPattern.equalsIgnoreCase(s);
}
@Override
public String toString() {
return "GlobPatternPredicate{globPattern=" + globPattern + "}";
}
}
}

View File

@ -19,7 +19,7 @@ public interface ScopeConfigurator<T> extends Function<InstrumentationScopeInfo,
/** Create a new builder. */
static <T> ScopeConfiguratorBuilder<T> builder() {
return new ScopeConfiguratorBuilder<>(unused -> null);
return new ScopeConfiguratorBuilder<>(null);
}
/**

View File

@ -8,7 +8,10 @@ package io.opentelemetry.sdk.internal;
import io.opentelemetry.sdk.common.InstrumentationScopeInfo;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.StringJoiner;
import java.util.function.Predicate;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
/**
@ -22,11 +25,11 @@ import javax.annotation.Nullable;
*/
public final class ScopeConfiguratorBuilder<T> {
private final ScopeConfigurator<T> baseScopeConfigurator;
@Nullable private final ScopeConfigurator<T> baseScopeConfigurator;
@Nullable private T defaultScopeConfig;
private final List<Condition<T>> conditions = new ArrayList<>();
ScopeConfiguratorBuilder(ScopeConfigurator<T> baseScopeConfigurator) {
ScopeConfiguratorBuilder(@Nullable ScopeConfigurator<T> baseScopeConfigurator) {
this.baseScopeConfigurator = baseScopeConfigurator;
}
@ -71,8 +74,7 @@ public final class ScopeConfiguratorBuilder<T> {
* @see #addCondition(Predicate, Object)
*/
public static Predicate<InstrumentationScopeInfo> nameMatchesGlob(String globPattern) {
Predicate<String> globPredicate = GlobUtil.toGlobPatternPredicate(globPattern);
return scopeInfo -> globPredicate.test(scopeInfo.getName());
return new ScopeNameMatcher(GlobUtil.createGlobPatternPredicate(globPattern));
}
/**
@ -82,24 +84,12 @@ public final class ScopeConfiguratorBuilder<T> {
* @see #addCondition(Predicate, Object)
*/
public static Predicate<InstrumentationScopeInfo> nameEquals(String scopeName) {
return scopeInfo -> scopeInfo.getName().equals(scopeName);
return new ScopeNameMatcher(name -> name.equals(scopeName));
}
/** Build a {@link ScopeConfigurator} with the configuration of this builder. */
public ScopeConfigurator<T> build() {
// TODO: return an instance with toString implementation which self describes rules
return scopeInfo -> {
T scopeConfig = baseScopeConfigurator.apply(scopeInfo);
if (scopeConfig != null) {
return scopeConfig;
}
for (Condition<T> condition : conditions) {
if (condition.scopeMatcher.test(scopeInfo)) {
return condition.scopeConfig;
}
}
return defaultScopeConfig;
};
return new ScopeConfiguratorImpl<>(baseScopeConfigurator, defaultScopeConfig, conditions);
}
private static final class Condition<T> {
@ -110,5 +100,80 @@ public final class ScopeConfiguratorBuilder<T> {
this.scopeMatcher = scopeMatcher;
this.scopeConfig = scopeConfig;
}
@Override
public String toString() {
StringJoiner joiner = new StringJoiner(", ", "Condition{", "}");
joiner.add("scopeMatcher=" + scopeMatcher);
joiner.add("scopeConfig=" + scopeConfig);
return joiner.toString();
}
}
private static class ScopeConfiguratorImpl<T> implements ScopeConfigurator<T> {
@Nullable private final ScopeConfigurator<T> baseScopeConfigurator;
@Nullable private final T defaultScopeConfig;
private final List<Condition<T>> conditions;
private ScopeConfiguratorImpl(
@Nullable ScopeConfigurator<T> baseScopeConfigurator,
@Nullable T defaultScopeConfig,
List<Condition<T>> conditions) {
this.baseScopeConfigurator = baseScopeConfigurator;
this.defaultScopeConfig = defaultScopeConfig;
this.conditions = conditions;
}
@Override
@Nullable
public T apply(InstrumentationScopeInfo scopeInfo) {
if (baseScopeConfigurator != null) {
T scopeConfig = baseScopeConfigurator.apply(scopeInfo);
if (scopeConfig != null) {
return scopeConfig;
}
}
for (Condition<T> condition : conditions) {
if (condition.scopeMatcher.test(scopeInfo)) {
return condition.scopeConfig;
}
}
return defaultScopeConfig;
}
@Override
public String toString() {
StringJoiner joiner = new StringJoiner(", ", "ScopeConfiguratorImpl{", "}");
if (baseScopeConfigurator != null) {
joiner.add("baseScopeConfigurator=" + baseScopeConfigurator);
}
if (defaultScopeConfig != null) {
joiner.add("defaultScopeConfig=" + defaultScopeConfig);
}
joiner.add(
"conditions="
+ conditions.stream()
.map(Objects::toString)
.collect(Collectors.joining(",", "[", "]")));
return joiner.toString();
}
}
private static class ScopeNameMatcher implements Predicate<InstrumentationScopeInfo> {
private final Predicate<String> nameMatcher;
private ScopeNameMatcher(Predicate<String> nameMatcher) {
this.nameMatcher = nameMatcher;
}
@Override
public boolean test(InstrumentationScopeInfo scopeInfo) {
return nameMatcher.test(scopeInfo.getName());
}
@Override
public String toString() {
return "ScopeNameMatcher{nameMatcher=" + nameMatcher + "}";
}
}
}

View File

@ -5,42 +5,51 @@
package io.opentelemetry.sdk.internal;
import static io.opentelemetry.sdk.internal.GlobUtil.toGlobPatternPredicate;
import static org.assertj.core.api.Assertions.assertThat;
import org.junit.jupiter.api.Test;
import java.util.stream.Stream;
import org.junit.jupiter.params.ParameterizedTest;
import org.junit.jupiter.params.provider.Arguments;
import org.junit.jupiter.params.provider.MethodSource;
class GlobUtilTest {
@Test
void matchesName() {
assertThat(toGlobPatternPredicate("foo").test("foo")).isTrue();
assertThat(toGlobPatternPredicate("foo").test("Foo")).isTrue();
assertThat(toGlobPatternPredicate("foo").test("bar")).isFalse();
assertThat(toGlobPatternPredicate("fo?").test("foo")).isTrue();
assertThat(toGlobPatternPredicate("fo??").test("fooo")).isTrue();
assertThat(toGlobPatternPredicate("fo?").test("fob")).isTrue();
assertThat(toGlobPatternPredicate("fo?").test("fooo")).isFalse();
assertThat(toGlobPatternPredicate("*").test("foo")).isTrue();
assertThat(toGlobPatternPredicate("*").test("bar")).isTrue();
assertThat(toGlobPatternPredicate("*").test("baz")).isTrue();
assertThat(toGlobPatternPredicate("*").test("foo.bar.baz")).isTrue();
assertThat(toGlobPatternPredicate("*").test(null)).isTrue();
assertThat(toGlobPatternPredicate("*").test("")).isTrue();
assertThat(toGlobPatternPredicate("fo*").test("fo")).isTrue();
assertThat(toGlobPatternPredicate("fo*").test("foo")).isTrue();
assertThat(toGlobPatternPredicate("fo*").test("fooo")).isTrue();
assertThat(toGlobPatternPredicate("fo*").test("foo.bar.baz")).isTrue();
assertThat(toGlobPatternPredicate("*bar").test("sandbar")).isTrue();
assertThat(toGlobPatternPredicate("fo*b*").test("foobar")).isTrue();
assertThat(toGlobPatternPredicate("fo*b*").test("foob")).isTrue();
assertThat(toGlobPatternPredicate("fo*b*").test("foo bar")).isTrue();
assertThat(toGlobPatternPredicate("fo? b??").test("foo bar")).isTrue();
assertThat(toGlobPatternPredicate("fo? b??").test("fooo bar")).isFalse();
assertThat(toGlobPatternPredicate("fo* ba?").test("foo is not bar")).isTrue();
assertThat(toGlobPatternPredicate("fo? b*").test("fox beetles for lunch")).isTrue();
assertThat(toGlobPatternPredicate("f()[]$^.{}|").test("f()[]$^.{}|")).isTrue();
assertThat(toGlobPatternPredicate("f()[]$^.{}|?").test("f()[]$^.{}|o")).isTrue();
assertThat(toGlobPatternPredicate("f()[]$^.{}|*").test("f()[]$^.{}|ooo")).isTrue();
@ParameterizedTest
@MethodSource("globPatternPredicateArgs")
void matchesName(String globPattern, String testString, boolean isMatchExpected) {
assertThat(GlobUtil.createGlobPatternPredicate(globPattern).test(testString))
.isEqualTo(isMatchExpected);
}
private static Stream<Arguments> globPatternPredicateArgs() {
return Stream.of(
Arguments.of("foo", "foo", true),
Arguments.of("foo", "Foo", true),
Arguments.of("foo", "bar", false),
Arguments.of("fo?", "foo", true),
Arguments.of("fo??", "fooo", true),
Arguments.of("fo?", "fob", true),
Arguments.of("fo?", "fooo", false),
Arguments.of("*", "foo", true),
Arguments.of("*", "bar", true),
Arguments.of("*", "baz", true),
Arguments.of("*", "foo.bar.baz", true),
Arguments.of("*", null, true),
Arguments.of("*", "", true),
Arguments.of("fo*", "fo", true),
Arguments.of("fo*", "foo", true),
Arguments.of("fo*", "fooo", true),
Arguments.of("fo*", "foo.bar.baz", true),
Arguments.of("*bar", "sandbar", true),
Arguments.of("fo*b*", "foobar", true),
Arguments.of("fo*b*", "foob", true),
Arguments.of("fo*b*", "foo bar", true),
Arguments.of("fo? b??", "foo bar", true),
Arguments.of("fo? b??", "fooo bar", false),
Arguments.of("fo* ba?", "foo is not bar", true),
Arguments.of("fo? b*", "fox beetles for lunch", true),
Arguments.of("f()[]$^.{}|", "f()[]$^.{}|", true),
Arguments.of("f()[]$^.{}|?", "f()[]$^.{}|o", true),
Arguments.of("f()[]$^.{}|*", "f()[]$^.{}|ooo", true));
}
}

View File

@ -135,6 +135,8 @@ public final class SdkLoggerProvider implements LoggerProvider, Closeable {
+ sharedState.getLogLimits()
+ ", logRecordProcessor="
+ sharedState.getLogRecordProcessor()
+ ", loggerConfigurator="
+ loggerConfigurator
+ '}';
}
}

View File

@ -24,7 +24,7 @@ public final class SdkLoggerProviderUtil {
private SdkLoggerProviderUtil() {}
/** Reflectively set the {@link ScopeConfigurator} to the {@link SdkLoggerProviderBuilder}. */
public static void setLoggerConfigurator(
public static SdkLoggerProviderBuilder setLoggerConfigurator(
SdkLoggerProviderBuilder sdkLoggerProviderBuilder,
ScopeConfigurator<LoggerConfig> loggerConfigurator) {
try {
@ -37,10 +37,11 @@ public final class SdkLoggerProviderUtil {
throw new IllegalStateException(
"Error calling setLoggerConfigurator on SdkLoggerProviderBuilder", e);
}
return sdkLoggerProviderBuilder;
}
/** Reflectively add a logger configurator condition to the {@link SdkLoggerProviderBuilder}. */
public static void addLoggerConfiguratorCondition(
public static SdkLoggerProviderBuilder addLoggerConfiguratorCondition(
SdkLoggerProviderBuilder sdkLoggerProviderBuilder,
Predicate<InstrumentationScopeInfo> scopeMatcher,
LoggerConfig loggerConfig) {
@ -54,5 +55,6 @@ public final class SdkLoggerProviderUtil {
throw new IllegalStateException(
"Error calling addLoggerConfiguratorCondition on SdkLoggerProviderBuilder", e);
}
return sdkLoggerProviderBuilder;
}
}

View File

@ -342,7 +342,8 @@ class SdkLoggerProviderTest {
+ "clock=SystemClock{}, "
+ "resource=Resource{schemaUrl=null, attributes={key=\"value\"}}, "
+ "logLimits=LogLimits{maxNumberOfAttributes=128, maxAttributeValueLength=2147483647}, "
+ "logRecordProcessor=MockLogRecordProcessor"
+ "logRecordProcessor=MockLogRecordProcessor, "
+ "loggerConfigurator=ScopeConfiguratorImpl{conditions=[]}"
+ "}");
}
}

View File

@ -180,6 +180,8 @@ public final class SdkMeterProvider implements MeterProvider, Closeable {
+ metricProducers
+ ", views="
+ registeredViews
+ ", meterConfigurator="
+ meterConfigurator
+ "}";
}

View File

@ -34,7 +34,7 @@ public final class SdkMeterProviderUtil {
*
* @param sdkMeterProviderBuilder the builder
*/
public static void setExemplarFilter(
public static SdkMeterProviderBuilder setExemplarFilter(
SdkMeterProviderBuilder sdkMeterProviderBuilder, ExemplarFilter exemplarFilter) {
try {
Method method =
@ -46,10 +46,11 @@ public final class SdkMeterProviderUtil {
throw new IllegalStateException(
"Error calling setExemplarFilter on SdkMeterProviderBuilder", e);
}
return sdkMeterProviderBuilder;
}
/** Reflectively set the {@link ScopeConfigurator} to the {@link SdkMeterProviderBuilder}. */
public static void setMeterConfigurator(
public static SdkMeterProviderBuilder setMeterConfigurator(
SdkMeterProviderBuilder sdkMeterProviderBuilder,
ScopeConfigurator<MeterConfig> meterConfigurator) {
try {
@ -62,10 +63,11 @@ public final class SdkMeterProviderUtil {
throw new IllegalStateException(
"Error calling setMeterConfigurator on SdkMeterProviderBuilder", e);
}
return sdkMeterProviderBuilder;
}
/** Reflectively add a tracer configurator condition to the {@link SdkMeterProviderBuilder}. */
public static void addMeterConfiguratorCondition(
public static SdkMeterProviderBuilder addMeterConfiguratorCondition(
SdkMeterProviderBuilder sdkMeterProviderBuilder,
Predicate<InstrumentationScopeInfo> scopeMatcher,
MeterConfig meterConfig) {
@ -79,6 +81,7 @@ public final class SdkMeterProviderUtil {
throw new IllegalStateException(
"Error calling addMeterConfiguratorCondition on SdkMeterProviderBuilder", e);
}
return sdkMeterProviderBuilder;
}
/**

View File

@ -169,7 +169,7 @@ public final class ViewRegistry {
return false;
}
if (selector.getInstrumentName() != null
&& !GlobUtil.toGlobPatternPredicate(selector.getInstrumentName())
&& !GlobUtil.createGlobPatternPredicate(selector.getInstrumentName())
.test(descriptor.getName())) {
return false;
}

View File

@ -187,6 +187,8 @@ public final class SdkTracerProvider implements TracerProvider, Closeable {
+ sharedState.getSampler()
+ ", spanProcessor="
+ sharedState.getActiveSpanProcessor()
+ ", tracerConfigurator="
+ tracerConfigurator
+ '}';
}
}