refactor: adjust tracer and meter provider customizer execution order (#4129)

* refactor: adjust tracer and meter provider customizer execution order

* refactor: Modify tracer provider customizer flow

* style: Format code using spotlessApply
This commit is contained in:
wallezhang 2022-02-01 01:56:00 +08:00 committed by GitHub
parent 87f788a3b4
commit 97d2115dc4
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 72 additions and 31 deletions

View File

@ -15,6 +15,7 @@ import io.opentelemetry.sdk.OpenTelemetrySdkBuilder;
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.traces.SdkTracerProviderConfigurer;
import io.opentelemetry.sdk.common.CompletableResultCode;
import io.opentelemetry.sdk.logs.SdkLogEmitterProvider;
import io.opentelemetry.sdk.metrics.SdkMeterProvider;
@ -215,6 +216,7 @@ public final class AutoConfiguredOpenTelemetrySdkBuilder implements AutoConfigur
public AutoConfiguredOpenTelemetrySdk build() {
if (!customized) {
customized = true;
mergeSdkTracerProviderConfigurer();
for (AutoConfigurationCustomizerProvider customizer :
ServiceLoader.load(AutoConfigurationCustomizerProvider.class, serviceClassLoader)) {
customizer.customize(this);
@ -223,23 +225,23 @@ public final class AutoConfiguredOpenTelemetrySdkBuilder implements AutoConfigur
SdkTracerProviderBuilder tracerProviderBuilder = SdkTracerProvider.builder();
ConfigProperties config = getConfig();
tracerProviderBuilder = tracerProviderCustomizer.apply(tracerProviderBuilder, config);
Resource resource =
ResourceConfiguration.configureResource(config, serviceClassLoader, resourceCustomizer);
tracerProviderBuilder.setResource(resource);
SdkMeterProvider meterProvider =
MeterProviderConfiguration.configureMeterProvider(resource, config, serviceClassLoader);
SdkTracerProvider tracerProvider =
TracerProviderConfiguration.configureTracerProvider(
tracerProviderBuilder,
config,
serviceClassLoader,
meterProvider,
spanExporterCustomizer,
samplerCustomizer);
tracerProviderBuilder.setResource(resource);
TracerProviderConfiguration.configureTracerProvider(
tracerProviderBuilder,
config,
serviceClassLoader,
meterProvider,
spanExporterCustomizer,
samplerCustomizer);
tracerProviderBuilder = tracerProviderCustomizer.apply(tracerProviderBuilder, config);
SdkTracerProvider tracerProvider = tracerProviderBuilder.build();
SdkLogEmitterProvider logEmitterProvider =
LogEmitterProviderConfiguration.configureLogEmitterProvider(
@ -280,6 +282,17 @@ public final class AutoConfiguredOpenTelemetrySdkBuilder implements AutoConfigur
return AutoConfiguredOpenTelemetrySdk.create(openTelemetrySdk, resource, config);
}
private void mergeSdkTracerProviderConfigurer() {
for (SdkTracerProviderConfigurer configurer :
ServiceLoader.load(SdkTracerProviderConfigurer.class, serviceClassLoader)) {
addTracerProviderCustomizer(
(builder, config) -> {
configurer.configure(builder, config);
return builder;
});
}
}
private ConfigProperties getConfig() {
ConfigProperties config = this.config;
if (config == null) {

View File

@ -9,8 +9,6 @@ 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;
import io.opentelemetry.sdk.autoconfigure.spi.traces.SdkTracerProviderConfigurer;
import io.opentelemetry.sdk.trace.SdkTracerProvider;
import io.opentelemetry.sdk.trace.SdkTracerProviderBuilder;
import io.opentelemetry.sdk.trace.SpanLimits;
import io.opentelemetry.sdk.trace.SpanLimitsBuilder;
@ -26,12 +24,11 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.ServiceLoader;
import java.util.function.BiFunction;
final class TracerProviderConfiguration {
static SdkTracerProvider configureTracerProvider(
static void configureTracerProvider(
SdkTracerProviderBuilder tracerProviderBuilder,
ConfigProperties config,
ClassLoader serviceClassLoader,
@ -49,21 +46,12 @@ final class TracerProviderConfiguration {
tracerProviderBuilder.setSampler(
samplerCustomizer.apply(configureSampler(sampler, config, serviceClassLoader), config));
// Run user configuration before setting exporters from environment to allow user span
// processors to effect export.
for (SdkTracerProviderConfigurer configurer :
ServiceLoader.load(SdkTracerProviderConfigurer.class, serviceClassLoader)) {
configurer.configure(tracerProviderBuilder, config);
}
Map<String, SpanExporter> exportersByName =
SpanExporterConfiguration.configureSpanExporters(
config, serviceClassLoader, meterProvider, spanExporterCustomizer);
configureSpanProcessors(config, exportersByName, meterProvider)
.forEach(tracerProviderBuilder::addSpanProcessor);
return tracerProviderBuilder.build();
}
static List<SpanProcessor> configureSpanProcessors(

View File

@ -23,12 +23,16 @@ import io.opentelemetry.context.propagation.TextMapPropagator;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.common.CompletableResultCode;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.testing.exporter.InMemorySpanExporter;
import io.opentelemetry.sdk.trace.IdGenerator;
import io.opentelemetry.sdk.trace.data.SpanData;
import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor;
import io.opentelemetry.sdk.trace.export.SpanExporter;
import io.opentelemetry.sdk.trace.samplers.Sampler;
import io.opentelemetry.sdk.trace.samplers.SamplingResult;
import io.opentelemetry.semconv.resource.attributes.ResourceAttributes;
import java.util.Collections;
import java.util.List;
import java.util.Map;
import java.util.concurrent.TimeUnit;
import org.junit.jupiter.api.BeforeEach;
@ -150,4 +154,37 @@ class AutoConfiguredOpenTelemetrySdkTest {
// Ensures the export happened.
sdk.getSdkTracerProvider().shutdown().join(10, TimeUnit.SECONDS);
}
@Test
void tracerProviderCustomizer() {
InMemorySpanExporter spanExporter = InMemorySpanExporter.create();
AutoConfiguredOpenTelemetrySdkBuilder autoConfiguration =
AutoConfiguredOpenTelemetrySdk.builder()
.addTracerProviderCustomizer(
(tracerProviderBuilder, config) -> {
tracerProviderBuilder.setResource(Resource.builder().put("cat", "meow").build());
return tracerProviderBuilder.addSpanProcessor(
SimpleSpanProcessor.create(spanExporter));
})
.addResourceCustomizer(
(resource, config) -> resource.merge(Resource.builder().put("cow", "moo").build()))
.addPropertiesSupplier(() -> Collections.singletonMap("otel.metrics.exporter", "none"))
.addPropertiesSupplier(() -> Collections.singletonMap("otel.traces.exporter", "none"))
.addPropertiesSupplier(() -> Collections.singletonMap("otel.logs.exporter", "none"))
.setResultAsGlobal(false);
GlobalOpenTelemetry.set(OpenTelemetry.noop());
AutoConfiguredOpenTelemetrySdk autoConfigured = autoConfiguration.build();
assertThat(autoConfigured.getResource().getAttribute(stringKey("cow"))).isEqualTo("moo");
OpenTelemetrySdk sdk = autoConfigured.getOpenTelemetrySdk();
sdk.getTracerProvider().get("test").spanBuilder("test").startSpan().end();
List<SpanData> spanItems = spanExporter.getFinishedSpanItems();
assertThat(spanItems.size()).isEqualTo(1);
SpanData spanData = spanItems.get(0);
assertThat(spanData.getResource().getAttribute(stringKey("cat"))).isEqualTo("meow");
// Ensures the export happened.
sdk.getSdkTracerProvider().shutdown().join(10, TimeUnit.SECONDS);
}
}

View File

@ -16,6 +16,7 @@ import io.opentelemetry.sdk.autoconfigure.spi.ConfigurationException;
import io.opentelemetry.sdk.common.CompletableResultCode;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.trace.SdkTracerProvider;
import io.opentelemetry.sdk.trace.SdkTracerProviderBuilder;
import io.opentelemetry.sdk.trace.SpanLimits;
import io.opentelemetry.sdk.trace.SpanProcessor;
import io.opentelemetry.sdk.trace.export.BatchSpanProcessor;
@ -61,14 +62,16 @@ class TracerProviderConfigurationTest {
Resource resource = Resource.create(Attributes.builder().put("cat", "meow").build());
// We don't have any exporters on classpath for this test so check no-op case. Exporter cases
// are verified in other test sets like testFullConfig.
SdkTracerProvider tracerProvider =
TracerProviderConfiguration.configureTracerProvider(
SdkTracerProvider.builder().setResource(resource),
DefaultConfigProperties.createForTest(properties),
TracerProviderConfiguration.class.getClassLoader(),
MeterProvider.noop(),
(a, unused) -> a,
(a, unused) -> a);
SdkTracerProviderBuilder tracerProviderBuilder =
SdkTracerProvider.builder().setResource(resource);
TracerProviderConfiguration.configureTracerProvider(
tracerProviderBuilder,
DefaultConfigProperties.createForTest(properties),
TracerProviderConfiguration.class.getClassLoader(),
MeterProvider.noop(),
(a, unused) -> a,
(a, unused) -> a);
SdkTracerProvider tracerProvider = tracerProviderBuilder.build();
try {
assertThat(tracerProvider.getSampler()).isEqualTo(Sampler.alwaysOff());