Add support for BatchLogRecordProcessor autoconfiguration (#4811)
This commit is contained in:
		
							parent
							
								
									7e1119731a
								
							
						
					
					
						commit
						99dbcaf3c6
					
				| 
						 | 
				
			
			@ -11,8 +11,10 @@ environment variables, e.g., `OTEL_TRACES_EXPORTER=zipkin`.
 | 
			
		|||
## Contents
 | 
			
		||||
 | 
			
		||||
* [General notes](#general-notes)
 | 
			
		||||
* [Disabling OpenTelemetrySdk](#disabling-opentelemetrysdk)
 | 
			
		||||
* [Exporters](#exporters)
 | 
			
		||||
  + [OTLP exporter (span, metric, and log exporters)](#otlp-exporter-span-metric-and-log-exporters)
 | 
			
		||||
    + [OTLP exporter retry](#otlp-exporter-retry)
 | 
			
		||||
  + [Jaeger exporter](#jaeger-exporter)
 | 
			
		||||
  + [Zipkin exporter](#zipkin-exporter)
 | 
			
		||||
  + [Prometheus exporter](#prometheus-exporter)
 | 
			
		||||
| 
						 | 
				
			
			@ -23,8 +25,11 @@ environment variables, e.g., `OTEL_TRACES_EXPORTER=zipkin`.
 | 
			
		|||
  + [Disabling automatic ResourceProviders](#disabling-automatic-resourceproviders)
 | 
			
		||||
* [Batch span processor](#batch-span-processor)
 | 
			
		||||
* [Sampler](#sampler)
 | 
			
		||||
* [Attribute limits](#attribute-limits)
 | 
			
		||||
* [Span limits](#span-limits)
 | 
			
		||||
* [Exemplars](#exemplars)
 | 
			
		||||
* [Periodic Metric Reader](#periodic-metric-reader)
 | 
			
		||||
* [Batch log record processor](#batch-log-record-processor)
 | 
			
		||||
* [Customizing the OpenTelemetry SDK](#customizing-the-opentelemetry-sdk)
 | 
			
		||||
 | 
			
		||||
## General notes
 | 
			
		||||
| 
						 | 
				
			
			@ -282,6 +287,15 @@ These properties can be used to control the maximum size of spans by placing lim
 | 
			
		|||
|-----------------------------|-----------------------------|----------------------------------------------------------------------------------------------|
 | 
			
		||||
| otel.metric.export.interval | OTEL_METRIC_EXPORT_INTERVAL | The interval, in milliseconds, between the start of two export attempts. Default is `60000`. |
 | 
			
		||||
 | 
			
		||||
## Batch log record processor
 | 
			
		||||
 | 
			
		||||
| System property                 | Environment variable            | Description                                                                        |
 | 
			
		||||
|---------------------------------|---------------------------------|------------------------------------------------------------------------------------|
 | 
			
		||||
| otel.blrp.schedule.delay        | OTEL_BLRP_SCHEDULE_DELAY        | The interval, in milliseconds, between two consecutive exports. Default is `5000`. |
 | 
			
		||||
| otel.blrp.max.queue.size        | OTEL_BLRP_MAX_QUEUE_SIZE        | The maximum queue size. Default is `2048`.                                         |
 | 
			
		||||
| otel.blrp.max.export.batch.size | OTEL_BLRP_MAX_EXPORT_BATCH_SIZE | The maximum batch size. Default is `512`.                                          |
 | 
			
		||||
| otel.blrp.export.timeout        | OTEL_BLRP_EXPORT_TIMEOUT        | The maximum allowed time, in milliseconds, to export data. Default is `30000`.     |
 | 
			
		||||
 | 
			
		||||
## Customizing the OpenTelemetry SDK
 | 
			
		||||
 | 
			
		||||
Autoconfiguration exposes SPI [hooks](../autoconfigure-spi/src/main/java/io/opentelemetry/sdk/autoconfigure/spi) for customizing behavior programmatically as needed.
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -25,7 +25,7 @@ dependencies {
 | 
			
		|||
 | 
			
		||||
  annotationProcessor("com.google.auto.value:auto-value")
 | 
			
		||||
 | 
			
		||||
  testImplementation(project(path = ":sdk:trace-shaded-deps"))
 | 
			
		||||
  testImplementation(project(":sdk:trace-shaded-deps"))
 | 
			
		||||
 | 
			
		||||
  testImplementation(project(":sdk:testing"))
 | 
			
		||||
  testImplementation("com.linecorp.armeria:armeria-junit5")
 | 
			
		||||
| 
						 | 
				
			
			@ -86,6 +86,7 @@ testing {
 | 
			
		|||
        implementation(project(":exporters:zipkin"))
 | 
			
		||||
        implementation(project(":sdk-extensions:resources"))
 | 
			
		||||
        implementation(project(":sdk:testing"))
 | 
			
		||||
        implementation(project(":sdk:trace-shaded-deps"))
 | 
			
		||||
        implementation(project(":semconv"))
 | 
			
		||||
 | 
			
		||||
        implementation("com.google.guava:guava")
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -14,8 +14,10 @@ import io.opentelemetry.sdk.logs.LogLimitsBuilder;
 | 
			
		|||
import io.opentelemetry.sdk.logs.LogRecordProcessor;
 | 
			
		||||
import io.opentelemetry.sdk.logs.SdkLoggerProviderBuilder;
 | 
			
		||||
import io.opentelemetry.sdk.logs.export.BatchLogRecordProcessor;
 | 
			
		||||
import io.opentelemetry.sdk.logs.export.BatchLogRecordProcessorBuilder;
 | 
			
		||||
import io.opentelemetry.sdk.logs.export.LogRecordExporter;
 | 
			
		||||
import io.opentelemetry.sdk.logs.export.SimpleLogRecordProcessor;
 | 
			
		||||
import java.time.Duration;
 | 
			
		||||
import java.util.ArrayList;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.List;
 | 
			
		||||
| 
						 | 
				
			
			@ -38,13 +40,15 @@ final class LoggerProviderConfiguration {
 | 
			
		|||
        configureLogRecordExporters(
 | 
			
		||||
            config, serviceClassLoader, meterProvider, logRecordExporterCustomizer);
 | 
			
		||||
 | 
			
		||||
    configureLogRecordProcessors(exportersByName, meterProvider)
 | 
			
		||||
    configureLogRecordProcessors(config, exportersByName, meterProvider)
 | 
			
		||||
        .forEach(loggerProviderBuilder::addLogRecordProcessor);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Visible for testing
 | 
			
		||||
  static List<LogRecordProcessor> configureLogRecordProcessors(
 | 
			
		||||
      Map<String, LogRecordExporter> exportersByName, MeterProvider meterProvider) {
 | 
			
		||||
      ConfigProperties config,
 | 
			
		||||
      Map<String, LogRecordExporter> exportersByName,
 | 
			
		||||
      MeterProvider meterProvider) {
 | 
			
		||||
    Map<String, LogRecordExporter> exportersByNameCopy = new HashMap<>(exportersByName);
 | 
			
		||||
    List<LogRecordProcessor> logRecordProcessors = new ArrayList<>();
 | 
			
		||||
 | 
			
		||||
| 
						 | 
				
			
			@ -57,14 +61,41 @@ final class LoggerProviderConfiguration {
 | 
			
		|||
      LogRecordExporter compositeLogRecordExporter =
 | 
			
		||||
          LogRecordExporter.composite(exportersByNameCopy.values());
 | 
			
		||||
      logRecordProcessors.add(
 | 
			
		||||
          BatchLogRecordProcessor.builder(compositeLogRecordExporter)
 | 
			
		||||
              .setMeterProvider(meterProvider)
 | 
			
		||||
              .build());
 | 
			
		||||
          configureBatchLogRecordProcessor(config, compositeLogRecordExporter, meterProvider));
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return logRecordProcessors;
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // VisibleForTesting
 | 
			
		||||
  static BatchLogRecordProcessor configureBatchLogRecordProcessor(
 | 
			
		||||
      ConfigProperties config, LogRecordExporter exporter, MeterProvider meterProvider) {
 | 
			
		||||
    BatchLogRecordProcessorBuilder builder =
 | 
			
		||||
        BatchLogRecordProcessor.builder(exporter).setMeterProvider(meterProvider);
 | 
			
		||||
 | 
			
		||||
    Duration scheduleDelay = config.getDuration("otel.blrp.schedule.delay");
 | 
			
		||||
    if (scheduleDelay != null) {
 | 
			
		||||
      builder.setScheduleDelay(scheduleDelay);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Integer maxQueue = config.getInt("otel.blrp.max.queue.size");
 | 
			
		||||
    if (maxQueue != null) {
 | 
			
		||||
      builder.setMaxQueueSize(maxQueue);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Integer maxExportBatch = config.getInt("otel.blrp.max.export.batch.size");
 | 
			
		||||
    if (maxExportBatch != null) {
 | 
			
		||||
      builder.setMaxExportBatchSize(maxExportBatch);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    Duration timeout = config.getDuration("otel.blrp.export.timeout");
 | 
			
		||||
    if (timeout != null) {
 | 
			
		||||
      builder.setExporterTimeout(timeout);
 | 
			
		||||
    }
 | 
			
		||||
 | 
			
		||||
    return builder.build();
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  // Visible for testing
 | 
			
		||||
  static LogLimits configureLogLimits(ConfigProperties config) {
 | 
			
		||||
    LogLimitsBuilder builder = LogLimits.builder();
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
| 
						 | 
				
			
			@ -16,8 +16,11 @@ import io.opentelemetry.sdk.logs.SdkLoggerProviderBuilder;
 | 
			
		|||
import io.opentelemetry.sdk.logs.export.BatchLogRecordProcessor;
 | 
			
		||||
import io.opentelemetry.sdk.logs.export.LogRecordExporter;
 | 
			
		||||
import io.opentelemetry.sdk.logs.export.SimpleLogRecordProcessor;
 | 
			
		||||
import io.opentelemetry.sdk.trace.internal.JcTools;
 | 
			
		||||
import java.util.Collections;
 | 
			
		||||
import java.util.HashMap;
 | 
			
		||||
import java.util.Map;
 | 
			
		||||
import java.util.Queue;
 | 
			
		||||
import java.util.concurrent.ArrayBlockingQueue;
 | 
			
		||||
import java.util.concurrent.TimeUnit;
 | 
			
		||||
import org.junit.jupiter.api.Test;
 | 
			
		||||
| 
						 | 
				
			
			@ -73,10 +76,50 @@ class LoggerProviderConfigurationTest {
 | 
			
		|||
 | 
			
		||||
    assertThat(
 | 
			
		||||
            LoggerProviderConfiguration.configureLogRecordProcessors(
 | 
			
		||||
                DefaultConfigProperties.createForTest(Collections.emptyMap()),
 | 
			
		||||
                ImmutableMap.of("logging", loggingExporter, "otlp", otlpExporter),
 | 
			
		||||
                MeterProvider.noop()))
 | 
			
		||||
        .hasSize(2)
 | 
			
		||||
        .hasAtLeastOneElementOfType(SimpleLogRecordProcessor.class)
 | 
			
		||||
        .hasAtLeastOneElementOfType(BatchLogRecordProcessor.class);
 | 
			
		||||
  }
 | 
			
		||||
 | 
			
		||||
  @Test
 | 
			
		||||
  void configureBatchLogRecordProcessor() {
 | 
			
		||||
    Map<String, String> properties = new HashMap<>();
 | 
			
		||||
    properties.put("otel.blrp.schedule.delay", "100000");
 | 
			
		||||
    properties.put("otel.blrp.max.queue.size", "2");
 | 
			
		||||
    properties.put("otel.blrp.max.export.batch.size", "3");
 | 
			
		||||
    properties.put("otel.blrp.export.timeout", "4");
 | 
			
		||||
 | 
			
		||||
    BatchLogRecordProcessor processor =
 | 
			
		||||
        LoggerProviderConfiguration.configureBatchLogRecordProcessor(
 | 
			
		||||
            DefaultConfigProperties.createForTest(properties),
 | 
			
		||||
            SystemOutLogRecordExporter.create(),
 | 
			
		||||
            MeterProvider.noop());
 | 
			
		||||
 | 
			
		||||
    try {
 | 
			
		||||
      assertThat(processor)
 | 
			
		||||
          .extracting("worker")
 | 
			
		||||
          .satisfies(
 | 
			
		||||
              worker -> {
 | 
			
		||||
                assertThat(worker)
 | 
			
		||||
                    .extracting("scheduleDelayNanos")
 | 
			
		||||
                    .isEqualTo(TimeUnit.MILLISECONDS.toNanos(100000));
 | 
			
		||||
                assertThat(worker)
 | 
			
		||||
                    .extracting("exporterTimeoutNanos")
 | 
			
		||||
                    .isEqualTo(TimeUnit.MILLISECONDS.toNanos(4));
 | 
			
		||||
                assertThat(worker).extracting("maxExportBatchSize").isEqualTo(3);
 | 
			
		||||
                assertThat(worker)
 | 
			
		||||
                    .extracting("queue")
 | 
			
		||||
                    .isInstanceOfSatisfying(
 | 
			
		||||
                        Queue.class, queue -> assertThat(JcTools.capacity(queue)).isEqualTo(2));
 | 
			
		||||
                assertThat(worker)
 | 
			
		||||
                    .extracting("logRecordExporter")
 | 
			
		||||
                    .isInstanceOf(SystemOutLogRecordExporter.class);
 | 
			
		||||
              });
 | 
			
		||||
    } finally {
 | 
			
		||||
      processor.shutdown();
 | 
			
		||||
    }
 | 
			
		||||
  }
 | 
			
		||||
}
 | 
			
		||||
| 
						 | 
				
			
			
 | 
			
		|||
		Loading…
	
		Reference in New Issue