Update exporter environment variable to latest spec's singular forms. (#2499)

* Update exporter environment variable to latest spec's singular forms.

* Fix!

* Use check per test-sets recommendation

* Missed one more
This commit is contained in:
Anuraag Agrawal 2021-01-13 13:46:26 +09:00 committed by GitHub
parent 9b85dfa3d4
commit efd559f1e0
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 189 additions and 164 deletions

View File

@ -12,7 +12,9 @@ ext.moduleName = "io.opentelemetry.sdk.autoconfigure"
testSets {
testConfigError
testFullConfig
testJaeger
testPrometheus
testZipkin
}
dependencies {
@ -43,6 +45,10 @@ dependencies {
testFullConfigImplementation libraries.prometheus_client_httpserver
testFullConfigImplementation project(':exporters:zipkin')
testJaegerImplementation project(':exporters:jaeger')
testZipkinImplementation project(':exporters:zipkin')
testConfigErrorImplementation project(':extensions:trace-propagators')
testConfigErrorImplementation project(':exporters:jaeger')
testConfigErrorImplementation project(':exporters:logging')
@ -59,7 +65,8 @@ dependencies {
testFullConfig {
environment("OTEL_RESOURCE_ATTRIBUTES", "service.name=test,cat=meow")
environment("OTEL_EXPORTER", "otlp,jaeger,zipkin")
environment("OTEL_TRACE_EXPORTER", "otlp")
environment("OTEL_METRICS_EXPORTER", "otlp")
environment("OTEL_PROPAGATORS", "tracecontext,baggage,b3,b3multi,jaeger,ottracer,xray,test")
environment("OTEL_BSP_SCHEDULE_DELAY_MILLIS", "10")
environment("OTEL_IMR_EXPORT_INTERVAL", "10")
@ -68,7 +75,19 @@ testFullConfig {
environment("OTEL_SPAN_ATTRIBUTE_COUNT_LIMIT", "2")
}
testJaeger {
environment("OTEL_TRACE_EXPORTER", "jaeger")
environment("OTEL_BSP_SCHEDULE_DELAY_MILLIS", "10")
}
testZipkin {
environment("OTEL_TRACE_EXPORTER", "zipkin")
environment("OTEL_BSP_SCHEDULE_DELAY_MILLIS", "10")
}
testPrometheus {
environment("OTEL_EXPORTER", "prometheus")
environment("OTEL_METRICS_EXPORTER", "prometheus")
environment("OTEL_IMR_EXPORT_INTERVAL", "10")
}
check.dependsOn(testConfigError, testFullConfig, testJaeger, testPrometheus, testZipkin)

View File

@ -14,39 +14,22 @@ import io.opentelemetry.sdk.metrics.export.IntervalMetricReaderBuilder;
import io.prometheus.client.exporter.HTTPServer;
import java.io.IOException;
import java.time.Duration;
import java.util.Arrays;
import java.util.Collections;
import java.util.List;
final class MetricExporterConfiguration {
static final List<String> RECOGNIZED_NAMES = Arrays.asList("otlp", "otlp_metrics", "prometheus");
static boolean configureExporter(
String name,
ConfigProperties config,
boolean metricsAlreadyRegistered,
SdkMeterProvider meterProvider) {
static void configureExporter(
String name, ConfigProperties config, SdkMeterProvider meterProvider) {
switch (name) {
case "otlp":
case "otlp_metrics":
if (metricsAlreadyRegistered) {
throw new ConfigurationException(
"Multiple metrics exporters configured. Only one metrics exporter can be "
+ "configured at a time.");
}
configureOtlpMetrics(config, meterProvider);
return true;
return;
case "prometheus":
if (metricsAlreadyRegistered) {
throw new ConfigurationException(
"Multiple metrics exporters configured. Only one metrics exporter can be "
+ "configured at a time.");
}
configurePrometheusMetrics(config, meterProvider);
return true;
return;
default:
return false;
return;
}
}

View File

@ -12,9 +12,6 @@ import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.metrics.SdkMeterProvider;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.trace.SdkTracerProvider;
import java.util.ArrayList;
import java.util.LinkedHashSet;
import java.util.Set;
/**
* Auto-configuration for the OpenTelemetry SDK. As an alternative to programmatically configuring
@ -33,21 +30,10 @@ public final class OpenTelemetrySdkAutoConfiguration {
Resource resource = configureResource(config);
Set<String> exporterNames =
new LinkedHashSet<>(config.getCommaSeparatedValues("otel.exporter"));
Set<String> unrecognizedExporters = new LinkedHashSet<>(exporterNames);
unrecognizedExporters.removeAll(SpanExporterConfiguration.RECOGNIZED_NAMES);
unrecognizedExporters.removeAll(MetricExporterConfiguration.RECOGNIZED_NAMES);
if (!unrecognizedExporters.isEmpty()) {
throw new ConfigurationException(
"Unrecognized value for otel.exporter: " + String.join(",", exporterNames));
}
configureMeterProvider(resource, exporterNames, config);
configureMeterProvider(resource, config);
SdkTracerProvider tracerProvider =
TracerProviderConfiguration.configureTracerProvider(resource, exporterNames, config);
TracerProviderConfiguration.configureTracerProvider(resource, config);
return OpenTelemetrySdk.builder()
.setTracerProvider(tracerProvider)
@ -55,16 +41,13 @@ public final class OpenTelemetrySdkAutoConfiguration {
.build();
}
private static void configureMeterProvider(
Resource resource, Set<String> exporterNames, ConfigProperties config) {
private static void configureMeterProvider(Resource resource, ConfigProperties config) {
SdkMeterProvider meterProvider =
SdkMeterProvider.builder().setResource(resource).buildAndRegisterGlobal();
boolean metricsConfigured = false;
for (String exporterName : new ArrayList<>(exporterNames)) {
metricsConfigured =
MetricExporterConfiguration.configureExporter(
exporterName, config, metricsConfigured, meterProvider);
String exporterName = config.getString("otel.metrics.exporter");
if (exporterName != null) {
MetricExporterConfiguration.configureExporter(exporterName, config, meterProvider);
}
}

View File

@ -14,15 +14,10 @@ import io.opentelemetry.exporter.zipkin.ZipkinSpanExporter;
import io.opentelemetry.exporter.zipkin.ZipkinSpanExporterBuilder;
import io.opentelemetry.sdk.trace.export.SpanExporter;
import java.time.Duration;
import java.util.Arrays;
import java.util.List;
import javax.annotation.Nullable;
final class SpanExporterConfiguration {
static final List<String> RECOGNIZED_NAMES =
Arrays.asList("otlp", "otlp_span", "jaeger", "zipkin", "logging");
@Nullable
static SpanExporter configureExporter(String name, ConfigProperties config) {
switch (name) {

View File

@ -16,15 +16,11 @@ import io.opentelemetry.sdk.trace.export.BatchSpanProcessorBuilder;
import io.opentelemetry.sdk.trace.export.SpanExporter;
import io.opentelemetry.sdk.trace.samplers.Sampler;
import java.time.Duration;
import java.util.ArrayList;
import java.util.List;
import java.util.ServiceLoader;
import java.util.Set;
final class TracerProviderConfiguration {
static SdkTracerProvider configureTracerProvider(
Resource resource, Set<String> exporterNames, ConfigProperties config) {
static SdkTracerProvider configureTracerProvider(Resource resource, ConfigProperties config) {
SdkTracerProviderBuilder tracerProviderBuilder =
SdkTracerProvider.builder()
.setResource(resource)
@ -37,27 +33,21 @@ final class TracerProviderConfiguration {
configurer.configure(tracerProviderBuilder);
}
List<SpanExporter> spanExporters = new ArrayList<>();
for (String name : new ArrayList<>(exporterNames)) {
SpanExporter exporter = SpanExporterConfiguration.configureExporter(name, config);
String exporterName = config.getString("otel.trace.exporter");
if (exporterName != null) {
SpanExporter exporter = SpanExporterConfiguration.configureExporter(exporterName, config);
if (exporter != null) {
spanExporters.add(exporter);
tracerProviderBuilder.addSpanProcessor(configureSpanProcessor(config, exporter));
}
}
if (!spanExporters.isEmpty()) {
tracerProviderBuilder.addSpanProcessor(configureSpanProcessor(config, spanExporters));
}
SdkTracerProvider tracerProvider = tracerProviderBuilder.build();
Runtime.getRuntime().addShutdownHook(new Thread(tracerProvider::shutdown));
return tracerProvider;
}
// VisibleForTesting
static BatchSpanProcessor configureSpanProcessor(
ConfigProperties config, List<SpanExporter> exporters) {
SpanExporter exporter = SpanExporter.composite(exporters);
static BatchSpanProcessor configureSpanProcessor(ConfigProperties config, SpanExporter exporter) {
BatchSpanProcessorBuilder builder = BatchSpanProcessor.builder(exporter);
Long scheduleDelayMillis = config.getLong("otel.bsp.schedule.delay.millis");

View File

@ -56,7 +56,7 @@ class NotOnClasspathTest {
assertThatThrownBy(
() ->
MetricExporterConfiguration.configureExporter(
"otlp", EMPTY, false, SdkMeterProvider.builder().build()))
"otlp", EMPTY, SdkMeterProvider.builder().build()))
.isInstanceOf(ConfigurationException.class)
.hasMessageContaining(
"OTLP Metrics Exporter enabled but opentelemetry-exporter-otlp-metrics not found on "
@ -68,7 +68,7 @@ class NotOnClasspathTest {
assertThatThrownBy(
() ->
MetricExporterConfiguration.configureExporter(
"prometheus", EMPTY, false, SdkMeterProvider.builder().build()))
"prometheus", EMPTY, SdkMeterProvider.builder().build()))
.isInstanceOf(ConfigurationException.class)
.hasMessageContaining(
"Prometheus Metrics Server enabled but opentelemetry-exporter-prometheus not found on "

View File

@ -47,7 +47,7 @@ class TracerProviderConfigurationTest {
// are verified in other test sets like testFullConfig.
SdkTracerProvider tracerProvider =
TracerProviderConfiguration.configureTracerProvider(
resource, Collections.emptySet(), ConfigProperties.createForTest(properties));
resource, ConfigProperties.createForTest(properties));
try {
assertThat(tracerProvider.getActiveTraceConfig().getSampler()).isEqualTo(Sampler.alwaysOff());
@ -68,8 +68,7 @@ class TracerProviderConfigurationTest {
@Test
void configureSpanProcessor_empty() {
BatchSpanProcessor processor =
TracerProviderConfiguration.configureSpanProcessor(
EMPTY, Collections.singletonList(exporter));
TracerProviderConfiguration.configureSpanProcessor(EMPTY, exporter);
try {
assertThat(processor)
@ -105,7 +104,7 @@ class TracerProviderConfigurationTest {
BatchSpanProcessor processor =
TracerProviderConfiguration.configureSpanProcessor(
ConfigProperties.createForTest(properties), Collections.singletonList(exporter));
ConfigProperties.createForTest(properties), exporter);
try {
assertThat(processor)

View File

@ -25,26 +25,6 @@ class ConfigErrorTest {
@RegisterExtension
LogCapturer logs = LogCapturer.create().captureForType(GlobalOpenTelemetry.class);
@Test
@SetSystemProperty(key = "otel.exporter", value = "otlp_metrics,prometheus")
void multipleMetricExportersPrometheusThrows() {
assertThatThrownBy(OpenTelemetrySdkAutoConfiguration::initialize)
.isInstanceOf(ConfigurationException.class)
.hasMessage(
"Multiple metrics exporters configured. "
+ "Only one metrics exporter can be configured at a time.");
}
@Test
@SetSystemProperty(key = "otel.exporter", value = "prometheus,otlp_metrics")
void multipleMetricExportersOtlpThrows() {
assertThatThrownBy(OpenTelemetrySdkAutoConfiguration::initialize)
.isInstanceOf(ConfigurationException.class)
.hasMessage(
"Multiple metrics exporters configured. "
+ "Only one metrics exporter can be configured at a time.");
}
@Test
@SetSystemProperty(key = "otel.propagators", value = "cat")
void invalidPropagator() {
@ -53,16 +33,6 @@ class ConfigErrorTest {
.hasMessage("Unrecognized value for otel.propagators: cat");
}
@Test
@SetSystemProperty(key = "otel.trace.sampler", value = "traceidratio")
void missingTraceIdRatio() {
assertThatThrownBy(OpenTelemetrySdkAutoConfiguration::initialize)
.isInstanceOf(ConfigurationException.class)
.hasMessage(
"otel.trace.sampler=traceidratio but otel.trace.sampler.arg is not provided. "
+ "Set otel.trace.sampler.arg to a value in the range [0.0, 1.0].");
}
@Test
@SetSystemProperty(key = "otel.trace.sampler", value = "traceidratio")
@SetSystemProperty(key = "otel.trace.sampler.arg", value = "bar")
@ -72,16 +42,6 @@ class ConfigErrorTest {
.hasMessage("Invalid value for property otel.trace.sampler.arg=bar. Must be a double.");
}
@Test
@SetSystemProperty(key = "otel.trace.sampler", value = "parentbased_traceidratio")
void missingTraceIdRatioWithParent() {
assertThatThrownBy(OpenTelemetrySdkAutoConfiguration::initialize)
.isInstanceOf(ConfigurationException.class)
.hasMessage(
"otel.trace.sampler=parentbased_traceidratio but otel.trace.sampler.arg is "
+ "not provided. Set otel.trace.sampler.arg to a value in the range [0.0, 1.0].");
}
@Test
@SetSystemProperty(key = "otel.trace.sampler", value = "parentbased_traceidratio")
@SetSystemProperty(key = "otel.trace.sampler.arg", value = "bar")
@ -100,15 +60,8 @@ class ConfigErrorTest {
}
@Test
@SetSystemProperty(key = "otel.exporter", value = "otlp,cat,dog")
void invalidExporter() {
assertThatThrownBy(OpenTelemetrySdkAutoConfiguration::initialize)
.isInstanceOf(ConfigurationException.class)
.hasMessage("Unrecognized value for otel.exporter: cat,dog");
}
@Test
@SetSystemProperty(key = "otel.exporter", value = "bar")
@SetSystemProperty(key = "otel.trace.sampler", value = "traceidratio")
@SetSystemProperty(key = "otel.trace.sampler.arg", value = "bar")
void globalOpenTelemetryWhenError() {
assertThat(GlobalOpenTelemetry.get())
.isInstanceOf(OpenTelemetrySdk.class)
@ -121,8 +74,6 @@ class ConfigErrorTest {
"Error automatically configuring OpenTelemetry SDK. "
+ "OpenTelemetry will not be enabled.");
assertThat(log.getLevel()).isEqualTo(Level.ERROR);
assertThat(log.getThrowable())
.isInstanceOf(ConfigurationException.class)
.hasMessage("Unrecognized value for otel.exporter: bar");
assertThat(log.getThrowable()).isInstanceOf(ConfigurationException.class);
}
}

View File

@ -8,8 +8,6 @@ package io.opentelemetry.sdk.autoconfigure;
import static org.assertj.core.api.Assertions.assertThat;
import static org.awaitility.Awaitility.await;
import com.linecorp.armeria.common.HttpResponse;
import com.linecorp.armeria.common.HttpStatus;
import com.linecorp.armeria.common.RequestHeaders;
import com.linecorp.armeria.server.ServerBuilder;
import com.linecorp.armeria.server.ServiceRequestContext;
@ -19,8 +17,6 @@ import io.grpc.stub.StreamObserver;
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.baggage.propagation.W3CBaggagePropagator;
import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator;
import io.opentelemetry.exporter.jaeger.proto.api_v2.Collector;
import io.opentelemetry.exporter.jaeger.proto.api_v2.CollectorServiceGrpc;
import io.opentelemetry.extension.trace.propagation.AwsXrayPropagator;
import io.opentelemetry.extension.trace.propagation.B3Propagator;
import io.opentelemetry.extension.trace.propagation.JaegerPropagator;
@ -45,13 +41,10 @@ import org.junit.jupiter.api.extension.RegisterExtension;
@SuppressWarnings("InterruptedExceptionSwallowed")
class FullConfigTest {
private static final BlockingQueue<Collector.PostSpansRequest> jaegerRequests =
new LinkedBlockingDeque<>();
private static final BlockingQueue<ExportTraceServiceRequest> otlpTraceRequests =
new LinkedBlockingDeque<>();
private static final BlockingQueue<ExportMetricsServiceRequest> otlpMetricsRequests =
new LinkedBlockingDeque<>();
private static final BlockingQueue<String> zipkinJsonRequests = new LinkedBlockingDeque<>();
@RegisterExtension
public static final ServerExtension server =
@ -105,32 +98,8 @@ class FullConfigTest {
responseObserver.onCompleted();
}
})
// Jaeger
.addService(
new CollectorServiceGrpc.CollectorServiceImplBase() {
@Override
public void postSpans(
Collector.PostSpansRequest request,
StreamObserver<Collector.PostSpansResponse> responseObserver) {
jaegerRequests.add(request);
responseObserver.onNext(Collector.PostSpansResponse.getDefaultInstance());
responseObserver.onCompleted();
}
})
.useBlockingTaskExecutor(true)
.build());
// Zipkin
sb.service(
"/api/v2/spans",
(ctx, req) ->
HttpResponse.from(
req.aggregate()
.thenApply(
aggRes -> {
zipkinJsonRequests.add(aggRes.contentUtf8());
return HttpResponse.of(HttpStatus.OK);
})));
}
};
@ -138,8 +107,6 @@ class FullConfigTest {
void setUp() {
otlpTraceRequests.clear();
otlpMetricsRequests.clear();
jaegerRequests.clear();
zipkinJsonRequests.clear();
}
@Test
@ -177,9 +144,7 @@ class FullConfigTest {
await()
.untilAsserted(
() -> {
assertThat(jaegerRequests).hasSize(1);
assertThat(otlpTraceRequests).hasSize(1);
assertThat(zipkinJsonRequests).hasSize(1);
// Not well defined how many metric exports would have happened by now, check that
// any

View File

@ -10,6 +10,7 @@ import static org.assertj.core.api.Assertions.assertThat;
import io.opentelemetry.exporter.otlp.metrics.OtlpGrpcMetricExporter;
import io.opentelemetry.sdk.metrics.SdkMeterProvider;
import java.util.Collections;
import java.util.concurrent.TimeUnit;
import org.junit.jupiter.api.Test;
class MetricExporterConfigurationTest {
@ -25,7 +26,10 @@ class MetricExporterConfigurationTest {
assertThat(exporter)
.isInstanceOfSatisfying(
OtlpGrpcMetricExporter.class,
otlp -> assertThat(otlp).extracting("deadlineMs").isEqualTo(10L));
otlp ->
assertThat(otlp)
.extracting("timeoutNanos")
.isEqualTo(TimeUnit.MILLISECONDS.toNanos(10L)));
} finally {
exporter.shutdown();
}

View File

@ -10,6 +10,7 @@ import static org.assertj.core.api.Assertions.assertThat;
import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter;
import io.opentelemetry.sdk.trace.export.SpanExporter;
import java.util.Collections;
import java.util.concurrent.TimeUnit;
import org.junit.jupiter.api.Test;
class SpanExporterConfigurationTest {
@ -29,7 +30,10 @@ class SpanExporterConfigurationTest {
assertThat(exporter)
.isInstanceOfSatisfying(
OtlpGrpcSpanExporter.class,
otlp -> assertThat(otlp).extracting("deadlineMs").isEqualTo(10L));
otlp ->
assertThat(otlp)
.extracting("timeoutNanos")
.isEqualTo(TimeUnit.MILLISECONDS.toNanos(10L)));
} finally {
exporter.shutdown();
}

View File

@ -0,0 +1,70 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.sdk.autoconfigure;
import static org.assertj.core.api.Assertions.assertThat;
import static org.awaitility.Awaitility.await;
import com.linecorp.armeria.server.ServerBuilder;
import com.linecorp.armeria.server.grpc.GrpcService;
import com.linecorp.armeria.testing.junit5.server.ServerExtension;
import io.grpc.stub.StreamObserver;
import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.exporter.jaeger.proto.api_v2.Collector;
import io.opentelemetry.exporter.jaeger.proto.api_v2.CollectorServiceGrpc;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
class JaegerConfigTest {
private static final BlockingQueue<Collector.PostSpansRequest> jaegerRequests =
new LinkedBlockingDeque<>();
@RegisterExtension
public static final ServerExtension server =
new ServerExtension() {
@Override
protected void configure(ServerBuilder sb) {
sb.service(
GrpcService.builder()
// Jaeger
.addService(
new CollectorServiceGrpc.CollectorServiceImplBase() {
@Override
public void postSpans(
Collector.PostSpansRequest request,
StreamObserver<Collector.PostSpansResponse> responseObserver) {
jaegerRequests.add(request);
responseObserver.onNext(Collector.PostSpansResponse.getDefaultInstance());
responseObserver.onCompleted();
}
})
.useBlockingTaskExecutor(true)
.build());
}
};
@BeforeEach
void setUp() {
jaegerRequests.clear();
}
@Test
void configures() {
String endpoint = "localhost:" + server.httpPort();
System.setProperty("otel.exporter.jaeger.endpoint", endpoint);
OpenTelemetrySdkAutoConfiguration.initialize();
GlobalOpenTelemetry.get().getTracer("test").spanBuilder("test").startSpan().end();
await().untilAsserted(() -> assertThat(jaegerRequests).hasSize(1));
}
}

View File

@ -0,0 +1,62 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.sdk.autoconfigure;
import static org.assertj.core.api.Assertions.assertThat;
import static org.awaitility.Awaitility.await;
import com.linecorp.armeria.common.HttpResponse;
import com.linecorp.armeria.common.HttpStatus;
import com.linecorp.armeria.server.ServerBuilder;
import com.linecorp.armeria.testing.junit5.server.ServerExtension;
import io.opentelemetry.api.GlobalOpenTelemetry;
import java.util.concurrent.BlockingQueue;
import java.util.concurrent.LinkedBlockingDeque;
import org.junit.jupiter.api.BeforeEach;
import org.junit.jupiter.api.Test;
import org.junit.jupiter.api.extension.RegisterExtension;
class ZipkinConfigTest {
private static final BlockingQueue<String> zipkinJsonRequests = new LinkedBlockingDeque<>();
@RegisterExtension
public static final ServerExtension server =
new ServerExtension() {
@Override
protected void configure(ServerBuilder sb) {
// Zipkin
sb.service(
"/api/v2/spans",
(ctx, req) ->
HttpResponse.from(
req.aggregate()
.thenApply(
aggRes -> {
zipkinJsonRequests.add(aggRes.contentUtf8());
return HttpResponse.of(HttpStatus.OK);
})));
}
};
@BeforeEach
void setUp() {
zipkinJsonRequests.clear();
}
@Test
void configures() {
String endpoint = "localhost:" + server.httpPort();
System.setProperty("otel.exporter.zipkin.endpoint", "http://" + endpoint + "/api/v2/spans");
OpenTelemetrySdkAutoConfiguration.initialize();
GlobalOpenTelemetry.get().getTracer("test").spanBuilder("test").startSpan().end();
await().untilAsserted(() -> assertThat(zipkinJsonRequests).hasSize(1));
}
}