Don't use global meter provider for trace export (#3901)
This commit is contained in:
parent
b9b8105da7
commit
6933de18e5
|
@ -1,2 +1,4 @@
|
|||
Comparing source compatibility of against
|
||||
No changes.
|
||||
*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder (not serializable)
|
||||
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
|
||||
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder setMeterProvider(io.opentelemetry.api.metrics.MeterProvider)
|
||||
|
|
|
@ -1,2 +1,4 @@
|
|||
Comparing source compatibility of against
|
||||
No changes.
|
||||
*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder (not serializable)
|
||||
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
|
||||
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder setMeterProvider(io.opentelemetry.api.metrics.MeterProvider)
|
||||
|
|
|
@ -1,2 +1,4 @@
|
|||
Comparing source compatibility of against
|
||||
No changes.
|
||||
*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.trace.export.BatchSpanProcessorBuilder (not serializable)
|
||||
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
|
||||
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.trace.export.BatchSpanProcessorBuilder setMeterProvider(io.opentelemetry.api.metrics.MeterProvider)
|
||||
|
|
|
@ -8,6 +8,7 @@ package io.opentelemetry.exporter.otlp.http.trace;
|
|||
import static io.opentelemetry.api.internal.Utils.checkArgument;
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
import io.opentelemetry.api.metrics.MeterProvider;
|
||||
import io.opentelemetry.exporter.otlp.internal.okhttp.OkHttpExporterBuilder;
|
||||
import io.opentelemetry.exporter.otlp.internal.traces.TraceRequestMarshaler;
|
||||
import java.time.Duration;
|
||||
|
@ -83,6 +84,16 @@ public final class OtlpHttpSpanExporterBuilder {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link MeterProvider} to use to collect metrics related to export. If not set, metrics
|
||||
* will not be collected.
|
||||
*/
|
||||
public OtlpHttpSpanExporterBuilder setMeterProvider(MeterProvider meterProvider) {
|
||||
requireNonNull(meterProvider, "meterProvider");
|
||||
delegate.setMeterProvider(meterProvider);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new instance of the exporter based on the builder's values.
|
||||
*
|
||||
|
|
|
@ -11,9 +11,9 @@ import static io.opentelemetry.api.common.AttributeKey.stringKey;
|
|||
import io.opentelemetry.api.common.AttributeKey;
|
||||
import io.opentelemetry.api.common.Attributes;
|
||||
import io.opentelemetry.api.metrics.BoundLongCounter;
|
||||
import io.opentelemetry.api.metrics.GlobalMeterProvider;
|
||||
import io.opentelemetry.api.metrics.LongCounter;
|
||||
import io.opentelemetry.api.metrics.Meter;
|
||||
import io.opentelemetry.api.metrics.MeterProvider;
|
||||
|
||||
/**
|
||||
* Helper for recording metrics from OTLP exporters.
|
||||
|
@ -61,14 +61,12 @@ public class ExporterMetrics {
|
|||
}
|
||||
|
||||
/** Create an instance for recording OTLP gRPC exporter metrics. */
|
||||
public static ExporterMetrics createGrpc(String type) {
|
||||
return new ExporterMetrics(
|
||||
GlobalMeterProvider.get().get("io.opentelemetry.exporters.otlp-grpc"), type);
|
||||
public static ExporterMetrics createGrpc(String type, MeterProvider meterProvider) {
|
||||
return new ExporterMetrics(meterProvider.get("io.opentelemetry.exporters.otlp-grpc"), type);
|
||||
}
|
||||
|
||||
/** Create an instance for recording OTLP http/protobuf exporter metrics. */
|
||||
public static ExporterMetrics createHttpProtobuf(String type) {
|
||||
return new ExporterMetrics(
|
||||
GlobalMeterProvider.get().get("io.opentelemetry.exporters.otlp-http"), type);
|
||||
public static ExporterMetrics createHttpProtobuf(String type, MeterProvider meterProvider) {
|
||||
return new ExporterMetrics(meterProvider.get("io.opentelemetry.exporters.otlp-http"), type);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -11,6 +11,7 @@ import com.google.common.util.concurrent.MoreExecutors;
|
|||
import io.grpc.Codec;
|
||||
import io.grpc.ManagedChannel;
|
||||
import io.grpc.Status;
|
||||
import io.opentelemetry.api.metrics.MeterProvider;
|
||||
import io.opentelemetry.exporter.otlp.internal.ExporterMetrics;
|
||||
import io.opentelemetry.exporter.otlp.internal.Marshaler;
|
||||
import io.opentelemetry.sdk.common.CompletableResultCode;
|
||||
|
@ -44,10 +45,11 @@ public final class DefaultGrpcExporter<T extends Marshaler> implements GrpcExpor
|
|||
String type,
|
||||
ManagedChannel channel,
|
||||
MarshalerServiceStub<T, ?, ?> stub,
|
||||
MeterProvider meterProvider,
|
||||
long timeoutNanos,
|
||||
boolean compressionEnabled) {
|
||||
this.type = type;
|
||||
this.exporterMetrics = ExporterMetrics.createGrpc(type);
|
||||
this.exporterMetrics = ExporterMetrics.createGrpc(type, meterProvider);
|
||||
this.managedChannel = channel;
|
||||
this.timeoutNanos = timeoutNanos;
|
||||
Codec codec = compressionEnabled ? new Codec.Gzip() : Codec.Identity.NONE;
|
||||
|
|
|
@ -13,6 +13,7 @@ import io.grpc.ManagedChannel;
|
|||
import io.grpc.ManagedChannelBuilder;
|
||||
import io.grpc.Metadata;
|
||||
import io.grpc.stub.MetadataUtils;
|
||||
import io.opentelemetry.api.metrics.MeterProvider;
|
||||
import io.opentelemetry.exporter.otlp.internal.Marshaler;
|
||||
import io.opentelemetry.exporter.otlp.internal.RetryPolicy;
|
||||
import java.lang.reflect.Field;
|
||||
|
@ -44,6 +45,7 @@ public final class DefaultGrpcExporterBuilder<T extends Marshaler>
|
|||
@Nullable private Metadata metadata;
|
||||
@Nullable private byte[] trustedCertificatesPem;
|
||||
@Nullable private RetryPolicy retryPolicy;
|
||||
private MeterProvider meterProvider = MeterProvider.noop();
|
||||
|
||||
/** Creates a new {@link DefaultGrpcExporterBuilder}. */
|
||||
// Visible for testing
|
||||
|
@ -123,6 +125,12 @@ public final class DefaultGrpcExporterBuilder<T extends Marshaler>
|
|||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GrpcExporterBuilder<T> setMeterProvider(MeterProvider meterProvider) {
|
||||
this.meterProvider = meterProvider;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GrpcExporter<T> build() {
|
||||
ManagedChannel channel = this.channel;
|
||||
|
@ -162,7 +170,8 @@ public final class DefaultGrpcExporterBuilder<T extends Marshaler>
|
|||
Codec codec = compressionEnabled ? new Codec.Gzip() : Codec.Identity.NONE;
|
||||
MarshalerServiceStub<T, ?, ?> stub =
|
||||
stubFactory.apply(channel).withCompression(codec.getMessageEncoding());
|
||||
return new DefaultGrpcExporter<>(type, channel, stub, timeoutNanos, compressionEnabled);
|
||||
return new DefaultGrpcExporter<>(
|
||||
type, channel, stub, meterProvider, timeoutNanos, compressionEnabled);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
package io.opentelemetry.exporter.otlp.internal.grpc;
|
||||
|
||||
import io.grpc.ManagedChannel;
|
||||
import io.opentelemetry.api.metrics.MeterProvider;
|
||||
import io.opentelemetry.exporter.otlp.internal.Marshaler;
|
||||
import io.opentelemetry.exporter.otlp.internal.RetryPolicy;
|
||||
import java.time.Duration;
|
||||
|
@ -29,5 +30,7 @@ public interface GrpcExporterBuilder<T extends Marshaler> {
|
|||
|
||||
GrpcExporterBuilder<T> addRetryPolicy(RetryPolicy retryPolicy);
|
||||
|
||||
GrpcExporterBuilder<T> setMeterProvider(MeterProvider meterProvider);
|
||||
|
||||
GrpcExporter<T> build();
|
||||
}
|
||||
|
|
|
@ -25,9 +25,9 @@ package io.opentelemetry.exporter.otlp.internal.grpc;
|
|||
|
||||
import io.opentelemetry.api.common.Attributes;
|
||||
import io.opentelemetry.api.metrics.BoundLongCounter;
|
||||
import io.opentelemetry.api.metrics.GlobalMeterProvider;
|
||||
import io.opentelemetry.api.metrics.LongCounter;
|
||||
import io.opentelemetry.api.metrics.Meter;
|
||||
import io.opentelemetry.api.metrics.MeterProvider;
|
||||
import io.opentelemetry.exporter.otlp.internal.Marshaler;
|
||||
import io.opentelemetry.sdk.common.CompletableResultCode;
|
||||
import io.opentelemetry.sdk.internal.ThrottlingLogger;
|
||||
|
@ -76,6 +76,7 @@ public final class OkHttpGrpcExporter<T extends Marshaler> implements GrpcExport
|
|||
OkHttpGrpcExporter(
|
||||
String type,
|
||||
OkHttpClient client,
|
||||
MeterProvider meterProvider,
|
||||
String endpoint,
|
||||
Headers headers,
|
||||
boolean compressionEnabled) {
|
||||
|
@ -85,7 +86,7 @@ public final class OkHttpGrpcExporter<T extends Marshaler> implements GrpcExport
|
|||
this.headers = headers;
|
||||
this.compressionEnabled = compressionEnabled;
|
||||
|
||||
Meter meter = GlobalMeterProvider.get().get("io.opentelemetry.exporters.otlp-grpc-okhttp");
|
||||
Meter meter = meterProvider.get("io.opentelemetry.exporters.otlp-grpc-okhttp");
|
||||
Attributes attributes = Attributes.builder().put("type", type).build();
|
||||
seen = meter.counterBuilder("otlp.exporter.seen").build().bind(attributes);
|
||||
LongCounter exported = meter.counterBuilder("otlp.exported.exported").build();
|
||||
|
|
|
@ -6,6 +6,7 @@
|
|||
package io.opentelemetry.exporter.otlp.internal.grpc;
|
||||
|
||||
import io.grpc.ManagedChannel;
|
||||
import io.opentelemetry.api.metrics.MeterProvider;
|
||||
import io.opentelemetry.exporter.otlp.internal.Marshaler;
|
||||
import io.opentelemetry.exporter.otlp.internal.RetryPolicy;
|
||||
import io.opentelemetry.exporter.otlp.internal.TlsUtil;
|
||||
|
@ -39,6 +40,7 @@ public final class OkHttpGrpcExporterBuilder<T extends Marshaler>
|
|||
private boolean compressionEnabled = false;
|
||||
private final Headers.Builder headers = new Headers.Builder();
|
||||
@Nullable private byte[] trustedCertificatesPem;
|
||||
private MeterProvider meterProvider = MeterProvider.noop();
|
||||
|
||||
/** Creates a new {@link OkHttpGrpcExporterBuilder}. */
|
||||
// Visible for testing
|
||||
|
@ -108,6 +110,12 @@ public final class OkHttpGrpcExporterBuilder<T extends Marshaler>
|
|||
throw new UnsupportedOperationException("Only available on DefaultGrpcExporter");
|
||||
}
|
||||
|
||||
@Override
|
||||
public GrpcExporterBuilder<T> setMeterProvider(MeterProvider meterProvider) {
|
||||
this.meterProvider = meterProvider;
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public GrpcExporter<T> build() {
|
||||
OkHttpClient.Builder clientBuilder = new OkHttpClient.Builder();
|
||||
|
@ -139,6 +147,6 @@ public final class OkHttpGrpcExporterBuilder<T extends Marshaler>
|
|||
}
|
||||
|
||||
return new OkHttpGrpcExporter<>(
|
||||
type, clientBuilder.build(), endpoint, headers.build(), compressionEnabled);
|
||||
type, clientBuilder.build(), meterProvider, endpoint, headers.build(), compressionEnabled);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
package io.opentelemetry.exporter.otlp.internal.okhttp;
|
||||
|
||||
import io.opentelemetry.api.metrics.MeterProvider;
|
||||
import io.opentelemetry.exporter.otlp.internal.ExporterMetrics;
|
||||
import io.opentelemetry.exporter.otlp.internal.Marshaler;
|
||||
import io.opentelemetry.exporter.otlp.internal.grpc.GrpcStatusUtil;
|
||||
|
@ -46,6 +47,7 @@ public final class OkHttpExporter<T extends Marshaler> {
|
|||
OkHttpExporter(
|
||||
String type,
|
||||
OkHttpClient client,
|
||||
MeterProvider meterProvider,
|
||||
String endpoint,
|
||||
@Nullable Headers headers,
|
||||
boolean compressionEnabled) {
|
||||
|
@ -55,7 +57,7 @@ public final class OkHttpExporter<T extends Marshaler> {
|
|||
this.headers = headers;
|
||||
this.compressionEnabled = compressionEnabled;
|
||||
|
||||
this.exporterMetrics = ExporterMetrics.createHttpProtobuf(type);
|
||||
this.exporterMetrics = ExporterMetrics.createHttpProtobuf(type, meterProvider);
|
||||
}
|
||||
|
||||
public CompletableResultCode export(T exportRequest, int numItems) {
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
package io.opentelemetry.exporter.otlp.internal.okhttp;
|
||||
|
||||
import io.opentelemetry.api.metrics.MeterProvider;
|
||||
import io.opentelemetry.exporter.otlp.internal.Marshaler;
|
||||
import io.opentelemetry.exporter.otlp.internal.TlsUtil;
|
||||
import java.net.URI;
|
||||
|
@ -30,6 +31,7 @@ public final class OkHttpExporterBuilder<T extends Marshaler> {
|
|||
private boolean compressionEnabled = false;
|
||||
@Nullable private Headers.Builder headersBuilder;
|
||||
@Nullable private byte[] trustedCertificatesPem;
|
||||
private MeterProvider meterProvider = MeterProvider.noop();
|
||||
|
||||
public OkHttpExporterBuilder(String type, String defaultEndpoint) {
|
||||
this.type = type;
|
||||
|
@ -84,6 +86,11 @@ public final class OkHttpExporterBuilder<T extends Marshaler> {
|
|||
return this;
|
||||
}
|
||||
|
||||
public OkHttpExporterBuilder<T> setMeterProvider(MeterProvider meterProvider) {
|
||||
this.meterProvider = meterProvider;
|
||||
return this;
|
||||
}
|
||||
|
||||
public OkHttpExporter<T> build() {
|
||||
OkHttpClient.Builder clientBuilder =
|
||||
new OkHttpClient.Builder().callTimeout(Duration.ofNanos(timeoutNanos));
|
||||
|
@ -101,6 +108,7 @@ public final class OkHttpExporterBuilder<T extends Marshaler> {
|
|||
|
||||
Headers headers = headersBuilder == null ? null : headersBuilder.build();
|
||||
|
||||
return new OkHttpExporter<>(type, clientBuilder.build(), endpoint, headers, compressionEnabled);
|
||||
return new OkHttpExporter<>(
|
||||
type, clientBuilder.build(), meterProvider, endpoint, headers, compressionEnabled);
|
||||
}
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import static io.opentelemetry.api.internal.Utils.checkArgument;
|
|||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
import io.grpc.ManagedChannel;
|
||||
import io.opentelemetry.api.metrics.MeterProvider;
|
||||
import io.opentelemetry.exporter.otlp.internal.grpc.GrpcExporter;
|
||||
import io.opentelemetry.exporter.otlp.internal.grpc.GrpcExporterBuilder;
|
||||
import io.opentelemetry.exporter.otlp.internal.traces.TraceRequestMarshaler;
|
||||
|
@ -121,6 +122,16 @@ public final class OtlpGrpcSpanExporterBuilder {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link MeterProvider} to use to collect metrics related to export. If not set, metrics
|
||||
* will not be collected.
|
||||
*/
|
||||
public OtlpGrpcSpanExporterBuilder setMeterProvider(MeterProvider meterProvider) {
|
||||
requireNonNull(meterProvider, "meterProvider");
|
||||
delegate.setMeterProvider(meterProvider);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructs a new instance of the exporter based on the builder's values.
|
||||
*
|
||||
|
|
|
@ -98,11 +98,16 @@ public final class OpenTelemetrySdkAutoConfiguration {
|
|||
PropagatorConfiguration.configurePropagators(
|
||||
config, serviceClassLoader, propagatorCustomizer);
|
||||
|
||||
configureMeterProvider(resource, config, serviceClassLoader);
|
||||
MeterProvider meterProvider = configureMeterProvider(resource, config, serviceClassLoader);
|
||||
|
||||
SdkTracerProvider tracerProvider =
|
||||
TracerProviderConfiguration.configureTracerProvider(
|
||||
resource, config, serviceClassLoader, spanExporterCustomizer, samplerCustomizer);
|
||||
resource,
|
||||
config,
|
||||
serviceClassLoader,
|
||||
meterProvider,
|
||||
spanExporterCustomizer,
|
||||
samplerCustomizer);
|
||||
|
||||
OpenTelemetrySdk openTelemetrySdk =
|
||||
OpenTelemetrySdk.builder()
|
||||
|
@ -115,7 +120,7 @@ public final class OpenTelemetrySdkAutoConfiguration {
|
|||
return openTelemetrySdk;
|
||||
}
|
||||
|
||||
private static void configureMeterProvider(
|
||||
private static MeterProvider configureMeterProvider(
|
||||
Resource resource, ConfigProperties config, ClassLoader serviceClassLoader) {
|
||||
SdkMeterProviderBuilder meterProviderBuilder = SdkMeterProvider.builder().setResource(resource);
|
||||
|
||||
|
@ -146,7 +151,7 @@ public final class OpenTelemetrySdkAutoConfiguration {
|
|||
if (exporterName == null || exporterName.equals("none")) {
|
||||
// In the event no exporters are configured set a noop exporter
|
||||
GlobalMeterProvider.set(MeterProvider.noop());
|
||||
return;
|
||||
return MeterProvider.noop();
|
||||
}
|
||||
MetricExporterConfiguration.configureExporter(
|
||||
exporterName, config, serviceClassLoader, meterProviderBuilder);
|
||||
|
@ -155,6 +160,8 @@ public final class OpenTelemetrySdkAutoConfiguration {
|
|||
|
||||
// Make sure metrics shut down when JVM shuts down.
|
||||
Runtime.getRuntime().addShutdownHook(new Thread(meterProvider::close));
|
||||
|
||||
return meterProvider;
|
||||
}
|
||||
|
||||
private OpenTelemetrySdkAutoConfiguration() {}
|
||||
|
|
|
@ -13,6 +13,7 @@ import static java.util.stream.Collectors.groupingBy;
|
|||
import static java.util.stream.Collectors.joining;
|
||||
import static java.util.stream.Collectors.toMap;
|
||||
|
||||
import io.opentelemetry.api.metrics.MeterProvider;
|
||||
import io.opentelemetry.exporter.jaeger.JaegerGrpcSpanExporter;
|
||||
import io.opentelemetry.exporter.jaeger.JaegerGrpcSpanExporterBuilder;
|
||||
import io.opentelemetry.exporter.logging.LoggingSpanExporter;
|
||||
|
@ -44,6 +45,7 @@ final class SpanExporterConfiguration {
|
|||
static Map<String, SpanExporter> configureSpanExporters(
|
||||
ConfigProperties config,
|
||||
ClassLoader serviceClassLoader,
|
||||
MeterProvider meterProvider,
|
||||
BiFunction<? super SpanExporter, ConfigProperties, ? extends SpanExporter>
|
||||
spanExporterCustomizer) {
|
||||
List<String> exporterNamesList = config.getList("otel.traces.exporter");
|
||||
|
@ -91,15 +93,19 @@ final class SpanExporterConfiguration {
|
|||
Function.identity(),
|
||||
exporterName ->
|
||||
spanExporterCustomizer.apply(
|
||||
configureExporter(exporterName, config, spiExporters), config)));
|
||||
configureExporter(exporterName, config, spiExporters, meterProvider),
|
||||
config)));
|
||||
}
|
||||
|
||||
// Visible for testing
|
||||
static SpanExporter configureExporter(
|
||||
String name, ConfigProperties config, Map<String, SpanExporter> spiExporters) {
|
||||
String name,
|
||||
ConfigProperties config,
|
||||
Map<String, SpanExporter> spiExporters,
|
||||
MeterProvider meterProvider) {
|
||||
switch (name) {
|
||||
case "otlp":
|
||||
return configureOtlp(config);
|
||||
return configureOtlp(config, meterProvider);
|
||||
case "jaeger":
|
||||
return configureJaeger(config);
|
||||
case "zipkin":
|
||||
|
@ -120,7 +126,7 @@ final class SpanExporterConfiguration {
|
|||
}
|
||||
|
||||
// Visible for testing
|
||||
static SpanExporter configureOtlp(ConfigProperties config) {
|
||||
static SpanExporter configureOtlp(ConfigProperties config, MeterProvider meterProvider) {
|
||||
String protocol = OtlpConfigUtil.getOtlpProtocol(DATA_TYPE_TRACES, config);
|
||||
|
||||
if (protocol.equals(PROTOCOL_HTTP_PROTOBUF)) {
|
||||
|
@ -140,6 +146,8 @@ final class SpanExporterConfiguration {
|
|||
builder::setTrustedCertificates,
|
||||
unused -> {});
|
||||
|
||||
builder.setMeterProvider(meterProvider);
|
||||
|
||||
return builder.build();
|
||||
} else if (protocol.equals(PROTOCOL_GRPC)) {
|
||||
ClasspathUtil.checkClassExists(
|
||||
|
@ -160,6 +168,9 @@ final class SpanExporterConfiguration {
|
|||
DefaultGrpcExporterBuilder.getDelegateBuilder(
|
||||
OtlpGrpcSpanExporterBuilder.class, builder)
|
||||
.addRetryPolicy(retryPolicy));
|
||||
|
||||
builder.setMeterProvider(meterProvider);
|
||||
|
||||
return builder.build();
|
||||
} else {
|
||||
throw new ConfigurationException("Unsupported OTLP traces protocol: " + protocol);
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
package io.opentelemetry.sdk.autoconfigure;
|
||||
|
||||
import io.opentelemetry.api.metrics.MeterProvider;
|
||||
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
|
||||
import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException;
|
||||
import io.opentelemetry.sdk.autoconfigure.spi.traces.ConfigurableSamplerProvider;
|
||||
|
@ -35,6 +36,7 @@ final class TracerProviderConfiguration {
|
|||
Resource resource,
|
||||
ConfigProperties config,
|
||||
ClassLoader serviceClassLoader,
|
||||
MeterProvider meterProvider,
|
||||
BiFunction<? super SpanExporter, ConfigProperties, ? extends SpanExporter>
|
||||
spanExporterCustomizer,
|
||||
BiFunction<? super Sampler, ConfigProperties, ? extends Sampler> samplerCustomizer) {
|
||||
|
@ -59,7 +61,7 @@ final class TracerProviderConfiguration {
|
|||
|
||||
Map<String, SpanExporter> exportersByName =
|
||||
SpanExporterConfiguration.configureSpanExporters(
|
||||
config, serviceClassLoader, spanExporterCustomizer);
|
||||
config, serviceClassLoader, meterProvider, spanExporterCustomizer);
|
||||
|
||||
configureSpanProcessors(config, exportersByName)
|
||||
.forEach(tracerProviderBuilder::addSpanProcessor);
|
||||
|
|
|
@ -8,6 +8,7 @@ package io.opentelemetry.sdk.autoconfigure;
|
|||
import static org.assertj.core.api.Assertions.assertThatCode;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
|
||||
import io.opentelemetry.api.metrics.MeterProvider;
|
||||
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
|
||||
import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException;
|
||||
import io.opentelemetry.sdk.metrics.SdkMeterProvider;
|
||||
|
@ -23,7 +24,8 @@ class NotOnClasspathTest {
|
|||
void otlpGrpcSpans() {
|
||||
assertThatThrownBy(
|
||||
() ->
|
||||
SpanExporterConfiguration.configureExporter("otlp", EMPTY, Collections.emptyMap()))
|
||||
SpanExporterConfiguration.configureExporter(
|
||||
"otlp", EMPTY, Collections.emptyMap(), MeterProvider.noop()))
|
||||
.isInstanceOf(ConfigurationException.class)
|
||||
.hasMessageContaining(
|
||||
"OTLP gRPC Trace Exporter enabled but opentelemetry-exporter-otlp not found on "
|
||||
|
@ -37,7 +39,8 @@ class NotOnClasspathTest {
|
|||
Collections.singletonMap("otel.exporter.otlp.protocol", "http/protobuf"));
|
||||
assertThatThrownBy(
|
||||
() ->
|
||||
SpanExporterConfiguration.configureExporter("otlp", config, Collections.emptyMap()))
|
||||
SpanExporterConfiguration.configureExporter(
|
||||
"otlp", config, Collections.emptyMap(), MeterProvider.noop()))
|
||||
.isInstanceOf(ConfigurationException.class)
|
||||
.hasMessageContaining(
|
||||
"OTLP HTTP Trace Exporter enabled but opentelemetry-exporter-otlp-http-trace not found on "
|
||||
|
@ -49,7 +52,7 @@ class NotOnClasspathTest {
|
|||
assertThatThrownBy(
|
||||
() ->
|
||||
SpanExporterConfiguration.configureExporter(
|
||||
"jaeger", EMPTY, Collections.emptyMap()))
|
||||
"jaeger", EMPTY, Collections.emptyMap(), MeterProvider.noop()))
|
||||
.isInstanceOf(ConfigurationException.class)
|
||||
.hasMessageContaining(
|
||||
"Jaeger gRPC Exporter enabled but opentelemetry-exporter-jaeger not found on "
|
||||
|
@ -61,7 +64,7 @@ class NotOnClasspathTest {
|
|||
assertThatThrownBy(
|
||||
() ->
|
||||
SpanExporterConfiguration.configureExporter(
|
||||
"zipkin", EMPTY, Collections.emptyMap()))
|
||||
"zipkin", EMPTY, Collections.emptyMap(), MeterProvider.noop()))
|
||||
.isInstanceOf(ConfigurationException.class)
|
||||
.hasMessageContaining(
|
||||
"Zipkin Exporter enabled but opentelemetry-exporter-zipkin not found on classpath");
|
||||
|
@ -72,7 +75,7 @@ class NotOnClasspathTest {
|
|||
assertThatThrownBy(
|
||||
() ->
|
||||
SpanExporterConfiguration.configureExporter(
|
||||
"logging", EMPTY, Collections.emptyMap()))
|
||||
"logging", EMPTY, Collections.emptyMap(), MeterProvider.noop()))
|
||||
.isInstanceOf(ConfigurationException.class)
|
||||
.hasMessageContaining(
|
||||
"Logging Trace Exporter enabled but opentelemetry-exporter-logging not found on "
|
||||
|
|
|
@ -10,6 +10,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
|||
import static org.mockito.Mockito.when;
|
||||
|
||||
import io.opentelemetry.api.common.Attributes;
|
||||
import io.opentelemetry.api.metrics.MeterProvider;
|
||||
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
|
||||
import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException;
|
||||
import io.opentelemetry.sdk.common.CompletableResultCode;
|
||||
|
@ -65,6 +66,7 @@ class TracerProviderConfigurationTest {
|
|||
resource,
|
||||
DefaultConfigProperties.createForTest(properties),
|
||||
TracerProviderConfiguration.class.getClassLoader(),
|
||||
MeterProvider.noop(),
|
||||
(a, unused) -> a,
|
||||
(a, unused) -> a);
|
||||
try {
|
||||
|
|
|
@ -9,6 +9,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import io.opentelemetry.api.metrics.MeterProvider;
|
||||
import io.opentelemetry.exporter.logging.LoggingSpanExporter;
|
||||
import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter;
|
||||
import io.opentelemetry.exporter.zipkin.ZipkinSpanExporter;
|
||||
|
@ -33,7 +34,10 @@ public class ConfigurableSpanExporterTest {
|
|||
ImmutableMap.of("test.option", "true", "otel.traces.exporter", "testExporter"));
|
||||
Map<String, SpanExporter> exportersByName =
|
||||
SpanExporterConfiguration.configureSpanExporters(
|
||||
config, SpanExporterConfiguration.class.getClassLoader(), (a, unused) -> a);
|
||||
config,
|
||||
SpanExporterConfiguration.class.getClassLoader(),
|
||||
MeterProvider.noop(),
|
||||
(a, unused) -> a);
|
||||
|
||||
assertThat(exportersByName)
|
||||
.hasSize(1)
|
||||
|
@ -52,7 +56,10 @@ public class ConfigurableSpanExporterTest {
|
|||
assertThatThrownBy(
|
||||
() ->
|
||||
SpanExporterConfiguration.configureSpanExporters(
|
||||
config, new URLClassLoader(new URL[0], null), (a, unused) -> a))
|
||||
config,
|
||||
new URLClassLoader(new URL[0], null),
|
||||
MeterProvider.noop(),
|
||||
(a, unused) -> a))
|
||||
.isInstanceOf(ConfigurationException.class)
|
||||
.hasMessageContaining("testExporter");
|
||||
}
|
||||
|
@ -66,7 +73,10 @@ public class ConfigurableSpanExporterTest {
|
|||
assertThatThrownBy(
|
||||
() ->
|
||||
SpanExporterConfiguration.configureSpanExporters(
|
||||
config, SpanExporterConfiguration.class.getClassLoader(), (a, unused) -> a))
|
||||
config,
|
||||
SpanExporterConfiguration.class.getClassLoader(),
|
||||
MeterProvider.noop(),
|
||||
(a, unused) -> a))
|
||||
.isInstanceOf(ConfigurationException.class)
|
||||
.hasMessageContaining("otel.traces.exporter contains duplicates: [otlp]");
|
||||
}
|
||||
|
@ -79,7 +89,10 @@ public class ConfigurableSpanExporterTest {
|
|||
assertThatThrownBy(
|
||||
() ->
|
||||
SpanExporterConfiguration.configureSpanExporters(
|
||||
config, SpanExporterConfiguration.class.getClassLoader(), (a, unused) -> a))
|
||||
config,
|
||||
SpanExporterConfiguration.class.getClassLoader(),
|
||||
MeterProvider.noop(),
|
||||
(a, unused) -> a))
|
||||
.isInstanceOf(ConfigurationException.class)
|
||||
.hasMessageContaining("otel.traces.exporter contains none along with other exporters");
|
||||
}
|
||||
|
@ -91,7 +104,8 @@ public class ConfigurableSpanExporterTest {
|
|||
SpanExporterConfiguration.configureExporter(
|
||||
"catExporter",
|
||||
DefaultConfigProperties.createForTest(Collections.emptyMap()),
|
||||
Collections.emptyMap()))
|
||||
Collections.emptyMap(),
|
||||
MeterProvider.noop()))
|
||||
.isInstanceOf(ConfigurationException.class)
|
||||
.hasMessageContaining("catExporter");
|
||||
}
|
||||
|
|
|
@ -9,6 +9,7 @@ import static org.assertj.core.api.Assertions.assertThat;
|
|||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
|
||||
import com.google.common.collect.ImmutableMap;
|
||||
import io.opentelemetry.api.metrics.MeterProvider;
|
||||
import io.opentelemetry.exporter.jaeger.JaegerGrpcSpanExporter;
|
||||
import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter;
|
||||
import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException;
|
||||
|
@ -25,7 +26,8 @@ class SpanExporterConfigurationTest {
|
|||
() ->
|
||||
SpanExporterConfiguration.configureOtlp(
|
||||
DefaultConfigProperties.createForTest(
|
||||
ImmutableMap.of("otel.exporter.otlp.protocol", "foo"))))
|
||||
ImmutableMap.of("otel.exporter.otlp.protocol", "foo")),
|
||||
MeterProvider.noop()))
|
||||
.isInstanceOf(ConfigurationException.class)
|
||||
.hasMessageContaining("Unsupported OTLP traces protocol: foo");
|
||||
}
|
||||
|
@ -38,7 +40,8 @@ class SpanExporterConfigurationTest {
|
|||
"otlp",
|
||||
DefaultConfigProperties.createForTest(
|
||||
Collections.singletonMap("otel.exporter.otlp.timeout", "10")),
|
||||
Collections.emptyMap());
|
||||
Collections.emptyMap(),
|
||||
MeterProvider.noop());
|
||||
try {
|
||||
assertThat(exporter)
|
||||
.isInstanceOfSatisfying(
|
||||
|
@ -60,7 +63,8 @@ class SpanExporterConfigurationTest {
|
|||
"jaeger",
|
||||
DefaultConfigProperties.createForTest(
|
||||
Collections.singletonMap("otel.exporter.jaeger.timeout", "10")),
|
||||
Collections.emptyMap());
|
||||
Collections.emptyMap(),
|
||||
MeterProvider.noop());
|
||||
try {
|
||||
assertThat(exporter)
|
||||
.isInstanceOfSatisfying(
|
||||
|
@ -82,7 +86,8 @@ class SpanExporterConfigurationTest {
|
|||
"zipkin",
|
||||
DefaultConfigProperties.createForTest(
|
||||
Collections.singletonMap("otel.exporter.zipkin.timeout", "5s")),
|
||||
Collections.emptyMap());
|
||||
Collections.emptyMap(),
|
||||
MeterProvider.noop());
|
||||
try {
|
||||
assertThat(exporter).isNotNull();
|
||||
} finally {
|
||||
|
|
|
@ -15,6 +15,7 @@ import com.google.common.collect.Lists;
|
|||
import com.linecorp.armeria.testing.junit5.server.SelfSignedCertificateExtension;
|
||||
import io.opentelemetry.api.GlobalOpenTelemetry;
|
||||
import io.opentelemetry.api.common.Attributes;
|
||||
import io.opentelemetry.api.metrics.MeterProvider;
|
||||
import io.opentelemetry.api.trace.SpanKind;
|
||||
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
|
||||
import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException;
|
||||
|
@ -104,7 +105,8 @@ class OtlpGrpcConfigTest {
|
|||
props.put("otel.exporter.otlp.timeout", "15s");
|
||||
ConfigProperties properties = DefaultConfigProperties.createForTest(props);
|
||||
SpanExporter spanExporter =
|
||||
SpanExporterConfiguration.configureExporter("otlp", properties, Collections.emptyMap());
|
||||
SpanExporterConfiguration.configureExporter(
|
||||
"otlp", properties, Collections.emptyMap(), MeterProvider.noop());
|
||||
MetricExporter metricExporter =
|
||||
MetricExporterConfiguration.configureOtlpMetrics(properties, SdkMeterProvider.builder());
|
||||
|
||||
|
@ -153,7 +155,10 @@ class OtlpGrpcConfigTest {
|
|||
props.put("otel.exporter.otlp.traces.timeout", "15s");
|
||||
SpanExporter spanExporter =
|
||||
SpanExporterConfiguration.configureExporter(
|
||||
"otlp", DefaultConfigProperties.createForTest(props), Collections.emptyMap());
|
||||
"otlp",
|
||||
DefaultConfigProperties.createForTest(props),
|
||||
Collections.emptyMap(),
|
||||
MeterProvider.noop());
|
||||
|
||||
assertThat(spanExporter)
|
||||
.extracting("delegate.timeoutNanos")
|
||||
|
@ -213,7 +218,7 @@ class OtlpGrpcConfigTest {
|
|||
assertThatThrownBy(
|
||||
() ->
|
||||
SpanExporterConfiguration.configureExporter(
|
||||
"otlp", properties, Collections.emptyMap()))
|
||||
"otlp", properties, Collections.emptyMap(), MeterProvider.noop()))
|
||||
.isInstanceOf(ConfigurationException.class)
|
||||
.hasMessageContaining("Invalid OTLP certificate path:");
|
||||
|
||||
|
|
|
@ -14,6 +14,7 @@ import com.google.common.collect.Lists;
|
|||
import com.linecorp.armeria.testing.junit5.server.SelfSignedCertificateExtension;
|
||||
import io.grpc.Status;
|
||||
import io.opentelemetry.api.common.Attributes;
|
||||
import io.opentelemetry.api.metrics.MeterProvider;
|
||||
import io.opentelemetry.api.trace.SpanKind;
|
||||
import io.opentelemetry.exporter.otlp.internal.RetryPolicy;
|
||||
import io.opentelemetry.sdk.common.CompletableResultCode;
|
||||
|
@ -90,7 +91,10 @@ class OtlpGrpcRetryTest {
|
|||
props.put("otel.experimental.exporter.otlp.retry.enabled", "true");
|
||||
SpanExporter spanExporter =
|
||||
SpanExporterConfiguration.configureExporter(
|
||||
"otlp", DefaultConfigProperties.createForTest(props), Collections.emptyMap());
|
||||
"otlp",
|
||||
DefaultConfigProperties.createForTest(props),
|
||||
Collections.emptyMap(),
|
||||
MeterProvider.noop());
|
||||
|
||||
testRetryableStatusCodes(() -> SPAN_DATA, spanExporter::export, server.traceRequests::size);
|
||||
testDefaultRetryPolicy(() -> SPAN_DATA, spanExporter::export, server.traceRequests::size);
|
||||
|
|
|
@ -22,6 +22,7 @@ import com.linecorp.armeria.server.ServerBuilder;
|
|||
import com.linecorp.armeria.testing.junit5.server.ServerExtension;
|
||||
import io.opentelemetry.api.GlobalOpenTelemetry;
|
||||
import io.opentelemetry.api.common.Attributes;
|
||||
import io.opentelemetry.api.metrics.MeterProvider;
|
||||
import io.opentelemetry.api.trace.SpanKind;
|
||||
import io.opentelemetry.proto.collector.metrics.v1.ExportMetricsServiceRequest;
|
||||
import io.opentelemetry.proto.collector.trace.v1.ExportTraceServiceRequest;
|
||||
|
@ -179,7 +180,8 @@ class OtlpHttpConfigTest {
|
|||
props.put("otel.exporter.otlp.timeout", "15s");
|
||||
ConfigProperties properties = DefaultConfigProperties.createForTest(props);
|
||||
SpanExporter spanExporter =
|
||||
SpanExporterConfiguration.configureExporter("otlp", properties, Collections.emptyMap());
|
||||
SpanExporterConfiguration.configureExporter(
|
||||
"otlp", properties, Collections.emptyMap(), MeterProvider.noop());
|
||||
MetricExporter metricExporter =
|
||||
MetricExporterConfiguration.configureOtlpMetrics(properties, SdkMeterProvider.builder());
|
||||
|
||||
|
@ -241,7 +243,10 @@ class OtlpHttpConfigTest {
|
|||
props.put("otel.exporter.otlp.traces.timeout", "15s");
|
||||
SpanExporter spanExporter =
|
||||
SpanExporterConfiguration.configureExporter(
|
||||
"otlp", DefaultConfigProperties.createForTest(props), Collections.emptyMap());
|
||||
"otlp",
|
||||
DefaultConfigProperties.createForTest(props),
|
||||
Collections.emptyMap(),
|
||||
MeterProvider.noop());
|
||||
|
||||
assertThat(spanExporter)
|
||||
.extracting("delegate.client", as(InstanceOfAssertFactories.type(OkHttpClient.class)))
|
||||
|
@ -315,7 +320,7 @@ class OtlpHttpConfigTest {
|
|||
assertThatThrownBy(
|
||||
() ->
|
||||
SpanExporterConfiguration.configureExporter(
|
||||
"otlp", properties, Collections.emptyMap()))
|
||||
"otlp", properties, Collections.emptyMap(), MeterProvider.noop()))
|
||||
.isInstanceOf(ConfigurationException.class)
|
||||
.hasMessageContaining("Invalid OTLP certificate path:");
|
||||
|
||||
|
|
|
@ -8,9 +8,9 @@ package io.opentelemetry.sdk.trace.export;
|
|||
import io.opentelemetry.api.common.AttributeKey;
|
||||
import io.opentelemetry.api.common.Attributes;
|
||||
import io.opentelemetry.api.metrics.BoundLongCounter;
|
||||
import io.opentelemetry.api.metrics.GlobalMeterProvider;
|
||||
import io.opentelemetry.api.metrics.LongCounter;
|
||||
import io.opentelemetry.api.metrics.Meter;
|
||||
import io.opentelemetry.api.metrics.MeterProvider;
|
||||
import io.opentelemetry.context.Context;
|
||||
import io.opentelemetry.sdk.common.CompletableResultCode;
|
||||
import io.opentelemetry.sdk.internal.DaemonThreadFactory;
|
||||
|
@ -66,6 +66,7 @@ public final class BatchSpanProcessor implements SpanProcessor {
|
|||
|
||||
BatchSpanProcessor(
|
||||
SpanExporter spanExporter,
|
||||
MeterProvider meterProvider,
|
||||
long scheduleDelayNanos,
|
||||
int maxQueueSize,
|
||||
int maxExportBatchSize,
|
||||
|
@ -73,6 +74,7 @@ public final class BatchSpanProcessor implements SpanProcessor {
|
|||
this.worker =
|
||||
new Worker(
|
||||
spanExporter,
|
||||
meterProvider,
|
||||
scheduleDelayNanos,
|
||||
maxExportBatchSize,
|
||||
exporterTimeoutNanos,
|
||||
|
@ -150,6 +152,7 @@ public final class BatchSpanProcessor implements SpanProcessor {
|
|||
|
||||
private Worker(
|
||||
SpanExporter spanExporter,
|
||||
MeterProvider meterProvider,
|
||||
long scheduleDelayNanos,
|
||||
int maxExportBatchSize,
|
||||
long exporterTimeoutNanos,
|
||||
|
@ -160,7 +163,7 @@ public final class BatchSpanProcessor implements SpanProcessor {
|
|||
this.exporterTimeoutNanos = exporterTimeoutNanos;
|
||||
this.queue = queue;
|
||||
this.signal = new ArrayBlockingQueue<>(1);
|
||||
Meter meter = GlobalMeterProvider.get().meterBuilder("io.opentelemetry.sdk.trace").build();
|
||||
Meter meter = meterProvider.meterBuilder("io.opentelemetry.sdk.trace").build();
|
||||
meter
|
||||
.gaugeBuilder("queueSize")
|
||||
.ofLongs()
|
||||
|
|
|
@ -8,6 +8,7 @@ package io.opentelemetry.sdk.trace.export;
|
|||
import static io.opentelemetry.api.internal.Utils.checkArgument;
|
||||
import static java.util.Objects.requireNonNull;
|
||||
|
||||
import io.opentelemetry.api.metrics.MeterProvider;
|
||||
import java.time.Duration;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
|
||||
|
@ -28,6 +29,7 @@ public final class BatchSpanProcessorBuilder {
|
|||
private int maxQueueSize = DEFAULT_MAX_QUEUE_SIZE;
|
||||
private int maxExportBatchSize = DEFAULT_MAX_EXPORT_BATCH_SIZE;
|
||||
private long exporterTimeoutNanos = TimeUnit.MILLISECONDS.toNanos(DEFAULT_EXPORT_TIMEOUT_MILLIS);
|
||||
private MeterProvider meterProvider = MeterProvider.noop();
|
||||
|
||||
BatchSpanProcessorBuilder(SpanExporter spanExporter) {
|
||||
this.spanExporter = requireNonNull(spanExporter, "spanExporter");
|
||||
|
@ -125,6 +127,16 @@ public final class BatchSpanProcessorBuilder {
|
|||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link MeterProvider} to use to collect metrics related to batch export. If not set,
|
||||
* metrics will not be collected.
|
||||
*/
|
||||
public BatchSpanProcessorBuilder setMeterProvider(MeterProvider meterProvider) {
|
||||
requireNonNull(meterProvider, "meterProvider");
|
||||
this.meterProvider = meterProvider;
|
||||
return this;
|
||||
}
|
||||
|
||||
// Visible for testing
|
||||
int getMaxExportBatchSize() {
|
||||
return maxExportBatchSize;
|
||||
|
@ -139,6 +151,11 @@ public final class BatchSpanProcessorBuilder {
|
|||
*/
|
||||
public BatchSpanProcessor build() {
|
||||
return new BatchSpanProcessor(
|
||||
spanExporter, scheduleDelayNanos, maxQueueSize, maxExportBatchSize, exporterTimeoutNanos);
|
||||
spanExporter,
|
||||
meterProvider,
|
||||
scheduleDelayNanos,
|
||||
maxQueueSize,
|
||||
maxExportBatchSize,
|
||||
exporterTimeoutNanos);
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue