Remove ConfigBuilder and deprecated exporter constants / timeouts (#2506)

* Remove deprecated usage from exporters

* Remove ConfigBuilder and deprecated exporter settings.
This commit is contained in:
Anuraag Agrawal 2021-01-14 09:31:03 +09:00 committed by GitHub
parent 53f0e30776
commit e0f6260bc9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
39 changed files with 50 additions and 2097 deletions

View File

@ -7,15 +7,9 @@ package io.opentelemetry.exporter.jaeger.thrift;
import io.jaegertracing.thrift.internal.senders.HttpSender;
import io.jaegertracing.thrift.internal.senders.ThriftSender;
import java.util.Map;
/** Builder utility for this exporter. */
@SuppressWarnings("deprecation") // Remove after ConfigBuilder is deleted
public final class JaegerThriftSpanExporterBuilder
extends io.opentelemetry.sdk.common.export.ConfigBuilder<JaegerThriftSpanExporterBuilder> {
private static final String KEY_SERVICE_NAME = "otel.exporter.jaeger.service.name";
private static final String KEY_ENDPOINT = "otel.exporter.jaeger.endpoint";
public final class JaegerThriftSpanExporterBuilder {
private String serviceName = JaegerThriftSpanExporter.DEFAULT_SERVICE_NAME;
private String endpoint = JaegerThriftSpanExporter.DEFAULT_ENDPOINT;
@ -57,27 +51,6 @@ public final class JaegerThriftSpanExporterBuilder
return this;
}
/**
* Sets the configuration values from the given configuration map for only the available keys.
*
* @param configMap {@link Map} holding the configuration values.
* @return this.
*/
@Override
protected JaegerThriftSpanExporterBuilder fromConfigMap(
Map<String, String> configMap, NamingConvention namingConvention) {
configMap = namingConvention.normalize(configMap);
String stringValue = getStringProperty(KEY_SERVICE_NAME, configMap);
if (stringValue != null) {
this.setServiceName(stringValue);
}
stringValue = getStringProperty(KEY_ENDPOINT, configMap);
if (stringValue != null) {
this.setEndpoint(stringValue);
}
return this;
}
/**
* Constructs a new instance of the exporter based on the builder's values.
*

View File

@ -30,7 +30,6 @@ import java.net.UnknownHostException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@ -227,14 +226,4 @@ class JaegerThriftSpanExporterTest {
verify(thriftSender).send(expectedProcess2, Collections.singletonList(expectedSpan2));
verify(thriftSender).send(expectedProcess1, Collections.singletonList(expectedSpan1));
}
@Test
void configTest() {
Properties options = new Properties();
String serviceName = "myGreatService";
options.put("otel.exporter.jaeger.service.name", serviceName);
JaegerThriftSpanExporter exporter =
JaegerThriftSpanExporter.builder().readProperties(options).build();
assertThat(exporter.getProcess().getServiceName()).isEqualTo(serviceName);
}
}

View File

@ -37,35 +37,9 @@ import javax.annotation.concurrent.ThreadSafe;
/** Exports spans to Jaeger via gRPC, using Jaeger's protobuf model. */
@ThreadSafe
public final class JaegerGrpcSpanExporter implements SpanExporter {
/**
* Default host name.
*
* @deprecated Will be removed without replacement
*/
@Deprecated public static final String DEFAULT_HOST_NAME = "unknown";
/**
* Default endpoint.
*
* @deprecated Will be removed without replacement
*/
@Deprecated public static final String DEFAULT_ENDPOINT = "localhost:14250";
/**
* Default service name.
*
* @deprecated Will be removed without replacement
*/
@Deprecated public static final String DEFAULT_SERVICE_NAME = DEFAULT_HOST_NAME;
/**
* Default deadline.
*
* @deprecated Will be removed without replacement
*/
@Deprecated public static final long DEFAULT_DEADLINE_MS = TimeUnit.SECONDS.toMillis(10);
private static final Logger logger = Logger.getLogger(JaegerGrpcSpanExporter.class.getName());
private static final String DEFAULT_HOST_NAME = "unknown";
private static final String CLIENT_VERSION_KEY = "jaeger.version";
private static final String CLIENT_VERSION_VALUE = "opentelemetry-java";
private static final String HOSTNAME_KEY = "hostname";

View File

@ -11,16 +11,10 @@ import static java.util.Objects.requireNonNull;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import java.time.Duration;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/** Builder utility for this exporter. */
@SuppressWarnings("deprecation") // Remove after ConfigBuilder is deleted
public final class JaegerGrpcSpanExporterBuilder
extends io.opentelemetry.sdk.common.export.ConfigBuilder<JaegerGrpcSpanExporterBuilder> {
private static final String KEY_SERVICE_NAME = "otel.exporter.jaeger.service.name";
private static final String KEY_ENDPOINT = "otel.exporter.jaeger.endpoint";
public final class JaegerGrpcSpanExporterBuilder {
private static final String DEFAULT_ENDPOINT = "localhost:14250";
private static final String DEFAULT_SERVICE_NAME = "unknown";
private static final long DEFAULT_TIMEOUT_SECS = 10;
@ -84,39 +78,6 @@ public final class JaegerGrpcSpanExporterBuilder
return setTimeout(timeout.toNanos(), TimeUnit.NANOSECONDS);
}
/**
* Sets the max waiting time for the collector to process each span batch. Optional.
*
* @param deadlineMs the max waiting time in millis.
* @return this.
* @deprecated Use {@link #setTimeout(long, TimeUnit)}
*/
@Deprecated
public JaegerGrpcSpanExporterBuilder setDeadlineMs(long deadlineMs) {
return setTimeout(Duration.ofMillis(deadlineMs));
}
/**
* Sets the configuration values from the given configuration map for only the available keys.
*
* @param configMap {@link Map} holding the configuration values.
* @return this.
*/
@Override
protected JaegerGrpcSpanExporterBuilder fromConfigMap(
Map<String, String> configMap, NamingConvention namingConvention) {
configMap = namingConvention.normalize(configMap);
String stringValue = getStringProperty(KEY_SERVICE_NAME, configMap);
if (stringValue != null) {
this.setServiceName(stringValue);
}
stringValue = getStringProperty(KEY_ENDPOINT, configMap);
if (stringValue != null) {
this.setEndpoint(stringValue);
}
return this;
}
/**
* Constructs a new instance of the exporter based on the builder's values.
*

View File

@ -38,7 +38,6 @@ import java.net.InetAddress;
import java.util.Collections;
import java.util.List;
import java.util.Optional;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.BeforeEach;
@ -258,19 +257,6 @@ class JaegerGrpcSpanExporterTest {
return tags.stream().filter(kv -> kv.getKey().equals(tagKey)).findFirst();
}
@Test
void configTest() {
Properties options = new Properties();
String serviceName = "myGreatService";
String endpoint = "127.0.0.1:9090";
options.put("otel.exporter.jaeger.service.name", serviceName);
options.put("otel.exporter.jaeger.endpoint", endpoint);
JaegerGrpcSpanExporter exporter =
JaegerGrpcSpanExporter.builder().readProperties(options).build();
assertThat(exporter.getProcessBuilder().getServiceName()).isEqualTo(serviceName);
assertThat(exporter.getManagedChannel().authority()).isEqualTo(endpoint);
}
@Test
@SuppressWarnings("PreferJavaTimeOverload")
void invalidConfig() {

View File

@ -24,52 +24,9 @@ import java.util.logging.Logger;
import javax.annotation.Nullable;
import javax.annotation.concurrent.ThreadSafe;
/**
* Exports metrics using OTLP via gRPC, using OpenTelemetry's protobuf model.
*
* <p>Configuration options for {@link OtlpGrpcMetricExporter} can be read from system properties,
* environment variables, or {@link java.util.Properties} objects.
*
* <p>For system properties and {@link java.util.Properties} objects, {@link OtlpGrpcMetricExporter}
* will look for the following names:
*
* <ul>
* <li>{@code otel.exporter.otlp.metric.timeout}: to set the max waiting time allowed to send each
* span batch.
* <li>{@code otel.exporter.otlp.metric.endpoint}: to set the endpoint to connect to.
* <li>{@code otel.exporter.otlp.metric.insecure}: whether to enable client transport security for
* the connection.
* <li>{@code otel.exporter.otlp.metric.headers}: the headers associated with the requests.
* </ul>
*
* <p>For environment variables, {@link OtlpGrpcMetricExporter} will look for the following names:
*
* <ul>
* <li>{@code OTEL_EXPORTER_OTLP_METRIC_TIMEOUT}: to set the max waiting time allowed to send each
* span batch.
* <li>{@code OTEL_EXPORTER_OTLP_METRIC_ENDPOINT}: to set the endpoint to connect to.
* <li>{@code OTEL_EXPORTER_OTLP_METRIC_INSECURE}: whether to enable client transport security for
* the connection.
* <li>{@code OTEL_EXPORTER_OTLP_METRIC_HEADERS}: the headers associated with the requests.
* </ul>
*
* <p>In both cases, if a property is missing, the name without "span" is used to resolve the value.
*/
/** Exports metrics using OTLP via gRPC, using OpenTelemetry's protobuf model. */
@ThreadSafe
public final class OtlpGrpcMetricExporter implements MetricExporter {
/**
* Default endpoint.
*
* @deprecated Will be removed without replacement
*/
@Deprecated public static final String DEFAULT_ENDPOINT = "localhost:4317";
/**
* Default timeout.
*
* @deprecated Will be removed without replacement
*/
@Deprecated public static final long DEFAULT_DEADLINE_MS = TimeUnit.SECONDS.toMillis(10);
private static final Logger logger = Logger.getLogger(OtlpGrpcMetricExporter.class.getName());
@ -156,7 +113,7 @@ public final class OtlpGrpcMetricExporter implements MetricExporter {
* @return a new {@link OtlpGrpcMetricExporter} instance.
*/
public static OtlpGrpcMetricExporter getDefault() {
return builder().readEnvironmentVariables().readSystemProperties().build();
return builder().build();
}
/**

View File

@ -9,31 +9,20 @@ import static io.grpc.Metadata.ASCII_STRING_MARSHALLER;
import static io.opentelemetry.api.internal.Utils.checkArgument;
import static java.util.Objects.requireNonNull;
import com.google.common.base.Splitter;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import io.grpc.Metadata;
import io.grpc.stub.MetadataUtils;
import io.opentelemetry.sdk.extension.otproto.CommonProperties;
import java.time.Duration;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import javax.annotation.Nullable;
/** Builder utility for this exporter. */
@SuppressWarnings("deprecation") // Remove after ConfigBuilder is deleted
public final class OtlpGrpcMetricExporterBuilder
extends io.opentelemetry.sdk.common.export.ConfigBuilder<OtlpGrpcMetricExporterBuilder> {
public final class OtlpGrpcMetricExporterBuilder {
private static final String DEFAULT_ENDPOINT = "localhost:4317";
private static final long DEFAULT_TIMEOUT_SECS = 10;
private static final String KEY_TIMEOUT = "otel.exporter.otlp.metric.timeout";
private static final String KEY_ENDPOINT = "otel.exporter.otlp.metric.endpoint";
private static final String KEY_INSECURE = "otel.exporter.otlp.metric.insecure";
private static final String KEY_HEADERS = "otel.exporter.otlp.metric.headers";
private ManagedChannel channel;
private long timeoutNanos = TimeUnit.SECONDS.toNanos(DEFAULT_TIMEOUT_SECS);
private String endpoint = DEFAULT_ENDPOINT;
@ -73,18 +62,6 @@ public final class OtlpGrpcMetricExporterBuilder
return setTimeout(timeout.toNanos(), TimeUnit.NANOSECONDS);
}
/**
* Sets the max waiting time for the collector to process each metric batch. Optional.
*
* @param deadlineMs the max waiting time
* @return this builder's instance
* @deprecated Use {@link #setTimeout(long, TimeUnit)}
*/
@Deprecated
public OtlpGrpcMetricExporterBuilder setDeadlineMs(long deadlineMs) {
return setTimeout(Duration.ofMillis(deadlineMs));
}
/**
* Sets the OTLP endpoint to connect to. Optional, defaults to "localhost:4317".
*
@ -150,56 +127,4 @@ public final class OtlpGrpcMetricExporterBuilder
}
OtlpGrpcMetricExporterBuilder() {}
/**
* Sets the configuration values from the given configuration map for only the available keys.
*
* @param configMap {@link Map} holding the configuration values.
* @return this.
*/
@Override
protected OtlpGrpcMetricExporterBuilder fromConfigMap(
Map<String, String> configMap, NamingConvention namingConvention) {
configMap = namingConvention.normalize(configMap);
Long value = getLongProperty(KEY_TIMEOUT, configMap);
if (value == null) {
value = getLongProperty(CommonProperties.KEY_TIMEOUT, configMap);
}
if (value != null) {
this.setTimeout(Duration.ofMillis(value));
}
String endpointValue = getStringProperty(KEY_ENDPOINT, configMap);
if (endpointValue == null) {
endpointValue = getStringProperty(CommonProperties.KEY_ENDPOINT, configMap);
}
if (endpointValue != null) {
this.setEndpoint(endpointValue);
}
Boolean insecure = getBooleanProperty(KEY_INSECURE, configMap);
if (insecure == null) {
insecure = getBooleanProperty(CommonProperties.KEY_INSECURE, configMap);
}
if (insecure != null) {
this.setUseTls(!insecure);
}
String metadataValue = getStringProperty(KEY_HEADERS, configMap);
if (metadataValue == null) {
metadataValue = getStringProperty(CommonProperties.KEY_HEADERS, configMap);
}
if (metadataValue != null) {
for (String keyValueString : Splitter.on(',').split(metadataValue)) {
final List<String> keyValue =
Splitter.on('=').limit(2).trimResults().omitEmptyStrings().splitToList(keyValueString);
if (keyValue.size() == 2) {
addHeader(keyValue.get(0), keyValue.get(1));
}
}
}
return this;
}
}

View File

@ -5,8 +5,6 @@
package io.opentelemetry.exporter.otlp.metrics;
import static com.google.common.base.Charsets.US_ASCII;
import static io.grpc.Metadata.ASCII_STRING_MARSHALLER;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
@ -36,7 +34,6 @@ import java.time.Duration;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
import org.awaitility.Awaitility;
import org.junit.jupiter.api.AfterEach;
@ -83,31 +80,6 @@ class OtlpGrpcMetricExporterTest {
.hasMessage("timeout");
}
@Test
void configTest() {
Properties options = new Properties();
options.put("otel.exporter.otlp.metric.timeout", "12");
options.put("otel.exporter.otlp.insecure", "true");
options.put("otel.exporter.otlp.headers", "test_1=1,test_2=2");
OtlpGrpcMetricExporterBuilder config = OtlpGrpcMetricExporter.builder().readProperties(options);
assertThat(config).extracting("useTls").isEqualTo(false);
assertThat(config).extracting("timeoutNanos").isEqualTo(TimeUnit.MILLISECONDS.toNanos(12));
assertThat(config)
.extracting("metadata")
.extracting("namesAndValues")
.isEqualTo(
new Object[] {
"test_1".getBytes(US_ASCII),
ASCII_STRING_MARSHALLER.toAsciiString("1").getBytes(US_ASCII),
"test_2".getBytes(US_ASCII),
ASCII_STRING_MARSHALLER.toAsciiString("2").getBytes(US_ASCII),
null,
null,
null,
null
});
}
@Test
void testExport() {
MetricData span = generateFakeMetric();

View File

@ -30,54 +30,10 @@ import java.util.logging.Logger;
import javax.annotation.Nullable;
import javax.annotation.concurrent.ThreadSafe;
/**
* Exports spans using OTLP via gRPC, using OpenTelemetry's protobuf model.
*
* <p>Configuration options for {@link OtlpGrpcSpanExporter} can be read from system properties,
* environment variables, or {@link java.util.Properties} objects.
*
* <p>For system properties and {@link java.util.Properties} objects, {@link OtlpGrpcSpanExporter}
* will look for the following names:
*
* <ul>
* <li>{@code otel.exporter.otlp.span.timeout}: to set the max waiting time allowed to send each
* span batch.
* <li>{@code otel.exporter.otlp.span.endpoint}: to set the endpoint to connect to.
* <li>{@code otel.exporter.otlp.span.insecure}: whether to enable client transport security for
* the connection.
* <li>{@code otel.exporter.otlp.span.headers}: the headers associated with the requests.
* </ul>
*
* <p>For environment variables, {@link OtlpGrpcSpanExporter} will look for the following names:
*
* <ul>
* <li>{@code OTEL_EXPORTER_OTLP_SPAN_TIMEOUT}: to set the max waiting time allowed to send each
* span batch.
* <li>{@code OTEL_EXPORTER_OTLP_SPAN_ENDPOINT}: to set the endpoint to connect to.
* <li>{@code OTEL_EXPORTER_OTLP_SPAN_INSECURE}: whether to enable client transport security for
* the connection.
* <li>{@code OTEL_EXPORTER_OTLP_SPAN_HEADERS}: the headers associated with the requests.
* </ul>
*
* <p>In both cases, if a property is missing, the name without "span" is used to resolve the value.
*/
/** Exports spans using OTLP via gRPC, using OpenTelemetry's protobuf model. */
@ThreadSafe
public final class OtlpGrpcSpanExporter implements SpanExporter {
/**
* Default endpoint.
*
* @deprecated Will be removed without replacement
*/
@Deprecated public static final String DEFAULT_ENDPOINT = "localhost:4317";
/**
* Default timeout.
*
* @deprecated Will be removed without replacement
*/
@Deprecated public static final long DEFAULT_TIMEOUT_MS = TimeUnit.SECONDS.toMillis(10);
private static final Logger logger = Logger.getLogger(OtlpGrpcSpanExporter.class.getName());
private static final String EXPORTER_NAME = OtlpGrpcSpanExporter.class.getSimpleName();
@ -186,7 +142,7 @@ public final class OtlpGrpcSpanExporter implements SpanExporter {
* @return a new {@link OtlpGrpcSpanExporter} instance.
*/
public static OtlpGrpcSpanExporter getDefault() {
return builder().readEnvironmentVariables().readSystemProperties().build();
return builder().build();
}
/**

View File

@ -9,35 +9,24 @@ import static io.grpc.Metadata.ASCII_STRING_MARSHALLER;
import static io.opentelemetry.api.internal.Utils.checkArgument;
import static java.util.Objects.requireNonNull;
import com.google.common.base.Splitter;
import io.grpc.ManagedChannel;
import io.grpc.ManagedChannelBuilder;
import io.grpc.Metadata;
import io.grpc.netty.GrpcSslContexts;
import io.grpc.netty.NettyChannelBuilder;
import io.grpc.stub.MetadataUtils;
import io.opentelemetry.sdk.extension.otproto.CommonProperties;
import java.io.ByteArrayInputStream;
import java.time.Duration;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import javax.annotation.Nullable;
import javax.net.ssl.SSLException;
/** Builder utility for this exporter. */
@SuppressWarnings("deprecation") // Remove after ConfigBuilder is deleted
public final class OtlpGrpcSpanExporterBuilder
extends io.opentelemetry.sdk.common.export.ConfigBuilder<OtlpGrpcSpanExporterBuilder> {
public final class OtlpGrpcSpanExporterBuilder {
private static final String DEFAULT_ENDPOINT = "localhost:4317";
private static final long DEFAULT_TIMEOUT_SECS = 10;
private static final String KEY_TIMEOUT = "otel.exporter.otlp.span.timeout";
private static final String KEY_ENDPOINT = "otel.exporter.otlp.span.endpoint";
private static final String KEY_INSECURE = "otel.exporter.otlp.span.insecure";
private static final String KEY_HEADERS = "otel.exporter.otlp.span.headers";
private ManagedChannel channel;
private long timeoutNanos = TimeUnit.SECONDS.toNanos(DEFAULT_TIMEOUT_SECS);
private String endpoint = DEFAULT_ENDPOINT;
@ -77,18 +66,6 @@ public final class OtlpGrpcSpanExporterBuilder
return setTimeout(timeout.toNanos(), TimeUnit.NANOSECONDS);
}
/**
* Sets the max waiting time for the collector to process each span batch. Optional.
*
* @param deadlineMs the max waiting time
* @return this builder's instance
* @deprecated Use {@link #setTimeout(long, TimeUnit)}
*/
@Deprecated
public OtlpGrpcSpanExporterBuilder setDeadlineMs(long deadlineMs) {
return setTimeout(Duration.ofMillis(deadlineMs));
}
/**
* Sets the OTLP endpoint to connect to. Optional, defaults to "localhost:4317".
*
@ -209,56 +186,4 @@ public final class OtlpGrpcSpanExporterBuilder
}
OtlpGrpcSpanExporterBuilder() {}
/**
* Sets the configuration values from the given configuration map for only the available keys.
*
* @param configMap {@link Map} holding the configuration values.
* @return this.
*/
@Override
protected OtlpGrpcSpanExporterBuilder fromConfigMap(
Map<String, String> configMap, NamingConvention namingConvention) {
configMap = namingConvention.normalize(configMap);
Long value = getLongProperty(KEY_TIMEOUT, configMap);
if (value == null) {
value = getLongProperty(CommonProperties.KEY_TIMEOUT, configMap);
}
if (value != null) {
this.setTimeout(Duration.ofMillis(value));
}
String endpointValue = getStringProperty(KEY_ENDPOINT, configMap);
if (endpointValue == null) {
endpointValue = getStringProperty(CommonProperties.KEY_ENDPOINT, configMap);
}
if (endpointValue != null) {
this.setEndpoint(endpointValue);
}
Boolean insecure = getBooleanProperty(KEY_INSECURE, configMap);
if (insecure == null) {
insecure = getBooleanProperty(CommonProperties.KEY_INSECURE, configMap);
}
if (insecure != null) {
this.setUseTls(!insecure);
}
String metadataValue = getStringProperty(KEY_HEADERS, configMap);
if (metadataValue == null) {
metadataValue = getStringProperty(CommonProperties.KEY_HEADERS, configMap);
}
if (metadataValue != null) {
for (String keyValueString : Splitter.on(',').split(metadataValue)) {
final List<String> keyValue =
Splitter.on('=').limit(2).trimResults().omitEmptyStrings().splitToList(keyValueString);
if (keyValue.size() == 2) {
addHeader(keyValue.get(0), keyValue.get(1));
}
}
}
return this;
}
}

View File

@ -1,112 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.exporter.otlp.trace;
import static com.google.common.base.Charsets.US_ASCII;
import static io.grpc.Metadata.ASCII_STRING_MARSHALLER;
import static org.assertj.core.api.Assertions.assertThat;
import com.linecorp.armeria.common.RequestHeaders;
import com.linecorp.armeria.server.ServerBuilder;
import com.linecorp.armeria.server.ServiceRequestContext;
import com.linecorp.armeria.server.grpc.GrpcService;
import com.linecorp.armeria.testing.junit5.server.ServerExtension;
import io.grpc.stub.StreamObserver;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.api.trace.SpanId;
import io.opentelemetry.api.trace.TraceId;
import io.opentelemetry.proto.collector.trace.v1.ExportTraceServiceRequest;
import io.opentelemetry.proto.collector.trace.v1.ExportTraceServiceResponse;
import io.opentelemetry.proto.collector.trace.v1.TraceServiceGrpc;
import io.opentelemetry.sdk.testing.trace.TestSpanData;
import io.opentelemetry.sdk.trace.data.StatusData;
import java.util.Arrays;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
class OtlpGrpcSpanExporterTest {
@RegisterExtension
public static ServerExtension server =
new ServerExtension() {
@Override
protected void configure(ServerBuilder sb) throws Exception {
sb.service(
GrpcService.builder()
.addService(
new TraceServiceGrpc.TraceServiceImplBase() {
@Override
public void export(
ExportTraceServiceRequest request,
StreamObserver<ExportTraceServiceResponse> responseObserver) {
RequestHeaders headers =
ServiceRequestContext.current().request().headers();
if (headers.get("key").equals("value")
&& headers.get("key2").equals("value2=")
&& headers.get("key3").equals("val=ue3")
&& headers.get("key4").equals("value4")
&& !headers.contains("key5")) {
responseObserver.onNext(
ExportTraceServiceResponse.getDefaultInstance());
responseObserver.onCompleted();
} else {
responseObserver.onError(new AssertionError("Invalid metadata"));
}
}
})
.build());
}
};
@Test
void configTest() {
Properties options = new Properties();
String endpoint = "localhost:" + server.httpPort();
options.put("otel.exporter.otlp.span.timeout", "5124");
options.put("otel.exporter.otlp.span.endpoint", endpoint);
options.put("otel.exporter.otlp.span.insecure", "true");
options.put(
"otel.exporter.otlp.span.headers",
"key=value,key2=value2=,key3=val=ue3, key4 = value4 ,key5= ");
OtlpGrpcSpanExporterBuilder builder = OtlpGrpcSpanExporter.builder().readProperties(options);
assertThat(builder)
.extracting("metadata")
.extracting("namesAndValues")
.isEqualTo(
new Object[] {
"key".getBytes(US_ASCII),
ASCII_STRING_MARSHALLER.toAsciiString("value").getBytes(US_ASCII),
"key2".getBytes(US_ASCII),
ASCII_STRING_MARSHALLER.toAsciiString("value2=").getBytes(US_ASCII),
"key3".getBytes(US_ASCII),
ASCII_STRING_MARSHALLER.toAsciiString("val=ue3").getBytes(US_ASCII),
"key4".getBytes(US_ASCII),
ASCII_STRING_MARSHALLER.toAsciiString("value4").getBytes(US_ASCII)
});
OtlpGrpcSpanExporter exporter = builder.build();
assertThat(exporter.getTimeoutNanos()).isEqualTo(TimeUnit.MILLISECONDS.toNanos(5124));
assertThat(
exporter
.export(
Arrays.asList(
TestSpanData.builder()
.setTraceId(TraceId.getInvalid())
.setSpanId(SpanId.getInvalid())
.setName("name")
.setKind(Span.Kind.CLIENT)
.setStartEpochNanos(1)
.setEndEpochNanos(2)
.setStatus(StatusData.ok())
.setHasEnded(true)
.build()))
.join(10, TimeUnit.SECONDS)
.isSuccess())
.isTrue();
}
}

View File

@ -39,24 +39,6 @@ import zipkin2.reporter.Sender;
/**
* This class was based on the OpenCensus zipkin exporter code at
* https://github.com/census-instrumentation/opencensus-java/tree/c960b19889de5e4a7b25f90919d28b066590d4f0/exporters/trace/zipkin
*
* <p>Configuration options for {@link ZipkinSpanExporter} can be read from system properties,
* environment variables, or {@link java.util.Properties} objects.
*
* <p>For system properties and {@link java.util.Properties} objects, {@link ZipkinSpanExporter}
* will look for the following names:
*
* <ul>
* <li>{@code otel.exporter.zipkin.service.name}: to set the service name.
* <li>{@code otel.exporter.zipkin.endpoint}: to set the endpoint URL.
* </ul>
*
* <p>For environment variables, {@link ZipkinSpanExporter} will look for the following names:
*
* <ul>
* <li>{@code OTEL_EXPORTER_ZIPKIN_SERVICE_NAME}: to set the service name.
* <li>{@code OTEL_EXPORTER_ZIPKIN_ENDPOINT}: to set the endpoint URL.
* </ul>
*/
public final class ZipkinSpanExporter implements SpanExporter {
public static final String DEFAULT_ENDPOINT = "http://localhost:9411/api/v2/spans";

View File

@ -5,7 +5,6 @@
package io.opentelemetry.exporter.zipkin;
import java.util.Map;
import zipkin2.Span;
import zipkin2.codec.BytesEncoder;
import zipkin2.codec.SpanBytesEncoder;
@ -13,11 +12,7 @@ import zipkin2.reporter.Sender;
import zipkin2.reporter.okhttp3.OkHttpSender;
/** Builder class for {@link ZipkinSpanExporter}. */
@SuppressWarnings("deprecation") // Remove after ConfigBuilder is deleted
public final class ZipkinSpanExporterBuilder
extends io.opentelemetry.sdk.common.export.ConfigBuilder<ZipkinSpanExporterBuilder> {
private static final String KEY_SERVICE_NAME = "otel.exporter.zipkin.service.name";
private static final String KEY_ENDPOINT = "otel.exporter.zipkin.endpoint";
public final class ZipkinSpanExporterBuilder {
private BytesEncoder<Span> encoder = SpanBytesEncoder.JSON_V2;
private Sender sender;
private String serviceName = ZipkinSpanExporter.DEFAULT_SERVICE_NAME;
@ -87,27 +82,6 @@ public final class ZipkinSpanExporterBuilder
return this;
}
/**
* Sets the configuration values from the given configuration map for only the available keys.
*
* @param configMap {@link Map} holding the configuration values.
* @return this.
*/
@Override
protected ZipkinSpanExporterBuilder fromConfigMap(
Map<String, String> configMap, NamingConvention namingConvention) {
configMap = namingConvention.normalize(configMap);
String stringValue = getStringProperty(KEY_SERVICE_NAME, configMap);
if (stringValue != null) {
this.setServiceName(stringValue);
}
stringValue = getStringProperty(KEY_ENDPOINT, configMap);
if (stringValue != null) {
this.setEndpoint(stringValue);
}
return this;
}
/**
* Builds a {@link ZipkinSpanExporter}.
*

View File

@ -39,7 +39,6 @@ import java.io.IOException;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
@ -401,16 +400,4 @@ class ZipkinSpanExporterTest {
.addAnnotation(1505855799000000L + 433901068L / 1000, "RECEIVED")
.addAnnotation(1505855799000000L + 459486280L / 1000, "SENT");
}
@Test
void configTest() {
Properties options = new Properties();
String serviceName = "myGreatService";
String endpoint = "http://127.0.0.1:9090";
options.put("otel.exporter.zipkin.service.name", serviceName);
options.put("otel.exporter.zipkin.endpoint", endpoint);
ZipkinSpanExporterBuilder config = ZipkinSpanExporter.builder().readProperties(options);
assertThat(config).extracting("serviceName").isEqualTo(serviceName);
assertThat(config).extracting("endpoint").isEqualTo(endpoint);
}
}

View File

@ -12,38 +12,12 @@ import io.opentelemetry.sdk.common.CompletableResultCode;
import io.opentelemetry.sdk.trace.ReadWriteSpan;
import io.opentelemetry.sdk.trace.ReadableSpan;
import io.opentelemetry.sdk.trace.SpanProcessor;
import java.util.Map;
import java.util.Objects;
import javax.annotation.concurrent.ThreadSafe;
/**
* A {@link SpanProcessor} implementation that uses {@code Disruptor} to execute all the hooks on an
* async thread.
*
* <p>Configuration options for {@link DisruptorAsyncSpanProcessor} can be read from system
* properties, environment variables, or {@link java.util.Properties} objects.
*
* <p>For system properties and {@link java.util.Properties} objects, {@link
* DisruptorAsyncSpanProcessor} will look for the following names:
*
* <ul>
* <li>{@code otel.disruptor.buffer.size}: number of events that can be enqueued at any one time.
* <li>{@code otel.disruptor.blocking}: to block the queue if no space available.
* <li>{@code otel.disruptor.num.retries}: number of retries for the {@link SleepingWaitStrategy}.
* <li>{@code otel.disruptor.sleeping.time}: waiting time in ns for the {@link
* SleepingWaitStrategy}.
* </ul>
*
* <p>For environment variables, {@link DisruptorAsyncSpanProcessor} will look for the following
* names:
*
* <ul>
* <li>{@code OTEL_DISRUPTOR_BUFFER_SIZE}: number of events that can be enqueued at any one time.
* <li>{@code OTEL_DISRUPTOR_BLOCKING}: to block the queue if no space available.
* <li>{@code OTEL_DISRUPTOR_NUM_RETRIES}: number of retries for the {@link SleepingWaitStrategy}.
* <li>{@code OTEL_DISRUPTOR_SLEEPING_TIME}: waiting time in ns for the {@link
* SleepingWaitStrategy}.
* </ul>
*/
@ThreadSafe
public final class DisruptorAsyncSpanProcessor implements SpanProcessor {
@ -102,14 +76,7 @@ public final class DisruptorAsyncSpanProcessor implements SpanProcessor {
}
/** Builder class for {@link DisruptorAsyncSpanProcessor}. */
@SuppressWarnings("deprecation") // Remove after ConfigBuilder is deleted
public static final class Builder
extends io.opentelemetry.sdk.common.export.ConfigBuilder<Builder> {
private static final String KEY_DISRUPTOR_BUFFER_SIZE = "otel.disruptor.buffer.size";
private static final String KEY_BLOCKING = "otel.disruptor.blocking";
private static final String KEY_NUM_RETRIES = "otel.disruptor.num.retries";
private static final String KEY_SLEEPING_TIME_NS = "otel.disruptor.sleeping.time";
public static final class Builder {
// Number of events that can be enqueued at any one time. If more than this are enqueued,
// then subsequent attempts to enqueue new entries will block.
@ -178,29 +145,6 @@ public final class DisruptorAsyncSpanProcessor implements SpanProcessor {
spanProcessor.isStartRequired(),
spanProcessor.isEndRequired());
}
@Override
protected Builder fromConfigMap(
Map<String, String> configMap, NamingConvention namingConvention) {
configMap = namingConvention.normalize(configMap);
Integer intValue = getIntProperty(KEY_DISRUPTOR_BUFFER_SIZE, configMap);
if (intValue != null) {
this.setBufferSize(intValue);
}
Boolean boolValue = getBooleanProperty(KEY_BLOCKING, configMap);
if (boolValue != null) {
this.setBlocking(boolValue);
}
Integer retries = getIntProperty(KEY_NUM_RETRIES, configMap);
if (retries == null) {
retries = DEFAULT_NUM_RETRIES;
}
Long sleepingNs = getLongProperty(KEY_SLEEPING_TIME_NS, configMap);
if (sleepingNs == null) {
sleepingNs = DEFAULT_SLEEPING_TIME_NS;
}
return setWaitingStrategy(new SleepingWaitStrategy(retries, sleepingNs));
}
}
private DisruptorAsyncSpanProcessor(

View File

@ -13,7 +13,6 @@ import io.opentelemetry.sdk.trace.ReadWriteSpan;
import io.opentelemetry.sdk.trace.ReadableSpan;
import io.opentelemetry.sdk.trace.SpanProcessor;
import java.util.Arrays;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicInteger;
import org.junit.jupiter.api.Test;
@ -257,18 +256,4 @@ class DisruptorAsyncSpanProcessorTest {
assertThat(incrementSpanProcessor.getCounterOnExportedForceFlushSpans()).isEqualTo(tenK);
assertThat(incrementSpanProcessor.getCounterOnShutdown()).isEqualTo(1);
}
@Test
void configTest() {
Properties options = new Properties();
options.put("otel.disruptor.blocking", "false");
options.put("otel.disruptor.buffer.size", "1234");
options.put("otel.disruptor.num.retries", "56");
options.put("otel.disruptor.sleeping.time", "78");
IncrementSpanProcessor incrementSpanProcessor = new IncrementSpanProcessor(REQUIRED, REQUIRED);
DisruptorAsyncSpanProcessor.Builder config =
DisruptorAsyncSpanProcessor.builder(incrementSpanProcessor).readProperties(options);
assertThat(config).extracting("blocking").isEqualTo(false);
assertThat(config).extracting("bufferSize").isEqualTo(1234);
}
}

View File

@ -16,7 +16,6 @@ import io.opentelemetry.sdk.internal.DaemonThreadFactory;
import io.opentelemetry.sdk.logging.LogProcessor;
import io.opentelemetry.sdk.logging.data.LogRecord;
import java.util.ArrayList;
import java.util.Map;
import java.util.Objects;
import java.util.concurrent.ArrayBlockingQueue;
import java.util.concurrent.BlockingQueue;
@ -218,18 +217,12 @@ public final class BatchLogProcessor implements LogProcessor {
}
}
@SuppressWarnings("deprecation") // Remove after ConfigBuilder is deleted
public static class Builder extends io.opentelemetry.sdk.common.export.ConfigBuilder<Builder> {
public static class Builder {
private static final long DEFAULT_SCHEDULE_DELAY_MILLIS = 200;
private static final int DEFAULT_MAX_QUEUE_SIZE = 2048;
private static final int DEFAULT_MAX_EXPORT_BATCH_SIZE = 512;
private static final long DEFAULT_EXPORT_TIMEOUT_MILLIS = 30_000;
private static final String KEY_SCHEDULE_DELAY_MILLIS = "otel.log.schedule.delay";
private static final String KEY_MAX_QUEUE_SIZE = "otel.log.max.queue";
private static final String KEY_MAX_EXPORT_BATCH_SIZE = "otel.log.max.export.batch";
private static final String KEY_EXPORT_TIMEOUT_MILLIS = "otel.log.export.timeout";
private final LogExporter logExporter;
private long scheduleDelayMillis = DEFAULT_SCHEDULE_DELAY_MILLIS;
private int maxQueueSize = DEFAULT_MAX_QUEUE_SIZE;
@ -332,28 +325,5 @@ public final class BatchLogProcessor implements LogProcessor {
public int getMaxExportBatchSize() {
return maxExportBatchSize;
}
@Override
protected Builder fromConfigMap(
Map<String, String> configMap, NamingConvention namingConvention) {
configMap = namingConvention.normalize(configMap);
Long longValue = getLongProperty(KEY_SCHEDULE_DELAY_MILLIS, configMap);
if (longValue != null) {
this.setScheduleDelayMillis(longValue);
}
Integer intValue = getIntProperty(KEY_MAX_QUEUE_SIZE, configMap);
if (intValue != null) {
this.setMaxQueueSize(intValue);
}
intValue = getIntProperty(KEY_MAX_EXPORT_BATCH_SIZE, configMap);
if (intValue != null) {
this.setMaxExportBatchSize(intValue);
}
intValue = getIntProperty(KEY_EXPORT_TIMEOUT_MILLIS, configMap);
if (intValue != null) {
this.setExporterTimeoutMillis(intValue);
}
return this;
}
}
}

View File

@ -8,50 +8,13 @@ package io.opentelemetry.sdk.logging.sdk;
import static org.assertj.core.api.AssertionsForInterfaceTypes.assertThat;
import static org.awaitility.Awaitility.await;
import io.opentelemetry.sdk.common.CompletableResultCode;
import io.opentelemetry.sdk.logging.data.LogRecord;
import io.opentelemetry.sdk.logging.export.BatchLogProcessor;
import io.opentelemetry.sdk.logging.export.LogExporter;
import io.opentelemetry.sdk.logging.util.TestLogExporter;
import java.util.Collection;
import java.util.Properties;
import java.util.concurrent.TimeUnit;
import org.junit.jupiter.api.Test;
class BatchLogProcessorTest {
@Test
void testBuilder() {
Properties props = new Properties();
long delay = 1234L;
int queue = 2345;
int batch = 521;
int timeout = 5432;
props.put("otel.log.schedule.delay", Long.toString(delay));
props.put("otel.log.max.queue", Integer.toString(queue));
props.put("otel.log.max.export.batch", Integer.toString(batch));
props.put("otel.log.export.timeout", Integer.toString(timeout));
BatchLogProcessor.Builder builder =
BatchLogProcessor.builder(
new LogExporter() {
@Override
public CompletableResultCode export(Collection<LogRecord> records) {
return CompletableResultCode.ofSuccess();
}
@Override
public CompletableResultCode shutdown() {
return CompletableResultCode.ofSuccess();
}
});
builder.readProperties(props);
assertThat(builder.getScheduleDelayMillis()).isEqualTo(delay);
assertThat(builder.getMaxQueueSize()).isEqualTo(queue);
assertThat(builder.getMaxExportBatchSize()).isEqualTo(batch);
assertThat(builder.getExporterTimeoutMillis()).isEqualTo(timeout);
}
@Test
void testForceExport() {

View File

@ -17,25 +17,7 @@ import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;
import javax.annotation.concurrent.ThreadSafe;
/**
* A {@link SpanProcessor} implementation for the traceZ zPage.
*
* <p>Configuration options for {@link TracezSpanProcessor} can be read from system properties,
* environment variables, or {@link java.util.Properties} objects.
*
* <p>For system properties and {@link java.util.Properties} objects, {@link TracezSpanProcessor}
* will look for the following names:
*
* <ul>
* <li>{@code otel.zpages.export.sampled}: sets whether only sampled spans should be exported.
* </ul>
*
* <p>For environment variables, {@link TracezSpanProcessor} will look for the following names:
*
* <ul>
* <li>{@code OTEL_ZPAGES_EXPORT_SAMPLED}: sets whether only sampled spans should be exported.
* </ul>
*/
/** A {@link SpanProcessor} implementation for the traceZ zPage. */
@ThreadSafe
final class TracezSpanProcessor implements SpanProcessor {
private final ConcurrentMap<String, ReadableSpan> runningSpanCache;
@ -130,39 +112,13 @@ final class TracezSpanProcessor implements SpanProcessor {
}
/** Builder class for {@link TracezSpanProcessor}. */
@SuppressWarnings("deprecation") // Remove after ConfigBuilder is deleted
public static final class Builder
extends io.opentelemetry.sdk.common.export.ConfigBuilder<Builder> {
public static final class Builder {
private static final String KEY_SAMPLED = "otel.zpages.export.sampled";
private static final boolean DEFAULT_EXPORT_ONLY_SAMPLED = true;
private boolean sampled = DEFAULT_EXPORT_ONLY_SAMPLED;
private Builder() {}
/**
* Sets the configuration values from the given configuration map for only the available keys.
* This method looks for the following keys:
*
* <ul>
* <li>{@code otel.zpages.export.sampled}: to set whether only sampled spans should be
* exported.
* </ul>
*
* @param configMap {@link Map} holding the configuration values.
* @return this.
*/
@Override
protected Builder fromConfigMap(
Map<String, String> configMap, NamingConvention namingConvention) {
configMap = namingConvention.normalize(configMap);
Boolean boolValue = getBooleanProperty(KEY_SAMPLED, configMap);
if (boolValue != null) {
return this.setExportOnlySampled(boolValue);
}
return this;
}
/**
* Sets whether only sampled spans should be exported.
*

View File

@ -19,7 +19,6 @@ import io.opentelemetry.sdk.trace.ReadableSpan;
import io.opentelemetry.sdk.trace.data.SpanData;
import io.opentelemetry.sdk.trace.data.StatusData;
import java.util.Collection;
import java.util.Properties;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.ExtendWith;
import org.mockito.Mock;
@ -97,43 +96,4 @@ class TracezSpanProcessorTest {
spanProcessor.onEnd(readableSpan);
assertSpanCacheSizes(spanProcessor, 0, 0);
}
@Test
void build_sampledFlagTrue_notInCache() {
/* Initialize a TraceZSpanProcessor that only looks at sampled spans */
Properties properties = new Properties();
properties.setProperty("otel.zpages.export.sampled", "true");
TracezSpanProcessor spanProcessor =
TracezSpanProcessor.builder().readProperties(properties).build();
/* Return a non-sampled span, which should not be added to the completed cache */
when(readWriteSpan.getSpanContext()).thenReturn(NOT_SAMPLED_SPAN_CONTEXT);
spanProcessor.onStart(Context.root(), readWriteSpan);
assertSpanCacheSizes(spanProcessor, 1, 0);
when(readableSpan.getSpanContext()).thenReturn(NOT_SAMPLED_SPAN_CONTEXT);
spanProcessor.onEnd(readableSpan);
assertSpanCacheSizes(spanProcessor, 0, 0);
}
@Test
void build_sampledFlagFalse_inCache() {
/* Initialize a TraceZSpanProcessor that looks at all spans */
Properties properties = new Properties();
properties.setProperty("otel.zpages.export.sampled", "false");
TracezSpanProcessor spanProcessor =
TracezSpanProcessor.builder().readProperties(properties).build();
/* Return a non-sampled span, which should be added to the caches */
when(readWriteSpan.getSpanContext()).thenReturn(NOT_SAMPLED_SPAN_CONTEXT);
spanProcessor.onStart(Context.root(), readWriteSpan);
assertSpanCacheSizes(spanProcessor, 1, 0);
when(readableSpan.getName()).thenReturn(SPAN_NAME);
when(readableSpan.getSpanContext()).thenReturn(NOT_SAMPLED_SPAN_CONTEXT);
when(readableSpan.toSpanData()).thenReturn(spanData);
when(spanData.getStatus()).thenReturn(SPAN_STATUS);
spanProcessor.onEnd(readableSpan);
assertSpanCacheSizes(spanProcessor, 0, 1);
}
}

View File

@ -1,164 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.sdk.common.export;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Properties;
import javax.annotation.Nonnull;
import javax.annotation.Nullable;
/**
* Base class for all the config builder classes (SimpleSpanProcessor, BatchSpanProcessor, etc).
*
* <p>The type parameter on this class should be set to the type of the implementation of this
* abstract class. For example, if your subclass is a Foo.Builder, then you would declare it as
*
* <p>{@code Foo.Builder extends ConfigBuilder<Foo.Builder>}
*
* @param <T> the type of the implementation.
* @deprecated Define an implementation of {@code SdkTracerProviderConfigurer} from the
* opentelemetry-sdk-extension-autoconfigure module to allow autoconfiguration of your type.
*/
@Deprecated
public abstract class ConfigBuilder<T> {
// Visible for testing
protected enum NamingConvention {
DOT {
@Override
public String normalize(@Nonnull String key) {
return key.toLowerCase();
}
},
ENV_VAR {
@Override
public String normalize(@Nonnull String key) {
return key.toLowerCase().replace("_", ".");
}
};
public abstract String normalize(@Nonnull String key);
/**
* Normalize the key value of the map using the class {@link #normalize(String)} method.
*
* @see #normalize(String)
* @param map The map to normalize
* @return an unmodifiable normalized map
*/
public Map<String, String> normalize(@Nonnull Map<String, String> map) {
Map<String, String> properties = new HashMap<>();
for (Map.Entry<String, String> entry : map.entrySet()) {
properties.put(normalize(entry.getKey()), entry.getValue());
}
return Collections.unmodifiableMap(properties);
}
}
/** Sets the configuration values from the given configuration map for only the available keys. */
protected abstract T fromConfigMap(
Map<String, String> configMap, NamingConvention namingConvention);
/** Sets the configuration values from the given {@link Properties} object. */
public T readProperties(Properties properties) {
// Properties incorrectly implements Map<Object, Object> but we know it only has Strings.
@SuppressWarnings({"unchecked", "rawtypes"})
Map<String, String> map = (Map) properties;
return fromConfigMap(map, NamingConvention.DOT);
}
/** Sets the configuration values from environment variables. */
public T readEnvironmentVariables() {
return fromConfigMap(System.getenv(), NamingConvention.ENV_VAR);
}
/** Sets the configuration values from system properties. */
public T readSystemProperties() {
return readProperties(System.getProperties());
}
/**
* Get a boolean property from the map, {@code null} if it cannot be found or it has a wrong type.
*
* @param name The property name
* @param map The map where to look for the property
* @return the {@link Boolean} value of the property, {@code null} in case of error or if the
* property cannot be found.
*/
@Nullable
protected static Boolean getBooleanProperty(String name, Map<String, String> map) {
if (map.containsKey(name)) {
return Boolean.parseBoolean(map.get(name));
}
return null;
}
/**
* Get an integer property from the map, {@code null} if it cannot be found or it has a wrong
* type.
*
* @param name The property name
* @param map The map where to look for the property
* @return the {@link Integer} value of the property, {@code null} in case of error or if the
* property cannot be found.
*/
@Nullable
protected static Integer getIntProperty(String name, Map<String, String> map) {
try {
return Integer.parseInt(map.get(name));
} catch (NumberFormatException ex) {
return null;
}
}
/**
* Get a long property from the map, {@code null} if it cannot be found or it has a wrong type.
*
* @param name The property name
* @param map The map where to look for the property
* @return the {@link Long} value of the property, {@code null} in case of error or if the
* property cannot be found.
*/
@Nullable
protected static Long getLongProperty(String name, Map<String, String> map) {
try {
return Long.parseLong(map.get(name));
} catch (NumberFormatException ex) {
return null;
}
}
/**
* Get a {@link String} property from the map, {@code null} if it cannot be found.
*
* @param name The property name
* @param map The map where to look for the property
* @return the {@link String} value of the property, {@code null} if the property cannot be found.
*/
@Nullable
protected static String getStringProperty(String name, Map<String, String> map) {
return map.get(name);
}
/**
* Get a double property from the map, {@code null} if it cannot be found or it has a wrong type.
*
* @param name The property name
* @param map The map where to look for the property
* @return the {@link Double} value of the property, {@code null} in case of error or if the
* property cannot be found.
*/
@Nullable
protected static Double getDoubleProperty(String name, Map<String, String> map) {
try {
return Double.parseDouble(map.get(name));
} catch (NumberFormatException | NullPointerException ex) {
return null;
}
}
}

View File

@ -1,78 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.sdk.resources;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;
import java.util.Map;
import javax.annotation.Nullable;
import javax.annotation.concurrent.ThreadSafe;
/**
* Provides a framework for detection of resource information from the environment variable
* "OTEL_RESOURCE_ATTRIBUTES" and system properties "otel.resource.attributes".
*/
@ThreadSafe
final class EnvAutodetectResource {
private static final String ATTRIBUTE_LIST_SPLITTER = ",";
private static final String ATTRIBUTE_KEY_VALUE_SPLITTER = "=";
private EnvAutodetectResource() {}
/*
* Creates an attribute map from the OTEL_RESOURCE_ATTRIBUTES environment variable or
* otel.resource.attributes system properties.
*
* <p>OTEL_RESOURCE_ATTRIBUTES: A comma-separated list of attributes describing the source in more
* detail, e.g. key1=val1,key2=val2. Domain names and paths are accepted as attribute keys.
* Values may be quoted or unquoted in general.
* If a value contains whitespaces, =, or " characters, it must always be quoted.
*/
// Visible for testing
static Attributes parseResourceAttributes(@Nullable String rawEnvAttributes) {
if (rawEnvAttributes == null) {
return Attributes.empty();
} else {
AttributesBuilder attrBuilders = Attributes.builder();
String[] rawAttributes = rawEnvAttributes.split(ATTRIBUTE_LIST_SPLITTER, -1);
for (String rawAttribute : rawAttributes) {
String[] keyValuePair = rawAttribute.split(ATTRIBUTE_KEY_VALUE_SPLITTER, -1);
if (keyValuePair.length != 2) {
continue;
}
attrBuilders.put(keyValuePair[0].trim(), keyValuePair[1].trim().replaceAll("^\"|\"$", ""));
}
return attrBuilders.build();
}
}
/** Builder utility for this EnvAutodetectResource. */
@SuppressWarnings("deprecation") // Remove after ConfigBuilder is deleted
protected static class Builder extends io.opentelemetry.sdk.common.export.ConfigBuilder<Builder> {
private static final String OTEL_RESOURCE_ATTRIBUTES_KEY = "otel.resource.attributes";
private String envAttributes;
@Override
protected Builder fromConfigMap(
Map<String, String> configMap, NamingConvention namingConvention) {
configMap = namingConvention.normalize(configMap);
String envAttributesValue = getStringProperty(OTEL_RESOURCE_ATTRIBUTES_KEY, configMap);
if (envAttributesValue != null) {
this.setEnvAttributes(envAttributesValue);
}
return this;
}
public Builder setEnvAttributes(String envAttributes) {
this.envAttributes = envAttributes;
return this;
}
public Resource build() {
return Resource.create(parseResourceAttributes(this.envAttributes));
}
}
}

View File

@ -16,19 +16,34 @@ import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.common.AttributesBuilder;
import io.opentelemetry.api.internal.StringUtils;
import io.opentelemetry.api.internal.Utils;
import java.util.Arrays;
import java.util.Objects;
import java.util.Properties;
import java.util.ServiceLoader;
import java.util.Set;
import java.util.stream.Collectors;
import javax.annotation.Nullable;
import javax.annotation.concurrent.Immutable;
/**
* {@link Resource} represents a resource, which capture identifying information about the entities
* for which signals (stats or traces) are reported.
*
* <p>To disable any {@link ResourceProvider} found on the classpath from being recognized, set the
* fully qualified class names of the {@link ResourceProvider} implementations as a comma separated
* list to the system property {@code -Dotel.java.disabled.resource_providers} or the {@code
* OTEL_JAVA_DISABLED_RESOURCE_PROVIDERS} environment variable.
*/
@Immutable
@AutoValue
public abstract class Resource {
private static final String OTEL_JAVA_DISABLED_RESOURCES_PROVIDERS_PROPERTY_KEY =
"otel.java.disabled.resource_providers";
private static final String OTEL_JAVA_DISABLED_RESOURCES_PROVIDERS_ENV_KEY =
"OTEL_JAVA_DISABLED_RESOURCE_PROVIDERS";
private static final int MAX_LENGTH = 255;
private static final String ERROR_MESSAGE_INVALID_CHARS =
" should be a ASCII string with a length greater than 0 and not exceed "
@ -50,13 +65,7 @@ public abstract class Resource {
.build());
}
private static final Resource DEFAULT =
new EnvAutodetectResource.Builder()
.readEnvironmentVariables()
.readSystemProperties()
.build()
.merge(TELEMETRY_SDK)
.merge(readResourceFromProviders());
private static final Resource DEFAULT = TELEMETRY_SDK.merge(readResourceFromProviders());
@Nullable
private static String readVersion() {
@ -72,13 +81,21 @@ public abstract class Resource {
}
private static Resource readResourceFromProviders() {
ResourcesConfig resourcesConfig =
ResourcesConfig.builder().readEnvironmentVariables().readSystemProperties().build();
String disabledResourceProvidersConfig =
System.getenv(OTEL_JAVA_DISABLED_RESOURCES_PROVIDERS_ENV_KEY);
if (disabledResourceProvidersConfig == null) {
disabledResourceProvidersConfig =
System.getProperty(OTEL_JAVA_DISABLED_RESOURCES_PROVIDERS_PROPERTY_KEY, "");
}
Set<String> disabledResourceProviders =
Arrays.stream(disabledResourceProvidersConfig.split(","))
.map(String::trim)
.filter(s -> !s.isEmpty())
.collect(Collectors.toSet());
Resource result = Resource.EMPTY;
for (ResourceProvider resourceProvider : ServiceLoader.load(ResourceProvider.class)) {
if (resourcesConfig
.getDisabledResourceProviders()
.contains(resourceProvider.getClass().getName())) {
if (disabledResourceProviders.contains(resourceProvider.getClass().getName())) {
continue;
}
result = result.merge(resourceProvider.create());

View File

@ -16,8 +16,6 @@ import io.opentelemetry.api.common.Attributes;
*
* <p>Resources specified via system properties or environment variables will take precedence over
* any value supplied via {@code ResourceProvider}.
*
* @see EnvAutodetectResource
*/
public abstract class ResourceProvider {

View File

@ -1,135 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.sdk.resources;
import static java.util.Objects.requireNonNull;
import com.google.auto.value.AutoValue;
import java.util.Arrays;
import java.util.Collections;
import java.util.Map;
import java.util.Properties;
import java.util.Set;
import java.util.stream.Collectors;
import javax.annotation.concurrent.Immutable;
/**
* Class that holds global resources parameters.
*
* <p>Configuration options for {@link ResourcesConfig} can be read from system properties,
* environment variables, or {@link Properties} objects.
*
* <p>For system properties and {@link Properties} objects, {@link ResourcesConfig} will look for
* the following names:
*
* <ul>
* <li>{@code otel.java.disabled.resource_providers}: to set the fully qualified class names of
* {@link ResourceProvider} implementations that are found on the classpath but should be
* disabled.
* </ul>
*
* <p>For environment variables, {@link ResourcesConfig} will look for the following names:
*
* <ul>
* <li>{@code OTEL_JAVA_DISABLED_RESOURCES_PROVIDERS}: to set the fully qualified class names of
* {@link ResourceProvider} implementations that are found on the classpath but should be
* disabled.
* </ul>
*/
@AutoValue
@Immutable
public abstract class ResourcesConfig {
/**
* Returns the default {@code ResourcesConfig}.
*
* @return the default {@code ResourcesConfig}.
*/
public static ResourcesConfig getDefault() {
return DEFAULT;
}
private static final ResourcesConfig DEFAULT = ResourcesConfig.builder().build();
/**
* Returns the fully qualified class names of {@link ResourceProvider} implementations that are
* found on the classpath but should be disabled.
*
* @return the fully qualified class names of {@link ResourceProvider} implementations that are
* found on the classpath but should be disabled.
*/
public abstract Set<String> getDisabledResourceProviders();
static Builder builder() {
return new AutoValue_ResourcesConfig.Builder()
.setDisabledResourceProviders(Collections.emptySet());
}
/**
* Returns a {@link Builder} initialized to the same property values as the current instance.
*
* @return a {@link Builder} initialized to the same property values as the current instance.
*/
public abstract Builder toBuilder();
/** Builder for {@link ResourcesConfig}. */
@AutoValue.Builder
@SuppressWarnings("deprecation") // Remove after ConfigBuilder is deleted
abstract static class Builder extends io.opentelemetry.sdk.common.export.ConfigBuilder<Builder> {
private static final String OTEL_JAVA_DISABLED_RESOURCES_PROVIDERS =
"otel.java.disabled.resource_providers";
Builder() {}
/**
* Sets the configuration values from the given configuration map for only the available keys.
*
* @param configMap {@link Map} holding the configuration values.
* @return this
*/
// Visible for testing
@Override
protected Builder fromConfigMap(
Map<String, String> configMap, NamingConvention namingConvention) {
configMap = namingConvention.normalize(configMap);
String stringValue = getStringProperty(OTEL_JAVA_DISABLED_RESOURCES_PROVIDERS, configMap);
if (stringValue != null) {
this.setDisabledResourceProviders(
Collections.unmodifiableSet(
Arrays.stream(stringValue.split(","))
.map(String::trim)
.filter(s -> !s.isEmpty())
.collect(Collectors.toSet())));
}
return this;
}
/**
* Sets the fully qualified class names of {@link ResourceProvider} implementations that are
* found on the classpath but should be disabled.
*
* @param disabledResourceProviders the fully qualified class names of {@link ResourceProvider}
* implementations that are found on the classpath but should be disabled.
* @return this.
*/
public abstract Builder setDisabledResourceProviders(Set<String> disabledResourceProviders);
abstract ResourcesConfig autoBuild();
/**
* Builds and returns a {@code ResourcesConfig} with the desired values.
*
* @return a {@code ResourcesConfig} with the desired values.
*/
public ResourcesConfig build() {
ResourcesConfig resourcesConfig = autoBuild();
requireNonNull(resourcesConfig.getDisabledResourceProviders(), "disabledResourceProviders");
return resourcesConfig;
}
}
}

View File

@ -1,283 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.sdk.common.export;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.entry;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import org.junit.jupiter.api.Nested;
import org.junit.jupiter.api.Test;
import org.junitpioneer.jupiter.SetEnvironmentVariable;
import org.junitpioneer.jupiter.SetSystemProperty;
/** Tests for {@link io.opentelemetry.sdk.common.export.ConfigBuilder}. */
@SuppressWarnings("deprecation") // Remove after ConfigBuilder is deleted
public class ConfigBuilderTest {
@Test
void normalize() {
Map<String, String> dotValues =
ConfigBuilder.NamingConvention.DOT.normalize(
Collections.singletonMap("Test.Config.Key", "value"));
assertThat(dotValues).containsEntry("test.config.key", "value");
Map<String, String> envValue =
ConfigBuilder.NamingConvention.ENV_VAR.normalize(
Collections.singletonMap("TEST_CONFIG_KEY", "value"));
assertThat(envValue).containsEntry("test.config.key", "value");
}
@Test
void booleanProperty() {
Boolean booleanProperty =
ConfigBuilder.getBooleanProperty("boolean", Collections.singletonMap("boolean", "true"));
assertThat(booleanProperty).isTrue();
}
@Test
void longProperty() {
Long longProperty =
ConfigBuilder.getLongProperty("long", Collections.singletonMap("long", "42343"));
assertThat(longProperty).isEqualTo(42343);
}
@Test
void intProperty() {
Integer intProperty =
ConfigBuilder.getIntProperty("int", Collections.singletonMap("int", "43543"));
assertThat(intProperty).isEqualTo(43543);
}
@Test
void doubleProperty() {
Double doubleProperty =
ConfigBuilder.getDoubleProperty("double", Collections.singletonMap("double", "5.6"));
assertThat(doubleProperty).isEqualTo(5.6);
}
@Test
void invalidBooleanProperty() {
Boolean booleanProperty =
ConfigBuilder.getBooleanProperty("boolean", Collections.singletonMap("boolean", "23435"));
assertThat(booleanProperty).isFalse();
}
@Test
void invalidLongProperty() {
Long longProperty =
ConfigBuilder.getLongProperty("long", Collections.singletonMap("long", "45.6"));
assertThat(longProperty).isNull();
}
@Test
void invalidIntProperty() {
Integer intProperty =
ConfigBuilder.getIntProperty("int", Collections.singletonMap("int", "false"));
assertThat(intProperty).isNull();
}
@Test
void invalidDoubleProperty() {
Double doubleProperty =
ConfigBuilder.getDoubleProperty("double", Collections.singletonMap("double", "something"));
assertThat(doubleProperty).isNull();
}
@Test
void nullValue_BooleanProperty() {
Boolean booleanProperty = ConfigBuilder.getBooleanProperty("boolean", Collections.emptyMap());
assertThat(booleanProperty).isNull();
}
@Test
void nullValue_LongProperty() {
Long longProperty = ConfigBuilder.getLongProperty("long", Collections.emptyMap());
assertThat(longProperty).isNull();
}
@Test
void nullValue_IntProperty() {
Integer intProperty = ConfigBuilder.getIntProperty("int", Collections.emptyMap());
assertThat(intProperty).isNull();
}
@Test
void nullValue_DoubleProperty() {
Double doubleProperty = ConfigBuilder.getDoubleProperty("double", Collections.emptyMap());
assertThat(doubleProperty).isNull();
}
@Test
void testNormalize_dot() {
assertThat(ConfigBuilder.NamingConvention.DOT.normalize("lower.case")).isEqualTo("lower.case");
assertThat(ConfigBuilder.NamingConvention.DOT.normalize("lower_case")).isEqualTo("lower_case");
assertThat(ConfigBuilder.NamingConvention.DOT.normalize("loWer.cAsE")).isEqualTo("lower.case");
assertThat(ConfigBuilder.NamingConvention.DOT.normalize("loWer_cAsE")).isEqualTo("lower_case");
}
@Test
void testNormalize_env() {
assertThat(ConfigBuilder.NamingConvention.ENV_VAR.normalize("lower.case"))
.isEqualTo("lower.case");
assertThat(ConfigBuilder.NamingConvention.ENV_VAR.normalize("lower_case"))
.isEqualTo("lower.case");
assertThat(ConfigBuilder.NamingConvention.ENV_VAR.normalize("loWer.cAsE"))
.isEqualTo("lower.case");
assertThat(ConfigBuilder.NamingConvention.ENV_VAR.normalize("loWer_cAsE"))
.isEqualTo("lower.case");
}
@Test
void testNormalize_dotMap() {
Map<String, String> map = new HashMap<>();
map.put("lower.case", "1");
map.put("lower_case", "2");
map.put("loWer.cAsE", "3");
map.put("loWer_cAsE", "4");
Map<String, String> normalized = ConfigBuilder.NamingConvention.DOT.normalize(map);
assertThat(normalized.size()).isEqualTo(2);
assertThat(normalized).containsOnly(entry("lower.case", "3"), entry("lower_case", "4"));
}
@Test
void testNormalize_envMap() {
Map<String, String> map = new HashMap<>();
map.put("lower.case", "1");
map.put("lower_case", "2");
map.put("loWer.cAsE", "3");
map.put("loWer_cAsE", "4");
Map<String, String> normalized = ConfigBuilder.NamingConvention.ENV_VAR.normalize(map);
assertThat(normalized.size()).isEqualTo(1);
assertThat(normalized).containsExactly(entry("lower.case", "3"));
}
@Test
void testBoolProperty() {
Map<String, String> map = new HashMap<>();
map.put("int", "1");
map.put("long", "2L");
map.put("boolt", "true");
map.put("boolf", "false");
map.put("string", "random");
assertThat(ConfigBuilder.getBooleanProperty("int", map)).isFalse();
assertThat(ConfigBuilder.getBooleanProperty("long", map)).isFalse();
assertThat(ConfigBuilder.getBooleanProperty("boolt", map)).isTrue();
assertThat(ConfigBuilder.getBooleanProperty("boolf", map)).isFalse();
assertThat(ConfigBuilder.getBooleanProperty("string", map)).isFalse();
assertThat(ConfigBuilder.getBooleanProperty("no-key", map)).isNull();
}
@Test
void testIntProperty() {
Map<String, String> map = new HashMap<>();
map.put("int", "1");
map.put("long", "2L");
map.put("boolt", "true");
map.put("boolf", "false");
map.put("string", "random");
assertThat(ConfigBuilder.getIntProperty("int", map)).isNotNull();
assertThat(ConfigBuilder.getIntProperty("int", map)).isEqualTo(1);
assertThat(ConfigBuilder.getIntProperty("long", map)).isNull();
assertThat(ConfigBuilder.getIntProperty("boolt", map)).isNull();
assertThat(ConfigBuilder.getIntProperty("boolf", map)).isNull();
assertThat(ConfigBuilder.getIntProperty("string", map)).isNull();
assertThat(ConfigBuilder.getIntProperty("no-key", map)).isNull();
}
@Test
void testLongProperty() {
Map<String, String> map = new HashMap<>();
map.put("int", "1");
map.put("long", "2L");
map.put("boolt", "true");
map.put("boolf", "false");
map.put("string", "random");
assertThat(ConfigBuilder.getLongProperty("int", map)).isNotNull();
assertThat(ConfigBuilder.getLongProperty("int", map)).isEqualTo(1);
assertThat(ConfigBuilder.getLongProperty("long", map)).isNull();
assertThat(ConfigBuilder.getLongProperty("boolt", map)).isNull();
assertThat(ConfigBuilder.getLongProperty("boolf", map)).isNull();
assertThat(ConfigBuilder.getLongProperty("string", map)).isNull();
assertThat(ConfigBuilder.getLongProperty("no-key", map)).isNull();
}
@Test
void testStringProperty() {
Map<String, String> map = new HashMap<>();
map.put("int", "1");
map.put("long", "2L");
map.put("boolt", "true");
map.put("boolf", "false");
map.put("string", "random");
assertThat(ConfigBuilder.getStringProperty("int", map)).isNotNull();
assertThat(ConfigBuilder.getStringProperty("long", map)).isNotNull();
assertThat(ConfigBuilder.getStringProperty("boolt", map)).isNotNull();
assertThat(ConfigBuilder.getStringProperty("boolf", map)).isNotNull();
assertThat(ConfigBuilder.getStringProperty("string", map)).isNotNull();
assertThat(ConfigBuilder.getStringProperty("no-key", map)).isNull();
}
private static final class ConfigTester
extends io.opentelemetry.sdk.common.export.ConfigBuilder<Map<String, String>> {
public static NamingConvention getNamingDot() {
return NamingConvention.DOT;
}
@Override
protected Map<String, String> fromConfigMap(
Map<String, String> configMap, NamingConvention namingConvention) {
return configMap;
}
}
@Nested
@SuppressWarnings("ClassCanBeStatic")
class ConfigurationSystemPropertiesTest {
@Test
@SetSystemProperty(key = "int", value = "1")
@SetSystemProperty(key = "long", value = "2L")
@SetSystemProperty(key = "boolt", value = "true")
@SetSystemProperty(key = "boolf", value = "false")
@SetSystemProperty(key = "string", value = "random")
public void testSystemProperties() {
ConfigTester config = new ConfigTester();
Map<String, String> map = config.readSystemProperties();
assertThat(ConfigBuilder.getStringProperty("int", map)).isEqualTo("1");
assertThat(ConfigBuilder.getStringProperty("long", map)).isEqualTo("2L");
assertThat(ConfigBuilder.getStringProperty("boolt", map)).isEqualTo("true");
assertThat(ConfigBuilder.getStringProperty("boolf", map)).isEqualTo("false");
assertThat(ConfigBuilder.getStringProperty("string", map)).isEqualTo("random");
assertThat(ConfigBuilder.getStringProperty("no-key", map)).isNull();
}
}
@Nested
@SuppressWarnings("ClassCanBeStatic")
class ConfigurationEnvVarsTest {
@Test
@SetEnvironmentVariable(key = "int", value = "1")
@SetEnvironmentVariable(key = "long", value = "2L")
@SetEnvironmentVariable(key = "boolt", value = "true")
@SetEnvironmentVariable(key = "boolf", value = "false")
@SetEnvironmentVariable(key = "string", value = "random")
public void testEnvironmentVariables() {
ConfigTester config = new ConfigTester();
Map<String, String> map = config.readEnvironmentVariables();
assertThat(ConfigBuilder.getStringProperty("int", map)).isEqualTo("1");
assertThat(ConfigBuilder.getStringProperty("long", map)).isEqualTo("2L");
assertThat(ConfigBuilder.getStringProperty("boolt", map)).isEqualTo("true");
assertThat(ConfigBuilder.getStringProperty("boolf", map)).isEqualTo("false");
assertThat(ConfigBuilder.getStringProperty("string", map)).isEqualTo("random");
assertThat(ConfigBuilder.getStringProperty("no-key", map)).isNull();
}
}
}

View File

@ -1,89 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.sdk.resources;
import static io.opentelemetry.api.common.AttributeKey.stringKey;
import static org.assertj.core.api.Assertions.assertThat;
import io.opentelemetry.api.common.Attributes;
import org.junit.jupiter.api.Test;
import org.junitpioneer.jupiter.SetEnvironmentVariable;
/** Tests for the {@link EnvAutodetectResource}. */
class EnvAutodetectResourceTest {
@Test
void parseResourceAttributes_null() {
assertThat(EnvAutodetectResource.parseResourceAttributes(null).isEmpty()).isTrue();
}
@Test
void parseResourceAttributes_empty() {
assertThat(EnvAutodetectResource.parseResourceAttributes("").isEmpty()).isTrue();
}
@Test
void parseResourceAttributes_malformed() {
assertThat(EnvAutodetectResource.parseResourceAttributes("value/foo").isEmpty()).isTrue();
}
@Test
void parseResourceAttributes_single() {
Attributes result = EnvAutodetectResource.parseResourceAttributes("value=foo");
assertThat(result).isEqualTo(Attributes.of(stringKey("value"), "foo"));
}
@Test
void parseResourceAttributes_multi() {
Attributes result = EnvAutodetectResource.parseResourceAttributes("value=foo, other=bar");
assertThat(result)
.isEqualTo(
Attributes.of(
stringKey("value"), "foo",
stringKey("other"), "bar"));
}
@Test
void parseResourceAttributes_whitespace() {
Attributes result = EnvAutodetectResource.parseResourceAttributes(" value = foo ");
assertThat(result).isEqualTo(Attributes.of(stringKey("value"), "foo"));
}
@Test
void parseResourceAttributes_quotes() {
Attributes result = EnvAutodetectResource.parseResourceAttributes("value=\"foo\"");
assertThat(result).isEqualTo(Attributes.of(stringKey("value"), "foo"));
}
@Test
void getResourceAttributes_properties() {
String key = "otel.resource.attributes";
System.setProperty(key, "value = foo");
Resource resource =
new EnvAutodetectResource.Builder()
.readEnvironmentVariables()
.readSystemProperties()
.build();
Attributes result = resource.getAttributes();
assertThat(result).isEqualTo(Attributes.of(stringKey("value"), "foo"));
System.clearProperty(key);
}
public static class ResourceAttributesEnvVarsTest {
@Test
@SetEnvironmentVariable(key = "OTEL_RESOURCE_ATTRIBUTES", value = "value = foo")
public void getResourceAttributes_envvars() {
Resource resource =
new EnvAutodetectResource.Builder()
.readEnvironmentVariables()
.readSystemProperties()
.build();
Attributes result = resource.getAttributes();
assertThat(result).isEqualTo(Attributes.of(stringKey("value"), "foo"));
}
}
}

View File

@ -1,59 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.sdk.resources;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import com.google.common.collect.ImmutableSet;
import org.junit.jupiter.api.Test;
class ResourcesConfigTest {
@Test
void defaultResourcesConfig() {
assertThat(ResourcesConfig.getDefault().getDisabledResourceProviders())
.isEqualTo(ImmutableSet.of());
}
@Test
void updateResourcesConfig_NullDisabledResourceProviders() {
assertThatThrownBy(
() ->
ResourcesConfig.getDefault().toBuilder().setDisabledResourceProviders(null).build())
.isInstanceOf(NullPointerException.class);
}
@Test
void updateResourcesConfig_SystemProperties() {
System.setProperty(
"otel.java.disabled.resource_providers",
"com.package.provider.ToDisable1, com.package.provider.ToDisable2");
ResourcesConfig resourcesConfig =
ResourcesConfig.builder().readSystemProperties().readEnvironmentVariables().build();
assertThat(resourcesConfig.getDisabledResourceProviders())
.isEqualTo(
ImmutableSet.of("com.package.provider.ToDisable1", "com.package.provider.ToDisable2"));
}
@Test
void updateResourcesConfig_EmptyDisabledResourceProviders() {
System.setProperty("otel.java.disabled.resource_providers", "");
ResourcesConfig resourcesConfig =
ResourcesConfig.builder().readSystemProperties().readEnvironmentVariables().build();
assertThat(resourcesConfig.getDisabledResourceProviders()).isEqualTo(ImmutableSet.of());
}
@Test
void updateResourcesConfig_All() {
ResourcesConfig resourcesConfig =
ResourcesConfig.builder()
.setDisabledResourceProviders(ImmutableSet.of("com.package.provider.ToDisable"))
.build();
assertThat(resourcesConfig.getDisabledResourceProviders())
.isEqualTo(ImmutableSet.of("com.package.provider.ToDisable"));
}
}

View File

@ -25,22 +25,6 @@ import javax.annotation.concurrent.Immutable;
* Wraps a list of {@link MetricProducer}s and automatically reads and exports the metrics every
* export interval. Metrics may also be dropped when it becomes time to export again, and there is
* an export in progress.
*
* <p>Configuration options for {@link IntervalMetricReader} can be read from system properties,
* environment variables, or {@link java.util.Properties} objects.
*
* <p>For system properties and {@link java.util.Properties} objects, {@link IntervalMetricReader}
* will look for the following names:
*
* <ul>
* <li>{@code otel.imr.export.interval}: sets the export interval between pushes to the exporter.
* </ul>
*
* <p>For environment variables, {@link IntervalMetricReader} will look for the following names:
*
* <ul>
* <li>{@code OTEL_IMR_EXPORT_INTERVAL}: sets the export interval between pushes to the exporter.
* </ul>
*/
public final class IntervalMetricReader {
private static final Logger logger = Logger.getLogger(IntervalMetricReader.class.getName());
@ -80,9 +64,11 @@ public final class IntervalMetricReader {
* default value.
*
* @return a new {@link IntervalMetricReaderBuilder} for {@link IntervalMetricReader}.
* @deprecated Use {@link #builder()}
*/
@Deprecated
public static IntervalMetricReaderBuilder builderFromDefaultSources() {
return builder().readEnvironmentVariables().readSystemProperties();
return builder();
}
@SuppressWarnings("FutureReturnValueIgnored")

View File

@ -7,14 +7,10 @@ package io.opentelemetry.sdk.metrics.export;
import io.opentelemetry.api.internal.Utils;
import java.util.Collection;
import java.util.Map;
/** Builder for {@link IntervalMetricReader}. */
@SuppressWarnings("deprecation") // Remove after ConfigBuilder is deleted
public final class IntervalMetricReaderBuilder
extends io.opentelemetry.sdk.common.export.ConfigBuilder<IntervalMetricReaderBuilder> {
public final class IntervalMetricReaderBuilder {
private final IntervalMetricReader.InternalState.Builder optionsBuilder;
private static final String KEY_EXPORT_INTERVAL = "otel.imr.export.interval";
IntervalMetricReaderBuilder(IntervalMetricReader.InternalState.Builder optionsBuilder) {
this.optionsBuilder = optionsBuilder;
@ -67,21 +63,4 @@ public final class IntervalMetricReaderBuilder
return new IntervalMetricReader(internalState);
}
/**
* Sets the configuration values from the given configuration map for only the available keys.
*
* @param configMap {@link Map} holding the configuration values.
* @return this.
*/
@Override
protected IntervalMetricReaderBuilder fromConfigMap(
Map<String, String> configMap, NamingConvention namingConvention) {
configMap = namingConvention.normalize(configMap);
Long value = getLongProperty(KEY_EXPORT_INTERVAL, configMap);
if (value != null) {
this.setExportIntervalMillis(value);
}
return this;
}
}

View File

@ -17,11 +17,9 @@ import io.opentelemetry.sdk.metrics.data.LongSumData;
import io.opentelemetry.sdk.metrics.data.MetricData;
import io.opentelemetry.sdk.resources.Resource;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.TimeUnit;
@ -60,21 +58,6 @@ class IntervalMetricReaderTest {
when(metricProducer.collectAllMetrics()).thenReturn(Collections.singletonList(METRIC_DATA));
}
@Test
void configTest() {
Properties options = new Properties();
options.put("otel.imr.export.interval", "12");
IntervalMetricReaderBuilder config =
IntervalMetricReader.builder()
.readProperties(options)
.setMetricProducers(Arrays.asList(metricProducer))
.setMetricExporter(metricExporter);
assertThat(config)
.extracting("optionsBuilder")
.extracting("exportIntervalMillis")
.isEqualTo(12L);
}
@Test
void intervalExport() throws Exception {
WaitingMetricExporter waitingMetricExporter = new WaitingMetricExporter();

View File

@ -10,21 +10,9 @@ import static java.util.Objects.requireNonNull;
import io.opentelemetry.api.internal.Utils;
import io.opentelemetry.api.trace.Span;
import io.opentelemetry.sdk.trace.samplers.Sampler;
import java.util.Map;
import java.util.Properties;
/** Builder for {@link TraceConfig}. */
@SuppressWarnings("deprecation") // Remove after ConfigBuilder is deleted
public final class TraceConfigBuilder
extends io.opentelemetry.sdk.common.export.ConfigBuilder<TraceConfigBuilder> {
private static final String KEY_SAMPLER_PROBABILITY = "otel.config.sampler.probability";
private static final String KEY_SPAN_ATTRIBUTE_COUNT_LIMIT = "otel.span.attribute.count.limit";
private static final String KEY_SPAN_EVENT_COUNT_LIMIT = "otel.span.event.count.limit";
private static final String KEY_SPAN_LINK_COUNT_LIMIT = "otel.span.link.count.limit";
private static final String KEY_SPAN_MAX_NUM_ATTRIBUTES_PER_EVENT = "otel.config.max.event.attrs";
private static final String KEY_SPAN_MAX_NUM_ATTRIBUTES_PER_LINK = "otel.config.max.link.attrs";
private static final String KEY_SPAN_ATTRIBUTE_MAX_VALUE_LENGTH = "otel.config.max.attr.length";
public final class TraceConfigBuilder {
private static final Sampler DEFAULT_SAMPLER = Sampler.parentBased(Sampler.alwaysOn());
private static final int DEFAULT_SPAN_MAX_NUM_ATTRIBUTES = 1000;
private static final int DEFAULT_SPAN_MAX_NUM_EVENTS = 1000;
@ -43,79 +31,6 @@ public final class TraceConfigBuilder
TraceConfigBuilder() {}
/**
* Sets the configuration values from the given configuration map for only the available keys.
*
* @param configMap {@link Map} holding the configuration values.
* @return this
*/
// Visible for testing
@Override
protected TraceConfigBuilder fromConfigMap(
Map<String, String> configMap, NamingConvention namingConvention) {
configMap = namingConvention.normalize(configMap);
Double doubleValue = getDoubleProperty(KEY_SAMPLER_PROBABILITY, configMap);
if (doubleValue != null) {
this.setTraceIdRatioBased(doubleValue);
}
Integer intValue = getIntProperty(KEY_SPAN_ATTRIBUTE_COUNT_LIMIT, configMap);
if (intValue != null) {
this.setMaxNumberOfAttributes(intValue);
}
intValue = getIntProperty(KEY_SPAN_EVENT_COUNT_LIMIT, configMap);
if (intValue != null) {
this.setMaxNumberOfEvents(intValue);
}
intValue = getIntProperty(KEY_SPAN_LINK_COUNT_LIMIT, configMap);
if (intValue != null) {
this.setMaxNumberOfLinks(intValue);
}
intValue = getIntProperty(KEY_SPAN_MAX_NUM_ATTRIBUTES_PER_EVENT, configMap);
if (intValue != null) {
this.setMaxNumberOfAttributesPerEvent(intValue);
}
intValue = getIntProperty(KEY_SPAN_MAX_NUM_ATTRIBUTES_PER_LINK, configMap);
if (intValue != null) {
this.setMaxNumberOfAttributesPerLink(intValue);
}
intValue = getIntProperty(KEY_SPAN_ATTRIBUTE_MAX_VALUE_LENGTH, configMap);
if (intValue != null) {
this.setMaxLengthOfAttributeValues(intValue);
}
return this;
}
/**
* * Sets the configuration values from the given properties object for only the available keys.
*
* @param properties {@link Properties} holding the configuration values.
* @return this
*/
@Override
public TraceConfigBuilder readProperties(Properties properties) {
return super.readProperties(properties);
}
/**
* * Sets the configuration values from environment variables for only the available keys.
*
* @return this.
*/
@Override
public TraceConfigBuilder readEnvironmentVariables() {
return super.readEnvironmentVariables();
}
/**
* * Sets the configuration values from system properties for only the available keys.
*
* @return this.
*/
@Override
public TraceConfigBuilder readSystemProperties() {
return super.readSystemProperties();
}
/**
* Sets the global default {@code Sampler}. It must be not {@code null} otherwise {@link #build()}
* will throw an exception.

View File

@ -37,30 +37,6 @@ import java.util.logging.Logger;
*
* <p>This batch {@link SpanProcessor} can cause high contention in a very high traffic service.
* TODO: Add a link to the SpanProcessor that uses Disruptor as alternative with low contention.
*
* <p>Configuration options for {@link BatchSpanProcessor} can be read from system properties,
* environment variables, or {@link java.util.Properties} objects.
*
* <p>For system properties and {@link java.util.Properties} objects, {@link BatchSpanProcessor}
* will look for the following names:
*
* <ul>
* <li>{@code otel.bsp.schedule.delay}: sets the delay interval between two consecutive exports.
* <li>{@code otel.bsp.max.queue}: sets the maximum queue size.
* <li>{@code otel.bsp.max.export.batch}: sets the maximum batch size.
* <li>{@code otel.bsp.export.timeout}: sets the maximum allowed time to export data.
* <li>{@code otel.bsp.export.sampled}: sets whether only sampled spans should be exported.
* </ul>
*
* <p>For environment variables, {@link BatchSpanProcessor} will look for the following names:
*
* <ul>
* <li>{@code OTEL_BSP_SCHEDULE_DELAY}: sets the delay interval between two consecutive exports.
* <li>{@code OTEL_BSP_MAX_QUEUE}: sets the maximum queue size.
* <li>{@code OTEL_BSP_MAX_EXPORT_BATCH}: sets the maximum batch size.
* <li>{@code OTEL_BSP_EXPORT_TIMEOUT}: sets the maximum allowed time to export data.
* <li>{@code OTEL_BSP_EXPORT_SAMPLED}: sets whether only sampled spans should be exported.
* </ul>
*/
public final class BatchSpanProcessor implements SpanProcessor {

View File

@ -9,19 +9,10 @@ import static io.opentelemetry.api.internal.Utils.checkArgument;
import static java.util.Objects.requireNonNull;
import java.time.Duration;
import java.util.Map;
import java.util.concurrent.TimeUnit;
/** Builder class for {@link BatchSpanProcessor}. */
@SuppressWarnings("deprecation") // Remove after ConfigBuilder is deleted
public final class BatchSpanProcessorBuilder
extends io.opentelemetry.sdk.common.export.ConfigBuilder<BatchSpanProcessorBuilder> {
private static final String KEY_SCHEDULE_DELAY_MILLIS = "otel.bsp.schedule.delay.millis";
private static final String KEY_MAX_QUEUE_SIZE = "otel.bsp.max.queue.size";
private static final String KEY_MAX_EXPORT_BATCH_SIZE = "otel.bsp.max.export.batch.size";
private static final String KEY_EXPORT_TIMEOUT_MILLIS = "otel.bsp.export.timeout.millis";
private static final String KEY_SAMPLED = "otel.bsp.export.sampled";
public final class BatchSpanProcessorBuilder {
// Visible for testing
static final long DEFAULT_SCHEDULE_DELAY_MILLIS = 5000;
@ -45,39 +36,6 @@ public final class BatchSpanProcessorBuilder
this.spanExporter = requireNonNull(spanExporter, "spanExporter");
}
/**
* Sets the configuration values from the given configuration map for only the available keys.
*
* @param configMap {@link Map} holding the configuration values.
* @return this.
*/
@Override
protected BatchSpanProcessorBuilder fromConfigMap(
Map<String, String> configMap, NamingConvention namingConvention) {
configMap = namingConvention.normalize(configMap);
Long longValue = getLongProperty(KEY_SCHEDULE_DELAY_MILLIS, configMap);
if (longValue != null) {
this.setScheduleDelay(Duration.ofMillis(longValue));
}
Integer intValue = getIntProperty(KEY_MAX_QUEUE_SIZE, configMap);
if (intValue != null) {
this.setMaxQueueSize(intValue);
}
intValue = getIntProperty(KEY_MAX_EXPORT_BATCH_SIZE, configMap);
if (intValue != null) {
this.setMaxExportBatchSize(intValue);
}
intValue = getIntProperty(KEY_EXPORT_TIMEOUT_MILLIS, configMap);
if (intValue != null) {
this.setExporterTimeout(Duration.ofMillis(intValue));
}
Boolean boolValue = getBooleanProperty(KEY_SAMPLED, configMap);
if (boolValue != null) {
this.setExportOnlySampled(boolValue);
}
return this;
}
// TODO: Consider to add support for constant Attributes and/or Resource.
/**

View File

@ -24,22 +24,6 @@ import java.util.logging.Logger;
* SpanData} and passes it directly to the configured exporter. This processor should only be used
* where the exporter(s) are able to handle multiple exports simultaneously, as there is no back
* pressure consideration here.
*
* <p>Configuration options for {@link SimpleSpanProcessor} can be read from system properties,
* environment variables, or {@link java.util.Properties} objects.
*
* <p>For system properties and {@link java.util.Properties} objects, {@link SimpleSpanProcessor}
* will look for the following names:
*
* <ul>
* <li>{@code otel.ssp.export.sampled}: sets whether only sampled spans should be exported.
* </ul>
*
* <p>For environment variables, {@link SimpleSpanProcessor} will look for the following names:
*
* <ul>
* <li>{@code OTEL_SSP_EXPORT_SAMPLED}: sets whether only sampled spans should be exported.
* </ul>
*/
public final class SimpleSpanProcessor implements SpanProcessor {
@ -58,19 +42,6 @@ public final class SimpleSpanProcessor implements SpanProcessor {
return new SimpleSpanProcessor(exporter, /* sampled= */ true);
}
/**
* Returns a new Builder for {@link SimpleSpanProcessor}.
*
* @param spanExporter the {@code SpanExporter} to where the Spans are pushed.
* @return a new {@link SimpleSpanProcessor}.
* @throws NullPointerException if the {@code spanExporter} is {@code null}.
* @deprecated Use {@link SimpleSpanProcessor#create(SpanExporter)}
*/
@Deprecated
public static SimpleSpanProcessorBuilder builder(SpanExporter spanExporter) {
return new SimpleSpanProcessorBuilder(spanExporter);
}
SimpleSpanProcessor(SpanExporter spanExporter, boolean sampled) {
this.spanExporter = requireNonNull(spanExporter, "spanExporter");
this.sampled = sampled;

View File

@ -1,85 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.sdk.trace.export;
import java.util.Map;
import java.util.Objects;
/**
* Builder class for {@link SimpleSpanProcessor}.
*
* @deprecated Use {@link SimpleSpanProcessor#create(SpanExporter)}
*/
@Deprecated
@SuppressWarnings("deprecation") // Remove after ConfigBuilder is deleted
public final class SimpleSpanProcessorBuilder
extends io.opentelemetry.sdk.common.export.ConfigBuilder<SimpleSpanProcessorBuilder> {
private static final String KEY_SAMPLED = "otel.ssp.export.sampled";
// Visible for testing
static final boolean DEFAULT_EXPORT_ONLY_SAMPLED = true;
private final SpanExporter spanExporter;
private boolean exportOnlySampled = DEFAULT_EXPORT_ONLY_SAMPLED;
SimpleSpanProcessorBuilder(SpanExporter spanExporter) {
this.spanExporter = Objects.requireNonNull(spanExporter, "spanExporter");
}
/**
* Sets the configuration values from the given configuration map for only the available keys.
* This method looks for the following keys:
*
* <ul>
* <li>{@code otel.ssp.export.sampled}: to set whether only sampled spans should be exported.
* </ul>
*
* @param configMap {@link Map} holding the configuration values.
* @return this.
*/
@Override
protected SimpleSpanProcessorBuilder fromConfigMap(
Map<String, String> configMap, NamingConvention namingConvention) {
configMap = namingConvention.normalize(configMap);
Boolean boolValue = getBooleanProperty(KEY_SAMPLED, configMap);
if (boolValue != null) {
return this.setExportOnlySampled(boolValue);
}
return this;
}
/**
* Set whether only sampled spans should be exported.
*
* <p>Default value is {@code true}.
*
* @param exportOnlySampled if {@code true} report only sampled spans.
* @return this.
*/
public SimpleSpanProcessorBuilder setExportOnlySampled(boolean exportOnlySampled) {
this.exportOnlySampled = exportOnlySampled;
return this;
}
// Visible for testing
boolean getExportOnlySampled() {
return exportOnlySampled;
}
// TODO: Add metrics for total exported spans.
// TODO: Consider to add support for constant Attributes and/or Resource.
/**
* Returns a new {@link SimpleSpanProcessor} that converts spans to proto and forwards them to the
* given {@code spanExporter}.
*
* @return a new {@link SimpleSpanProcessor}.
* @throws NullPointerException if the {@code spanExporter} is {@code null}.
*/
public SimpleSpanProcessor build() {
return new SimpleSpanProcessor(spanExporter, exportOnlySampled);
}
}

View File

@ -1,88 +0,0 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.sdk.trace.config;
import static org.assertj.core.api.Assertions.assertThat;
import static org.assertj.core.api.Assertions.assertThatThrownBy;
import io.opentelemetry.sdk.trace.samplers.Sampler;
import org.junit.jupiter.api.AfterEach;
import org.junit.jupiter.api.Test;
public class TraceConfigSystemPropertiesTest {
@AfterEach
void tearDown() {
System.clearProperty("otel.config.sampler.probability");
System.clearProperty("otel.span.attribute.count.limit");
System.clearProperty("otel.span.event.count.limit");
System.clearProperty("otel.span.link.count.limit");
System.clearProperty("otel.config.max.event.attrs");
System.clearProperty("otel.config.max.link.attrs");
}
@Test
void updateTraceConfig_SystemProperties() {
System.setProperty("otel.config.sampler.probability", "0.3");
System.setProperty("otel.span.attribute.count.limit", "5");
System.setProperty("otel.span.event.count.limit", "6");
System.setProperty("otel.span.link.count.limit", "9");
System.setProperty("otel.config.max.event.attrs", "7");
System.setProperty("otel.config.max.link.attrs", "11");
TraceConfig traceConfig =
TraceConfig.builder().readEnvironmentVariables().readSystemProperties().build();
// this is not a useful assertion. How can we do better?
assertThat(traceConfig.getSampler())
.isEqualTo(Sampler.parentBased(Sampler.traceIdRatioBased(0.3)));
assertThat(traceConfig.getMaxNumberOfAttributes()).isEqualTo(5);
assertThat(traceConfig.getMaxNumberOfEvents()).isEqualTo(6);
assertThat(traceConfig.getMaxNumberOfLinks()).isEqualTo(9);
assertThat(traceConfig.getMaxNumberOfAttributesPerEvent()).isEqualTo(7);
assertThat(traceConfig.getMaxNumberOfAttributesPerLink()).isEqualTo(11);
}
@Test
void updateTraceConfig_InvalidSamplerProbability() {
System.setProperty("otel.config.sampler.probability", "-1");
assertThatThrownBy(() -> TraceConfig.builder().readSystemProperties().build())
.isInstanceOf(IllegalArgumentException.class);
}
@Test
void updateTraceConfig_NonPositiveMaxNumberOfAttributes() {
System.setProperty("otel.span.attribute.count.limit", "-5");
assertThatThrownBy(() -> TraceConfig.builder().readSystemProperties().build())
.isInstanceOf(IllegalArgumentException.class);
}
@Test
void updateTraceConfig_NonPositiveMaxNumberOfEvents() {
System.setProperty("otel.span.event.count.limit", "-6");
assertThatThrownBy(() -> TraceConfig.builder().readSystemProperties().build())
.isInstanceOf(IllegalArgumentException.class);
}
@Test
void updateTraceConfig_NonPositiveMaxNumberOfLinks() {
System.setProperty("otel.span.link.count.limit", "-9");
assertThatThrownBy(() -> TraceConfig.builder().readSystemProperties().build())
.isInstanceOf(IllegalArgumentException.class);
}
@Test
void updateTraceConfig_NonPositiveMaxNumberOfAttributesPerEvent() {
System.setProperty("otel.config.max.event.attrs", "-7");
assertThatThrownBy(() -> TraceConfig.builder().readSystemProperties().build())
.isInstanceOf(IllegalArgumentException.class);
}
@Test
void updateTraceConfig_NonPositiveMaxNumberOfAttributesPerLink() {
System.setProperty("otel.config.max.link.attrs", "-10");
assertThatThrownBy(() -> TraceConfig.builder().readSystemProperties().build())
.isInstanceOf(IllegalArgumentException.class);
}
}

View File

@ -28,7 +28,6 @@ import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.CountDownLatch;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.atomic.AtomicBoolean;
@ -63,29 +62,10 @@ class BatchSpanProcessorTest {
return (ReadableSpan) span;
}
@Test
void configTest() {
Properties options = new Properties();
options.put("otel.bsp.schedule.delay.millis", "12");
options.put("otel.bsp.max.queue.size", "34");
options.put("otel.bsp.max.export.batch.size", "56");
options.put("otel.bsp.export.timeout.millis", "78");
options.put("otel.bsp.export.sampled", "false");
BatchSpanProcessorBuilder config =
BatchSpanProcessor.builder(new WaitingSpanExporter(0, CompletableResultCode.ofSuccess()))
.readProperties(options);
assertThat(config.getScheduleDelayNanos()).isEqualTo(TimeUnit.MILLISECONDS.toNanos(12));
assertThat(config.getMaxQueueSize()).isEqualTo(34);
assertThat(config.getMaxExportBatchSize()).isEqualTo(56);
assertThat(config.getExporterTimeoutNanos()).isEqualTo(TimeUnit.MILLISECONDS.toNanos(78));
assertThat(config.getExportOnlySampled()).isEqualTo(false);
}
@Test
void configTest_EmptyOptions() {
BatchSpanProcessorBuilder config =
BatchSpanProcessor.builder(new WaitingSpanExporter(0, CompletableResultCode.ofSuccess()))
.readProperties(new Properties());
BatchSpanProcessor.builder(new WaitingSpanExporter(0, CompletableResultCode.ofSuccess()));
assertThat(config.getScheduleDelayNanos())
.isEqualTo(
TimeUnit.MILLISECONDS.toNanos(BatchSpanProcessorBuilder.DEFAULT_SCHEDULE_DELAY_MILLIS));

View File

@ -32,7 +32,6 @@ import io.opentelemetry.sdk.trace.export.BatchSpanProcessorTest.WaitingSpanExpor
import io.opentelemetry.sdk.trace.samplers.Sampler;
import java.util.Collections;
import java.util.List;
import java.util.Properties;
import java.util.concurrent.atomic.AtomicReference;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
@ -76,23 +75,6 @@ class SimpleSpanProcessorTest {
.hasMessage("exporter");
}
@Test
void configTest() {
Properties options = new Properties();
options.put("otel.ssp.export.sampled", "false");
SimpleSpanProcessorBuilder config =
SimpleSpanProcessor.builder(spanExporter).readProperties(options);
assertThat(config.getExportOnlySampled()).isEqualTo(false);
}
@Test
void configTest_EmptyOptions() {
SimpleSpanProcessorBuilder config =
SimpleSpanProcessor.builder(spanExporter).readProperties(new Properties());
assertThat(config.getExportOnlySampled())
.isEqualTo(SimpleSpanProcessorBuilder.DEFAULT_EXPORT_ONLY_SAMPLED);
}
@Test
void onStartSync() {
simpleSampledSpansProcessor.onStart(Context.root(), readWriteSpan);
@ -218,42 +200,4 @@ class SimpleSpanProcessorTest {
simpleSampledSpansProcessor.close();
verify(spanExporter).shutdown();
}
@Test
void buildFromProperties_defaultSampledFlag() {
Properties properties = new Properties();
SimpleSpanProcessor spanProcessor =
SimpleSpanProcessor.builder(spanExporter).readProperties(properties).build();
when(readableSpan.getSpanContext()).thenReturn(NOT_SAMPLED_SPAN_CONTEXT);
spanProcessor.onEnd(readableSpan);
verifyNoInteractions(spanExporter);
}
@Test
void buildFromProperties_onlySampledTrue() {
Properties properties = new Properties();
properties.setProperty("otel.ssp.export.sampled", "true");
SimpleSpanProcessor spanProcessor =
SimpleSpanProcessor.builder(spanExporter).readProperties(properties).build();
when(readableSpan.getSpanContext()).thenReturn(NOT_SAMPLED_SPAN_CONTEXT);
spanProcessor.onEnd(readableSpan);
verifyNoInteractions(spanExporter);
}
@Test
void buildFromProperties_onlySampledFalse() {
Properties properties = new Properties();
properties.setProperty("otel.ssp.export.sampled", "false");
SimpleSpanProcessor spanProcessor =
SimpleSpanProcessor.builder(spanExporter).readProperties(properties).build();
SpanData spanData = TestUtils.makeBasicSpan();
when(readableSpan.getSpanContext()).thenReturn(NOT_SAMPLED_SPAN_CONTEXT);
when(readableSpan.toSpanData()).thenReturn(spanData);
spanProcessor.onEnd(readableSpan);
verify(spanExporter).export(Collections.singletonList(spanData));
}
}