io.opentelemetry.sdk.autoconfigure.TracerProviderConfiguration Maven / Gradle / Ivy
Go to download
Show more of this group Show more artifacts with this name
Show all versions of opentelemetry-sdk-extension-autoconfigure Show documentation
Show all versions of opentelemetry-sdk-extension-autoconfigure Show documentation
OpenTelemetry SDK Auto-configuration
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.sdk.autoconfigure;
import io.opentelemetry.api.metrics.MeterProvider;
import io.opentelemetry.sdk.autoconfigure.internal.NamedSpiManager;
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.traces.ConfigurableSamplerProvider;
import io.opentelemetry.sdk.trace.SdkTracerProviderBuilder;
import io.opentelemetry.sdk.trace.SpanLimits;
import io.opentelemetry.sdk.trace.SpanLimitsBuilder;
import io.opentelemetry.sdk.trace.SpanProcessor;
import io.opentelemetry.sdk.trace.export.BatchSpanProcessor;
import io.opentelemetry.sdk.trace.export.BatchSpanProcessorBuilder;
import io.opentelemetry.sdk.trace.export.SimpleSpanProcessor;
import io.opentelemetry.sdk.trace.export.SpanExporter;
import io.opentelemetry.sdk.trace.samplers.Sampler;
import java.io.Closeable;
import java.time.Duration;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.BiFunction;
final class TracerProviderConfiguration {
private static final double DEFAULT_TRACEIDRATIO_SAMPLE_RATIO = 1.0d;
private static final String PARENTBASED_ALWAYS_ON = "parentbased_always_on";
private static final List simpleProcessorExporterNames =
Arrays.asList("console", "logging");
static void configureTracerProvider(
SdkTracerProviderBuilder tracerProviderBuilder,
ConfigProperties config,
SpiHelper spiHelper,
MeterProvider meterProvider,
BiFunction super SpanExporter, ConfigProperties, ? extends SpanExporter>
spanExporterCustomizer,
BiFunction super SpanProcessor, ConfigProperties, ? extends SpanProcessor>
spanProcessorCustomizer,
BiFunction super Sampler, ConfigProperties, ? extends Sampler> samplerCustomizer,
List closeables) {
tracerProviderBuilder.setSpanLimits(configureSpanLimits(config));
String sampler = config.getString("otel.traces.sampler", PARENTBASED_ALWAYS_ON);
tracerProviderBuilder.setSampler(
samplerCustomizer.apply(configureSampler(sampler, config, spiHelper), config));
Map exportersByName =
SpanExporterConfiguration.configureSpanExporters(
config, spiHelper, spanExporterCustomizer, closeables);
List processors =
configureSpanProcessors(config, exportersByName, meterProvider, closeables);
for (SpanProcessor processor : processors) {
SpanProcessor wrapped = spanProcessorCustomizer.apply(processor, config);
if (wrapped != processor) {
closeables.add(wrapped);
}
tracerProviderBuilder.addSpanProcessor(wrapped);
}
}
static List configureSpanProcessors(
ConfigProperties config,
Map exportersByName,
MeterProvider meterProvider,
List closeables) {
Map exportersByNameCopy = new HashMap<>(exportersByName);
List spanProcessors = new ArrayList<>();
for (String simpleProcessorExporterNames : simpleProcessorExporterNames) {
SpanExporter exporter = exportersByNameCopy.remove(simpleProcessorExporterNames);
if (exporter != null) {
SpanProcessor spanProcessor = SimpleSpanProcessor.create(exporter);
closeables.add(spanProcessor);
spanProcessors.add(spanProcessor);
}
}
if (!exportersByNameCopy.isEmpty()) {
SpanExporter compositeSpanExporter = SpanExporter.composite(exportersByNameCopy.values());
SpanProcessor spanProcessor =
configureBatchSpanProcessor(config, compositeSpanExporter, meterProvider);
closeables.add(spanProcessor);
spanProcessors.add(spanProcessor);
}
return spanProcessors;
}
// VisibleForTesting
static BatchSpanProcessor configureBatchSpanProcessor(
ConfigProperties config, SpanExporter exporter, MeterProvider meterProvider) {
BatchSpanProcessorBuilder builder =
BatchSpanProcessor.builder(exporter).setMeterProvider(meterProvider);
Duration scheduleDelay = config.getDuration("otel.bsp.schedule.delay");
if (scheduleDelay != null) {
builder.setScheduleDelay(scheduleDelay);
}
Integer maxQueue = config.getInt("otel.bsp.max.queue.size");
if (maxQueue != null) {
builder.setMaxQueueSize(maxQueue);
}
Integer maxExportBatch = config.getInt("otel.bsp.max.export.batch.size");
if (maxExportBatch != null) {
builder.setMaxExportBatchSize(maxExportBatch);
}
Duration timeout = config.getDuration("otel.bsp.export.timeout");
if (timeout != null) {
builder.setExporterTimeout(timeout);
}
return builder.build();
}
// Visible for testing
static SpanLimits configureSpanLimits(ConfigProperties config) {
SpanLimitsBuilder builder = SpanLimits.builder();
Integer maxAttrLength = config.getInt("otel.attribute.value.length.limit");
if (maxAttrLength != null) {
builder.setMaxAttributeValueLength(maxAttrLength);
}
Integer maxSpanAttrLength = config.getInt("otel.span.attribute.value.length.limit");
if (maxSpanAttrLength != null) {
builder.setMaxAttributeValueLength(maxSpanAttrLength);
}
Integer maxAttrs = config.getInt("otel.attribute.count.limit");
if (maxAttrs != null) {
builder.setMaxNumberOfAttributes(maxAttrs);
builder.setMaxNumberOfAttributesPerEvent(maxAttrs);
builder.setMaxNumberOfAttributesPerLink(maxAttrs);
}
Integer maxSpanAttrs = config.getInt("otel.span.attribute.count.limit");
if (maxSpanAttrs != null) {
builder.setMaxNumberOfAttributes(maxSpanAttrs);
}
Integer maxEvents = config.getInt("otel.span.event.count.limit");
if (maxEvents != null) {
builder.setMaxNumberOfEvents(maxEvents);
}
Integer maxLinks = config.getInt("otel.span.link.count.limit");
if (maxLinks != null) {
builder.setMaxNumberOfLinks(maxLinks);
}
return builder.build();
}
// Visible for testing
static Sampler configureSampler(String sampler, ConfigProperties config, SpiHelper spiHelper) {
NamedSpiManager spiSamplersManager =
spiHelper.loadConfigurable(
ConfigurableSamplerProvider.class,
ConfigurableSamplerProvider::getName,
ConfigurableSamplerProvider::createSampler,
config);
switch (sampler) {
case "always_on":
return Sampler.alwaysOn();
case "always_off":
return Sampler.alwaysOff();
case "traceidratio":
return ratioSampler(config);
case PARENTBASED_ALWAYS_ON:
return Sampler.parentBased(Sampler.alwaysOn());
case "parentbased_always_off":
return Sampler.parentBased(Sampler.alwaysOff());
case "parentbased_traceidratio":
return Sampler.parentBased(ratioSampler(config));
case "parentbased_jaeger_remote":
Sampler jaegerRemote = spiSamplersManager.getByName("jaeger_remote");
if (jaegerRemote == null) {
throw new ConfigurationException(
"parentbased_jaeger_remote configured but opentelemetry-sdk-extension-jaeger-remote-sampler not on classpath");
}
return Sampler.parentBased(jaegerRemote);
default:
Sampler spiSampler = spiSamplersManager.getByName(sampler);
if (spiSampler == null) {
throw new ConfigurationException(
"Unrecognized value for otel.traces.sampler: " + sampler);
}
return spiSampler;
}
}
private static Sampler ratioSampler(ConfigProperties config) {
double ratio = config.getDouble("otel.traces.sampler.arg", DEFAULT_TRACEIDRATIO_SAMPLE_RATIO);
return Sampler.traceIdRatioBased(ratio);
}
private TracerProviderConfiguration() {}
}