Autoconfigure listener (#5931)
This commit is contained in:
parent
f99e4961cb
commit
f2f3ab33b7
|
@ -1,2 +1,13 @@
|
|||
Comparing source compatibility of against
|
||||
No changes.
|
||||
*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder (not serializable)
|
||||
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
|
||||
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder setMeterProvider(java.util.function.Supplier<io.opentelemetry.api.metrics.MeterProvider>)
|
||||
*** 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(java.util.function.Supplier<io.opentelemetry.api.metrics.MeterProvider>)
|
||||
*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder (not serializable)
|
||||
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
|
||||
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder setMeterProvider(java.util.function.Supplier<io.opentelemetry.api.metrics.MeterProvider>)
|
||||
*** 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(java.util.function.Supplier<io.opentelemetry.api.metrics.MeterProvider>)
|
||||
|
|
|
@ -123,8 +123,8 @@ public class GrpcExporterBuilder<T extends Marshaler> {
|
|||
return this;
|
||||
}
|
||||
|
||||
public GrpcExporterBuilder<T> setMeterProvider(MeterProvider meterProvider) {
|
||||
this.meterProviderSupplier = () -> meterProvider;
|
||||
public GrpcExporterBuilder<T> setMeterProvider(Supplier<MeterProvider> meterProviderSupplier) {
|
||||
this.meterProviderSupplier = meterProviderSupplier;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -112,8 +112,8 @@ public final class HttpExporterBuilder<T extends Marshaler> {
|
|||
return this;
|
||||
}
|
||||
|
||||
public HttpExporterBuilder<T> setMeterProvider(MeterProvider meterProvider) {
|
||||
this.meterProviderSupplier = () -> meterProvider;
|
||||
public HttpExporterBuilder<T> setMeterProvider(Supplier<MeterProvider> meterProviderSupplier) {
|
||||
this.meterProviderSupplier = meterProviderSupplier;
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -145,7 +145,7 @@ public final class JaegerGrpcSpanExporterBuilder {
|
|||
*/
|
||||
public JaegerGrpcSpanExporterBuilder setMeterProvider(MeterProvider meterProvider) {
|
||||
requireNonNull(meterProvider, "meterProvider");
|
||||
delegate.setMeterProvider(meterProvider);
|
||||
delegate.setMeterProvider(() -> meterProvider);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ import io.opentelemetry.exporter.otlp.internal.OtlpUserAgent;
|
|||
import io.opentelemetry.sdk.common.export.RetryPolicy;
|
||||
import java.time.Duration;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Supplier;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
|
||||
|
@ -135,7 +136,18 @@ public final class OtlpHttpLogRecordExporterBuilder {
|
|||
*/
|
||||
public OtlpHttpLogRecordExporterBuilder setMeterProvider(MeterProvider meterProvider) {
|
||||
requireNonNull(meterProvider, "meterProvider");
|
||||
delegate.setMeterProvider(meterProvider);
|
||||
setMeterProvider(() -> meterProvider);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link MeterProvider} supplier used to collect metrics related to export. If not set,
|
||||
* uses {@link GlobalOpenTelemetry#getMeterProvider()}.
|
||||
*/
|
||||
public OtlpHttpLogRecordExporterBuilder setMeterProvider(
|
||||
Supplier<MeterProvider> meterProviderSupplier) {
|
||||
requireNonNull(meterProviderSupplier, "meterProviderSupplier");
|
||||
delegate.setMeterProvider(meterProviderSupplier);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -43,7 +43,7 @@ public final class OtlpHttpMetricExporterBuilder {
|
|||
|
||||
OtlpHttpMetricExporterBuilder(HttpExporterBuilder<MetricsRequestMarshaler> delegate) {
|
||||
this.delegate = delegate;
|
||||
delegate.setMeterProvider(MeterProvider.noop());
|
||||
delegate.setMeterProvider(MeterProvider::noop);
|
||||
OtlpUserAgent.addUserAgentHeader(delegate::addHeader);
|
||||
}
|
||||
|
||||
|
|
|
@ -16,6 +16,7 @@ import io.opentelemetry.exporter.otlp.internal.OtlpUserAgent;
|
|||
import io.opentelemetry.sdk.common.export.RetryPolicy;
|
||||
import java.time.Duration;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Supplier;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
|
||||
|
@ -136,7 +137,18 @@ public final class OtlpHttpSpanExporterBuilder {
|
|||
*/
|
||||
public OtlpHttpSpanExporterBuilder setMeterProvider(MeterProvider meterProvider) {
|
||||
requireNonNull(meterProvider, "meterProvider");
|
||||
delegate.setMeterProvider(meterProvider);
|
||||
setMeterProvider(() -> meterProvider);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link MeterProvider} supplier to use to collect metrics related to export. If not
|
||||
* set, uses {@link GlobalOpenTelemetry#getMeterProvider()}.
|
||||
*/
|
||||
public OtlpHttpSpanExporterBuilder setMeterProvider(
|
||||
Supplier<MeterProvider> meterProviderSupplier) {
|
||||
requireNonNull(meterProviderSupplier, "meterProviderSupplier");
|
||||
delegate.setMeterProvider(meterProviderSupplier);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -9,14 +9,18 @@ import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.DATA_TYPE_L
|
|||
import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.PROTOCOL_GRPC;
|
||||
import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.PROTOCOL_HTTP_PROTOBUF;
|
||||
|
||||
import io.opentelemetry.api.metrics.MeterProvider;
|
||||
import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporter;
|
||||
import io.opentelemetry.exporter.otlp.http.logs.OtlpHttpLogRecordExporterBuilder;
|
||||
import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporter;
|
||||
import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogRecordExporterBuilder;
|
||||
import io.opentelemetry.sdk.OpenTelemetrySdk;
|
||||
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
|
||||
import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException;
|
||||
import io.opentelemetry.sdk.autoconfigure.spi.internal.AutoConfigureListener;
|
||||
import io.opentelemetry.sdk.autoconfigure.spi.logs.ConfigurableLogRecordExporterProvider;
|
||||
import io.opentelemetry.sdk.logs.export.LogRecordExporter;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
/**
|
||||
* {@link LogRecordExporter} SPI implementation for {@link OtlpGrpcLogRecordExporter} and {@link
|
||||
|
@ -25,7 +29,12 @@ import io.opentelemetry.sdk.logs.export.LogRecordExporter;
|
|||
* <p>This class is internal and is hence not for public use. Its APIs are unstable and can change
|
||||
* at any time.
|
||||
*/
|
||||
public class OtlpLogRecordExporterProvider implements ConfigurableLogRecordExporterProvider {
|
||||
public class OtlpLogRecordExporterProvider
|
||||
implements ConfigurableLogRecordExporterProvider, AutoConfigureListener {
|
||||
|
||||
private final AtomicReference<MeterProvider> meterProviderRef =
|
||||
new AtomicReference<>(MeterProvider.noop());
|
||||
|
||||
@Override
|
||||
public LogRecordExporter createExporter(ConfigProperties config) {
|
||||
String protocol = OtlpConfigUtil.getOtlpProtocol(DATA_TYPE_LOGS, config);
|
||||
|
@ -43,6 +52,7 @@ public class OtlpLogRecordExporterProvider implements ConfigurableLogRecordExpor
|
|||
builder::setTrustedCertificates,
|
||||
builder::setClientTls,
|
||||
builder::setRetryPolicy);
|
||||
builder.setMeterProvider(meterProviderRef::get);
|
||||
|
||||
return builder.build();
|
||||
} else if (protocol.equals(PROTOCOL_GRPC)) {
|
||||
|
@ -58,6 +68,7 @@ public class OtlpLogRecordExporterProvider implements ConfigurableLogRecordExpor
|
|||
builder::setTrustedCertificates,
|
||||
builder::setClientTls,
|
||||
builder::setRetryPolicy);
|
||||
builder.setMeterProvider(meterProviderRef::get);
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
@ -78,4 +89,9 @@ public class OtlpLogRecordExporterProvider implements ConfigurableLogRecordExpor
|
|||
OtlpGrpcLogRecordExporterBuilder grpcBuilder() {
|
||||
return OtlpGrpcLogRecordExporter.builder();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterAutoConfigure(OpenTelemetrySdk sdk) {
|
||||
meterProviderRef.set(sdk.getMeterProvider());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -26,6 +26,7 @@ import io.opentelemetry.sdk.metrics.export.MetricExporter;
|
|||
* at any time.
|
||||
*/
|
||||
public class OtlpMetricExporterProvider implements ConfigurableMetricExporterProvider {
|
||||
|
||||
@Override
|
||||
public MetricExporter createExporter(ConfigProperties config) {
|
||||
String protocol = OtlpConfigUtil.getOtlpProtocol(DATA_TYPE_METRICS, config);
|
||||
|
|
|
@ -9,14 +9,18 @@ import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.DATA_TYPE_T
|
|||
import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.PROTOCOL_GRPC;
|
||||
import static io.opentelemetry.exporter.otlp.internal.OtlpConfigUtil.PROTOCOL_HTTP_PROTOBUF;
|
||||
|
||||
import io.opentelemetry.api.metrics.MeterProvider;
|
||||
import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporter;
|
||||
import io.opentelemetry.exporter.otlp.http.trace.OtlpHttpSpanExporterBuilder;
|
||||
import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter;
|
||||
import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporterBuilder;
|
||||
import io.opentelemetry.sdk.OpenTelemetrySdk;
|
||||
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
|
||||
import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException;
|
||||
import io.opentelemetry.sdk.autoconfigure.spi.internal.AutoConfigureListener;
|
||||
import io.opentelemetry.sdk.autoconfigure.spi.traces.ConfigurableSpanExporterProvider;
|
||||
import io.opentelemetry.sdk.trace.export.SpanExporter;
|
||||
import java.util.concurrent.atomic.AtomicReference;
|
||||
|
||||
/**
|
||||
* {@link SpanExporter} SPI implementation for {@link OtlpGrpcSpanExporter} and {@link
|
||||
|
@ -25,7 +29,12 @@ import io.opentelemetry.sdk.trace.export.SpanExporter;
|
|||
* <p>This class is internal and is hence not for public use. Its APIs are unstable and can change
|
||||
* at any time.
|
||||
*/
|
||||
public class OtlpSpanExporterProvider implements ConfigurableSpanExporterProvider {
|
||||
public class OtlpSpanExporterProvider
|
||||
implements ConfigurableSpanExporterProvider, AutoConfigureListener {
|
||||
|
||||
private final AtomicReference<MeterProvider> meterProviderRef =
|
||||
new AtomicReference<>(MeterProvider.noop());
|
||||
|
||||
@Override
|
||||
public SpanExporter createExporter(ConfigProperties config) {
|
||||
String protocol = OtlpConfigUtil.getOtlpProtocol(DATA_TYPE_TRACES, config);
|
||||
|
@ -42,6 +51,7 @@ public class OtlpSpanExporterProvider implements ConfigurableSpanExporterProvide
|
|||
builder::setTrustedCertificates,
|
||||
builder::setClientTls,
|
||||
builder::setRetryPolicy);
|
||||
builder.setMeterProvider(meterProviderRef::get);
|
||||
|
||||
return builder.build();
|
||||
} else if (protocol.equals(PROTOCOL_GRPC)) {
|
||||
|
@ -57,6 +67,7 @@ public class OtlpSpanExporterProvider implements ConfigurableSpanExporterProvide
|
|||
builder::setTrustedCertificates,
|
||||
builder::setClientTls,
|
||||
builder::setRetryPolicy);
|
||||
builder.setMeterProvider(meterProviderRef::get);
|
||||
|
||||
return builder.build();
|
||||
}
|
||||
|
@ -77,4 +88,9 @@ public class OtlpSpanExporterProvider implements ConfigurableSpanExporterProvide
|
|||
OtlpGrpcSpanExporterBuilder grpcBuilder() {
|
||||
return OtlpGrpcSpanExporter.builder();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterAutoConfigure(OpenTelemetrySdk sdk) {
|
||||
meterProviderRef.set(sdk.getMeterProvider());
|
||||
}
|
||||
}
|
||||
|
|
|
@ -18,6 +18,7 @@ import io.opentelemetry.sdk.common.export.RetryPolicy;
|
|||
import java.net.URI;
|
||||
import java.time.Duration;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Supplier;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
|
||||
|
@ -179,7 +180,18 @@ public final class OtlpGrpcLogRecordExporterBuilder {
|
|||
*/
|
||||
public OtlpGrpcLogRecordExporterBuilder setMeterProvider(MeterProvider meterProvider) {
|
||||
requireNonNull(meterProvider, "meterProvider");
|
||||
delegate.setMeterProvider(meterProvider);
|
||||
setMeterProvider(() -> meterProvider);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link MeterProvider} supplier used to collect metrics related to export. If not set,
|
||||
* uses {@link GlobalOpenTelemetry#getMeterProvider()}.
|
||||
*/
|
||||
public OtlpGrpcLogRecordExporterBuilder setMeterProvider(
|
||||
Supplier<MeterProvider> meterProviderSupplier) {
|
||||
requireNonNull(meterProviderSupplier, "meterProviderSupplier");
|
||||
delegate.setMeterProvider(meterProviderSupplier);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -53,7 +53,7 @@ public final class OtlpGrpcMetricExporterBuilder {
|
|||
|
||||
OtlpGrpcMetricExporterBuilder(GrpcExporterBuilder<MetricsRequestMarshaler> delegate) {
|
||||
this.delegate = delegate;
|
||||
delegate.setMeterProvider(MeterProvider.noop());
|
||||
delegate.setMeterProvider(MeterProvider::noop);
|
||||
OtlpUserAgent.addUserAgentHeader(delegate::addHeader);
|
||||
}
|
||||
|
||||
|
|
|
@ -18,6 +18,7 @@ import io.opentelemetry.sdk.common.export.RetryPolicy;
|
|||
import java.net.URI;
|
||||
import java.time.Duration;
|
||||
import java.util.concurrent.TimeUnit;
|
||||
import java.util.function.Supplier;
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.X509TrustManager;
|
||||
|
||||
|
@ -176,7 +177,18 @@ public final class OtlpGrpcSpanExporterBuilder {
|
|||
*/
|
||||
public OtlpGrpcSpanExporterBuilder setMeterProvider(MeterProvider meterProvider) {
|
||||
requireNonNull(meterProvider, "meterProvider");
|
||||
delegate.setMeterProvider(meterProvider);
|
||||
setMeterProvider(() -> meterProvider);
|
||||
return this;
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets the {@link MeterProvider} supplier used to collect metrics related to export. If not set,
|
||||
* uses {@link GlobalOpenTelemetry#getMeterProvider()}.
|
||||
*/
|
||||
public OtlpGrpcSpanExporterBuilder setMeterProvider(
|
||||
Supplier<MeterProvider> meterProviderSupplier) {
|
||||
requireNonNull(meterProviderSupplier, "meterProviderSupplier");
|
||||
delegate.setMeterProvider(meterProviderSupplier);
|
||||
return this;
|
||||
}
|
||||
|
||||
|
|
|
@ -259,7 +259,7 @@ public class OtlpPipelineStressTest {
|
|||
// set up the span exporter and wire it into the SDK
|
||||
OtlpGrpcSpanExporter spanExporter =
|
||||
OtlpGrpcSpanExporter.builder()
|
||||
.setMeterProvider(meterProvider)
|
||||
.setMeterProvider(() -> meterProvider)
|
||||
.setEndpoint(
|
||||
"http://"
|
||||
+ toxiproxyContainer.getHost()
|
||||
|
|
|
@ -0,0 +1,20 @@
|
|||
/*
|
||||
* Copyright The OpenTelemetry Authors
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
package io.opentelemetry.sdk.autoconfigure.spi.internal;
|
||||
|
||||
import io.opentelemetry.sdk.OpenTelemetrySdk;
|
||||
|
||||
/**
|
||||
* Interface to be extended by SPIs that require access to the autoconfigured {@link
|
||||
* OpenTelemetrySdk} instance.
|
||||
*
|
||||
* <p>This is not a standalone SPI. Instead, implementations of other SPIs can also implement this
|
||||
* interface to receive a callback with the configured SDK.
|
||||
*/
|
||||
public interface AutoConfigureListener {
|
||||
|
||||
void afterAutoConfigure(OpenTelemetrySdk sdk);
|
||||
}
|
|
@ -18,6 +18,7 @@ import io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer;
|
|||
import io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizerProvider;
|
||||
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
|
||||
import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException;
|
||||
import io.opentelemetry.sdk.autoconfigure.spi.internal.AutoConfigureListener;
|
||||
import io.opentelemetry.sdk.autoconfigure.spi.internal.DefaultConfigProperties;
|
||||
import io.opentelemetry.sdk.logs.SdkLoggerProvider;
|
||||
import io.opentelemetry.sdk.logs.SdkLoggerProviderBuilder;
|
||||
|
@ -405,6 +406,7 @@ public final class AutoConfiguredOpenTelemetrySdkBuilder implements AutoConfigur
|
|||
|
||||
maybeRegisterShutdownHook(openTelemetrySdk);
|
||||
maybeSetAsGlobal(openTelemetrySdk);
|
||||
callAutoConfigureListeners(spiHelper, openTelemetrySdk);
|
||||
|
||||
return AutoConfiguredOpenTelemetrySdk.create(openTelemetrySdk, resource, config);
|
||||
} catch (RuntimeException e) {
|
||||
|
@ -478,6 +480,18 @@ public final class AutoConfiguredOpenTelemetrySdkBuilder implements AutoConfigur
|
|||
Level.FINE, "Global OpenTelemetry set to {0} by autoconfiguration", openTelemetrySdk);
|
||||
}
|
||||
|
||||
// Visible for testing
|
||||
void callAutoConfigureListeners(SpiHelper spiHelper, OpenTelemetrySdk openTelemetrySdk) {
|
||||
for (AutoConfigureListener listener : spiHelper.getListeners()) {
|
||||
try {
|
||||
listener.afterAutoConfigure(openTelemetrySdk);
|
||||
} catch (Throwable throwable) {
|
||||
logger.log(
|
||||
Level.WARNING, "Error invoking listener " + listener.getClass().getName(), throwable);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@SuppressWarnings("deprecation") // Support deprecated SdkTracerProviderConfigurer
|
||||
private void mergeSdkTracerProviderConfigurer() {
|
||||
for (io.opentelemetry.sdk.autoconfigure.spi.traces.SdkTracerProviderConfigurer configurer :
|
||||
|
|
|
@ -7,12 +7,16 @@ package io.opentelemetry.sdk.autoconfigure.internal;
|
|||
|
||||
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
|
||||
import io.opentelemetry.sdk.autoconfigure.spi.Ordered;
|
||||
import io.opentelemetry.sdk.autoconfigure.spi.internal.AutoConfigureListener;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collections;
|
||||
import java.util.Comparator;
|
||||
import java.util.HashMap;
|
||||
import java.util.IdentityHashMap;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
import java.util.ServiceLoader;
|
||||
import java.util.Set;
|
||||
import java.util.function.BiFunction;
|
||||
import java.util.function.Function;
|
||||
import java.util.function.Supplier;
|
||||
|
@ -25,6 +29,8 @@ public final class SpiHelper {
|
|||
|
||||
private final ClassLoader classLoader;
|
||||
private final SpiFinder spiFinder;
|
||||
private final Set<AutoConfigureListener> listeners =
|
||||
Collections.newSetFromMap(new IdentityHashMap<>());
|
||||
|
||||
// Visible for testing
|
||||
SpiHelper(ClassLoader classLoader, SpiFinder spiFinder) {
|
||||
|
@ -57,7 +63,13 @@ public final class SpiHelper {
|
|||
Map<String, Supplier<T>> nameToProvider = new HashMap<>();
|
||||
for (S provider : load(spiClass)) {
|
||||
String name = getName.apply(provider);
|
||||
nameToProvider.put(name, () -> getConfigurable.apply(provider, config));
|
||||
nameToProvider.put(
|
||||
name,
|
||||
() -> {
|
||||
T result = getConfigurable.apply(provider, config);
|
||||
maybeAddListener(result);
|
||||
return result;
|
||||
});
|
||||
}
|
||||
return NamedSpiManager.create(nameToProvider);
|
||||
}
|
||||
|
@ -85,11 +97,23 @@ public final class SpiHelper {
|
|||
public <T> List<T> load(Class<T> spiClass) {
|
||||
List<T> result = new ArrayList<>();
|
||||
for (T service : spiFinder.load(spiClass, classLoader)) {
|
||||
maybeAddListener(service);
|
||||
result.add(service);
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
private void maybeAddListener(Object object) {
|
||||
if (object instanceof AutoConfigureListener) {
|
||||
listeners.add((AutoConfigureListener) object);
|
||||
}
|
||||
}
|
||||
|
||||
/** Return the set of SPIs loaded which implement {@link AutoConfigureListener}. */
|
||||
public Set<AutoConfigureListener> getListeners() {
|
||||
return Collections.unmodifiableSet(listeners);
|
||||
}
|
||||
|
||||
// Visible for testing
|
||||
interface SpiFinder {
|
||||
<T> Iterable<T> load(Class<T> spiClass, ClassLoader classLoader);
|
||||
|
|
|
@ -8,6 +8,7 @@ package io.opentelemetry.sdk.autoconfigure;
|
|||
import static io.opentelemetry.api.common.AttributeKey.stringKey;
|
||||
import static java.util.Collections.singletonMap;
|
||||
import static org.assertj.core.api.Assertions.assertThat;
|
||||
import static org.assertj.core.api.Assertions.assertThatCode;
|
||||
import static org.assertj.core.api.Assertions.assertThatThrownBy;
|
||||
import static org.mockito.ArgumentMatchers.any;
|
||||
import static org.mockito.Mockito.doReturn;
|
||||
|
@ -33,8 +34,10 @@ import io.opentelemetry.context.propagation.TextMapGetter;
|
|||
import io.opentelemetry.context.propagation.TextMapPropagator;
|
||||
import io.opentelemetry.internal.testing.slf4j.SuppressLogger;
|
||||
import io.opentelemetry.sdk.OpenTelemetrySdk;
|
||||
import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper;
|
||||
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
|
||||
import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException;
|
||||
import io.opentelemetry.sdk.autoconfigure.spi.internal.AutoConfigureListener;
|
||||
import io.opentelemetry.sdk.common.CompletableResultCode;
|
||||
import io.opentelemetry.sdk.logs.LogRecordProcessor;
|
||||
import io.opentelemetry.sdk.logs.SdkLoggerProvider;
|
||||
|
@ -393,6 +396,27 @@ class AutoConfiguredOpenTelemetrySdkTest {
|
|||
verify(sdk).close();
|
||||
}
|
||||
|
||||
@Test
|
||||
void builder_CallAutoConfigureListeners() {
|
||||
builder = spy(builder);
|
||||
|
||||
assertThatCode(() -> builder.build()).doesNotThrowAnyException();
|
||||
|
||||
verify(builder, times(1)).callAutoConfigureListeners(any(), any());
|
||||
}
|
||||
|
||||
@Test
|
||||
void callAutoConfigureListeners() {
|
||||
AutoConfigureListener listener = mock(AutoConfigureListener.class);
|
||||
SpiHelper spiHelper = mock(SpiHelper.class);
|
||||
when(spiHelper.getListeners()).thenReturn(Collections.singleton(listener));
|
||||
OpenTelemetrySdk sdk = mock(OpenTelemetrySdk.class);
|
||||
|
||||
builder.callAutoConfigureListeners(spiHelper, sdk);
|
||||
|
||||
verify(listener).afterAutoConfigure(sdk);
|
||||
}
|
||||
|
||||
private static Supplier<Map<String, String>> disableExportPropertySupplier() {
|
||||
Map<String, String> props = new HashMap<>();
|
||||
props.put("otel.metrics.exporter", "none");
|
||||
|
|
|
@ -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.exporter.otlp.internal.OtlpLogRecordExporterProvider;
|
||||
import io.opentelemetry.internal.testing.CleanupExtension;
|
||||
import io.opentelemetry.sdk.autoconfigure.internal.NamedSpiManager;
|
||||
import io.opentelemetry.sdk.autoconfigure.internal.SpiHelper;
|
||||
|
@ -37,12 +38,10 @@ class ConfigurableLogRecordExporterTest {
|
|||
ImmutableMap.of("test.option", "true", "otel.logs.exporter", "testExporter"));
|
||||
List<Closeable> closeables = new ArrayList<>();
|
||||
|
||||
SpiHelper spiHelper = SpiHelper.create(LogRecordExporterConfiguration.class.getClassLoader());
|
||||
Map<String, LogRecordExporter> exportersByName =
|
||||
LogRecordExporterConfiguration.configureLogRecordExporters(
|
||||
config,
|
||||
SpiHelper.create(LogRecordExporterConfiguration.class.getClassLoader()),
|
||||
(a, unused) -> a,
|
||||
closeables);
|
||||
config, spiHelper, (a, unused) -> a, closeables);
|
||||
cleanup.addCloseables(closeables);
|
||||
|
||||
assertThat(exportersByName)
|
||||
|
@ -55,6 +54,11 @@ class ConfigurableLogRecordExporterTest {
|
|||
assertThat(closeables)
|
||||
.hasExactlyElementsOfTypes(
|
||||
TestConfigurableLogRecordExporterProvider.TestLogRecordExporter.class);
|
||||
assertThat(spiHelper.getListeners())
|
||||
.satisfiesExactlyInAnyOrder(
|
||||
listener ->
|
||||
assertThat(listener).isInstanceOf(TestConfigurableLogRecordExporterProvider.class),
|
||||
listener -> assertThat(listener).isInstanceOf(OtlpLogRecordExporterProvider.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -64,17 +68,16 @@ class ConfigurableLogRecordExporterTest {
|
|||
ImmutableMap.of("test.option", "true", "otel.logs.exporter", "testExporter"));
|
||||
List<Closeable> closeables = new ArrayList<>();
|
||||
|
||||
SpiHelper spiHelper = SpiHelper.create(new URLClassLoader(new URL[0], null));
|
||||
assertThatThrownBy(
|
||||
() ->
|
||||
LogRecordExporterConfiguration.configureLogRecordExporters(
|
||||
config,
|
||||
SpiHelper.create(new URLClassLoader(new URL[0], null)),
|
||||
(a, unused) -> a,
|
||||
closeables))
|
||||
config, spiHelper, (a, unused) -> a, closeables))
|
||||
.isInstanceOf(ConfigurationException.class)
|
||||
.hasMessageContaining("testExporter");
|
||||
cleanup.addCloseables(closeables);
|
||||
assertThat(closeables).isEmpty();
|
||||
assertThat(spiHelper.getListeners()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -49,6 +49,10 @@ class ConfigurableMetricExporterTest {
|
|||
.isInstanceOf(TestConfigurableMetricExporterProvider.TestMetricExporter.class)
|
||||
.extracting("config")
|
||||
.isSameAs(config);
|
||||
assertThat(spiHelper.getListeners())
|
||||
.satisfiesExactlyInAnyOrder(
|
||||
listener ->
|
||||
assertThat(listener).isInstanceOf(TestConfigurableMetricExporterProvider.class));
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -88,6 +92,7 @@ class ConfigurableMetricExporterTest {
|
|||
.hasMessageContaining("otel.metrics.exporter contains none along with other exporters");
|
||||
cleanup.addCloseables(closeables);
|
||||
assertThat(closeables).isEmpty();
|
||||
assertThat(spiHelper.getListeners()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -11,6 +11,7 @@ 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.internal.OtlpSpanExporterProvider;
|
||||
import io.opentelemetry.exporter.otlp.trace.OtlpGrpcSpanExporter;
|
||||
import io.opentelemetry.exporter.zipkin.ZipkinSpanExporter;
|
||||
import io.opentelemetry.internal.testing.CleanupExtension;
|
||||
|
@ -63,6 +64,11 @@ class ConfigurableSpanExporterTest {
|
|||
.isSameAs(config);
|
||||
assertThat(closeables)
|
||||
.hasExactlyElementsOfTypes(TestConfigurableSpanExporterProvider.TestSpanExporter.class);
|
||||
assertThat(spiHelper.getListeners())
|
||||
.satisfiesExactlyInAnyOrder(
|
||||
listener ->
|
||||
assertThat(listener).isInstanceOf(TestConfigurableSpanExporterProvider.class),
|
||||
listener -> assertThat(listener).isInstanceOf(OtlpSpanExporterProvider.class));
|
||||
}
|
||||
|
||||
@Test
|
||||
|
@ -83,6 +89,7 @@ class ConfigurableSpanExporterTest {
|
|||
.hasMessageContaining("testExporter");
|
||||
cleanup.addCloseables(closeables);
|
||||
assertThat(closeables).isEmpty();
|
||||
assertThat(spiHelper.getListeners()).isEmpty();
|
||||
}
|
||||
|
||||
@Test
|
||||
|
|
|
@ -39,8 +39,6 @@ import io.opentelemetry.proto.collector.trace.v1.TraceServiceGrpc;
|
|||
import io.opentelemetry.proto.common.v1.AnyValue;
|
||||
import io.opentelemetry.proto.common.v1.KeyValue;
|
||||
import io.opentelemetry.proto.metrics.v1.Metric;
|
||||
import io.opentelemetry.proto.metrics.v1.ResourceMetrics;
|
||||
import io.opentelemetry.proto.metrics.v1.ScopeMetrics;
|
||||
import io.opentelemetry.sdk.OpenTelemetrySdk;
|
||||
import java.util.ArrayList;
|
||||
import java.util.Collection;
|
||||
|
@ -216,8 +214,8 @@ class FullConfigTest {
|
|||
eventEmitter.emit("test-name", Attributes.builder().put("cow", "moo").build());
|
||||
|
||||
openTelemetrySdk.getSdkTracerProvider().forceFlush().join(10, TimeUnit.SECONDS);
|
||||
openTelemetrySdk.getSdkMeterProvider().forceFlush().join(10, TimeUnit.SECONDS);
|
||||
openTelemetrySdk.getSdkLoggerProvider().forceFlush().join(10, TimeUnit.SECONDS);
|
||||
openTelemetrySdk.getSdkMeterProvider().forceFlush().join(10, TimeUnit.SECONDS);
|
||||
|
||||
await().untilAsserted(() -> assertThat(otlpTraceRequests).hasSize(1));
|
||||
|
||||
|
@ -257,38 +255,61 @@ class FullConfigTest {
|
|||
.untilAsserted(
|
||||
() -> {
|
||||
ExportMetricsServiceRequest metricRequest = otlpMetricsRequests.take();
|
||||
assertThat(metricRequest.getResourceMetrics(0).getResource().getAttributesList())
|
||||
.contains(
|
||||
KeyValue.newBuilder()
|
||||
.setKey("service.name")
|
||||
.setValue(AnyValue.newBuilder().setStringValue("test").build())
|
||||
.build(),
|
||||
KeyValue.newBuilder()
|
||||
.setKey("cat")
|
||||
.setValue(AnyValue.newBuilder().setStringValue("meow").build())
|
||||
.build());
|
||||
|
||||
for (ResourceMetrics resourceMetrics : metricRequest.getResourceMetricsList()) {
|
||||
assertThat(resourceMetrics.getScopeMetricsList())
|
||||
.anySatisfy(ilm -> assertThat(ilm.getScope().getName()).isEqualTo("test"));
|
||||
for (ScopeMetrics instrumentationLibraryMetrics :
|
||||
resourceMetrics.getScopeMetricsList()) {
|
||||
for (Metric metric : instrumentationLibraryMetrics.getMetricsList()) {
|
||||
// SPI was loaded
|
||||
// MetricExporterCustomizer filters metrics not named my-metric
|
||||
assertThat(metric.getName()).isEqualTo("my-metric");
|
||||
// TestMeterProviderConfigurer configures a view that only passes on attribute
|
||||
// named allowed
|
||||
// configured-test
|
||||
assertThat(getFirstDataPointLabels(metric))
|
||||
.contains(
|
||||
KeyValue.newBuilder()
|
||||
.setKey("allowed")
|
||||
.setValue(AnyValue.newBuilder().setStringValue("bear").build())
|
||||
.build());
|
||||
}
|
||||
}
|
||||
}
|
||||
assertThat(metricRequest.getResourceMetricsList())
|
||||
.satisfiesExactly(
|
||||
resourceMetrics -> {
|
||||
assertThat(resourceMetrics.getResource().getAttributesList())
|
||||
.contains(
|
||||
KeyValue.newBuilder()
|
||||
.setKey("service.name")
|
||||
.setValue(AnyValue.newBuilder().setStringValue("test").build())
|
||||
.build(),
|
||||
KeyValue.newBuilder()
|
||||
.setKey("cat")
|
||||
.setValue(AnyValue.newBuilder().setStringValue("meow").build())
|
||||
.build());
|
||||
assertThat(resourceMetrics.getScopeMetricsList())
|
||||
.anySatisfy(
|
||||
scopeMetrics -> {
|
||||
assertThat(scopeMetrics.getScope().getName()).isEqualTo("test");
|
||||
assertThat(scopeMetrics.getMetricsList())
|
||||
.satisfiesExactly(
|
||||
metric -> {
|
||||
// SPI was loaded
|
||||
assertThat(metric.getName()).isEqualTo("my-metric");
|
||||
// TestMeterProviderConfigurer configures a view that
|
||||
// only passes on attribute
|
||||
// named allowed
|
||||
// configured-test
|
||||
assertThat(getFirstDataPointLabels(metric))
|
||||
.contains(
|
||||
KeyValue.newBuilder()
|
||||
.setKey("allowed")
|
||||
.setValue(
|
||||
AnyValue.newBuilder()
|
||||
.setStringValue("bear")
|
||||
.build())
|
||||
.build());
|
||||
});
|
||||
})
|
||||
// This verifies that AutoConfigureListener was invoked and the OTLP
|
||||
// span / log exporters received the autoconfigured OpenTelemetrySdk
|
||||
// instance
|
||||
.anySatisfy(
|
||||
scopeMetrics -> {
|
||||
assertThat(scopeMetrics.getScope().getName())
|
||||
.isEqualTo("io.opentelemetry.exporters.otlp-grpc");
|
||||
assertThat(scopeMetrics.getMetricsList())
|
||||
.satisfiesExactlyInAnyOrder(
|
||||
metric ->
|
||||
assertThat(metric.getName())
|
||||
.isEqualTo("otlp.exporter.seen"),
|
||||
metric ->
|
||||
assertThat(metric.getName())
|
||||
.isEqualTo("otlp.exporter.exported"));
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
await().untilAsserted(() -> assertThat(otlpLogsRequests).hasSize(1));
|
||||
|
|
|
@ -48,7 +48,13 @@ public class MetricCustomizer implements AutoConfigurationCustomizerProvider {
|
|||
// please configure the SdkMeterProvider with the appropriate view.
|
||||
Collection<MetricData> filtered =
|
||||
metrics.stream()
|
||||
.filter(metricData -> metricData.getName().equals("my-metric"))
|
||||
.filter(
|
||||
metricData ->
|
||||
metricData.getName().equals("my-metric")
|
||||
|| metricData
|
||||
.getInstrumentationScopeInfo()
|
||||
.getName()
|
||||
.startsWith("io.opentelemetry.exporters"))
|
||||
.collect(Collectors.toList());
|
||||
return delegate.export(filtered);
|
||||
}
|
||||
|
|
|
@ -5,7 +5,9 @@
|
|||
|
||||
package io.opentelemetry.sdk.autoconfigure.provider;
|
||||
|
||||
import io.opentelemetry.sdk.OpenTelemetrySdk;
|
||||
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
|
||||
import io.opentelemetry.sdk.autoconfigure.spi.internal.AutoConfigureListener;
|
||||
import io.opentelemetry.sdk.autoconfigure.spi.logs.ConfigurableLogRecordExporterProvider;
|
||||
import io.opentelemetry.sdk.common.CompletableResultCode;
|
||||
import io.opentelemetry.sdk.logs.data.LogRecordData;
|
||||
|
@ -13,7 +15,7 @@ import io.opentelemetry.sdk.logs.export.LogRecordExporter;
|
|||
import java.util.Collection;
|
||||
|
||||
public class TestConfigurableLogRecordExporterProvider
|
||||
implements ConfigurableLogRecordExporterProvider {
|
||||
implements ConfigurableLogRecordExporterProvider, AutoConfigureListener {
|
||||
|
||||
@Override
|
||||
public LogRecordExporter createExporter(ConfigProperties config) {
|
||||
|
@ -25,6 +27,9 @@ public class TestConfigurableLogRecordExporterProvider
|
|||
return "testExporter";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterAutoConfigure(OpenTelemetrySdk sdk) {}
|
||||
|
||||
public static class TestLogRecordExporter implements LogRecordExporter {
|
||||
private final ConfigProperties config;
|
||||
|
||||
|
|
|
@ -5,7 +5,9 @@
|
|||
|
||||
package io.opentelemetry.sdk.autoconfigure.provider;
|
||||
|
||||
import io.opentelemetry.sdk.OpenTelemetrySdk;
|
||||
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
|
||||
import io.opentelemetry.sdk.autoconfigure.spi.internal.AutoConfigureListener;
|
||||
import io.opentelemetry.sdk.autoconfigure.spi.metrics.ConfigurableMetricExporterProvider;
|
||||
import io.opentelemetry.sdk.common.CompletableResultCode;
|
||||
import io.opentelemetry.sdk.metrics.InstrumentType;
|
||||
|
@ -14,7 +16,8 @@ import io.opentelemetry.sdk.metrics.data.MetricData;
|
|||
import io.opentelemetry.sdk.metrics.export.MetricExporter;
|
||||
import java.util.Collection;
|
||||
|
||||
public class TestConfigurableMetricExporterProvider implements ConfigurableMetricExporterProvider {
|
||||
public class TestConfigurableMetricExporterProvider
|
||||
implements ConfigurableMetricExporterProvider, AutoConfigureListener {
|
||||
|
||||
@Override
|
||||
public MetricExporter createExporter(ConfigProperties config) {
|
||||
|
@ -26,6 +29,9 @@ public class TestConfigurableMetricExporterProvider implements ConfigurableMetri
|
|||
return "testExporter";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterAutoConfigure(OpenTelemetrySdk sdk) {}
|
||||
|
||||
public static class TestMetricExporter implements MetricExporter {
|
||||
private final ConfigProperties config;
|
||||
|
||||
|
|
|
@ -5,14 +5,17 @@
|
|||
|
||||
package io.opentelemetry.sdk.autoconfigure.provider;
|
||||
|
||||
import io.opentelemetry.sdk.OpenTelemetrySdk;
|
||||
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
|
||||
import io.opentelemetry.sdk.autoconfigure.spi.internal.AutoConfigureListener;
|
||||
import io.opentelemetry.sdk.autoconfigure.spi.traces.ConfigurableSpanExporterProvider;
|
||||
import io.opentelemetry.sdk.common.CompletableResultCode;
|
||||
import io.opentelemetry.sdk.trace.data.SpanData;
|
||||
import io.opentelemetry.sdk.trace.export.SpanExporter;
|
||||
import java.util.Collection;
|
||||
|
||||
public class TestConfigurableSpanExporterProvider implements ConfigurableSpanExporterProvider {
|
||||
public class TestConfigurableSpanExporterProvider
|
||||
implements ConfigurableSpanExporterProvider, AutoConfigureListener {
|
||||
@Override
|
||||
public SpanExporter createExporter(ConfigProperties config) {
|
||||
return new TestSpanExporter(config);
|
||||
|
@ -23,6 +26,9 @@ public class TestConfigurableSpanExporterProvider implements ConfigurableSpanExp
|
|||
return "testExporter";
|
||||
}
|
||||
|
||||
@Override
|
||||
public void afterAutoConfigure(OpenTelemetrySdk sdk) {}
|
||||
|
||||
public static class TestSpanExporter implements SpanExporter {
|
||||
|
||||
private final ConfigProperties config;
|
||||
|
|
Loading…
Reference in New Issue