Logs customizer (#4148)

This commit is contained in:
jack-berg 2022-02-04 10:11:56 -06:00 committed by GitHub
parent 5d2c59f839
commit eb92539f94
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
13 changed files with 282 additions and 62 deletions

View File

@ -1,6 +1,8 @@
Comparing source compatibility of against
***! MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer (not serializable)
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
+++! NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer addLogEmitterProviderCustomizer(java.util.function.BiFunction)
+++! NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer addLogExporterCustomizer(java.util.function.BiFunction)
+++! NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer addMeterProviderCustomizer(java.util.function.BiFunction)
+++! NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer addMetricExporterCustomizer(java.util.function.BiFunction)
+++! NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer addTracerProviderCustomizer(java.util.function.BiFunction)

View File

@ -12,4 +12,7 @@ dependencies {
// implementation dependency to require users to add the artifact directly to their build to use
// SdkMeterProviderBuilder.
implementation(project(":sdk:metrics"))
// implementation dependency to require users to add the artifact directly to their build to use
// SdkLogEmitterProviderBuilder.
implementation(project(":sdk:logs"))
}

View File

@ -6,6 +6,8 @@
package io.opentelemetry.sdk.autoconfigure.spi;
import io.opentelemetry.context.propagation.TextMapPropagator;
import io.opentelemetry.sdk.logs.SdkLogEmitterProviderBuilder;
import io.opentelemetry.sdk.logs.export.LogExporter;
import io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder;
import io.opentelemetry.sdk.metrics.export.MetricExporter;
import io.opentelemetry.sdk.resources.Resource;
@ -106,4 +108,28 @@ public interface AutoConfigurationCustomizer {
exporterCustomizer) {
return this;
}
/**
* Adds a {@link BiFunction} to invoke the with the {@link SdkLogEmitterProviderBuilder} to allow
* customization. The return value of the {@link BiFunction} will replace the passed-in argument.
*
* <p>Multiple calls will execute the customizers in order.
*/
default AutoConfigurationCustomizer addLogEmitterProviderCustomizer(
BiFunction<SdkLogEmitterProviderBuilder, ConfigProperties, SdkLogEmitterProviderBuilder>
meterProviderCustomizer) {
return this;
}
/**
* Adds a {@link BiFunction} to invoke with the default autoconfigured {@link LogExporter} to
* allow customization. The return value of the {@link BiFunction} will replace the passed-in
* argument.
*
* <p>Multiple calls will execute the customizers in order.
*/
default AutoConfigurationCustomizer addLogExporterCustomizer(
BiFunction<? super LogExporter, ConfigProperties, ? extends LogExporter> exporterCustomizer) {
return this;
}
}

View File

@ -17,6 +17,8 @@ import io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizerProvide
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import io.opentelemetry.sdk.common.CompletableResultCode;
import io.opentelemetry.sdk.logs.SdkLogEmitterProvider;
import io.opentelemetry.sdk.logs.SdkLogEmitterProviderBuilder;
import io.opentelemetry.sdk.logs.export.LogExporter;
import io.opentelemetry.sdk.metrics.SdkMeterProvider;
import io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder;
import io.opentelemetry.sdk.metrics.export.MetricExporter;
@ -64,6 +66,11 @@ public final class AutoConfiguredOpenTelemetrySdkBuilder implements AutoConfigur
private BiFunction<? super MetricExporter, ConfigProperties, ? extends MetricExporter>
metricExporterCustomizer = (a, unused) -> a;
private BiFunction<SdkLogEmitterProviderBuilder, ConfigProperties, SdkLogEmitterProviderBuilder>
logEmitterProviderCustomizer = (a, unused) -> a;
private BiFunction<? super LogExporter, ConfigProperties, ? extends LogExporter>
logExporterCustomizer = (a, unused) -> a;
private BiFunction<? super Resource, ConfigProperties, ? extends Resource> resourceCustomizer =
(a, unused) -> a;
@ -216,6 +223,38 @@ public final class AutoConfiguredOpenTelemetrySdkBuilder implements AutoConfigur
return this;
}
/**
* Adds a {@link BiFunction} to invoke the with the {@link SdkLogEmitterProviderBuilder} to allow
* customization. The return value of the {@link BiFunction} will replace the passed-in argument.
*
* <p>Multiple calls will execute the customizers in order.
*/
@Override
public AutoConfiguredOpenTelemetrySdkBuilder addLogEmitterProviderCustomizer(
BiFunction<SdkLogEmitterProviderBuilder, ConfigProperties, SdkLogEmitterProviderBuilder>
logEmitterProviderCustomizer) {
requireNonNull(logEmitterProviderCustomizer, "logEmitterProviderCustomizer");
this.logEmitterProviderCustomizer =
mergeCustomizer(this.logEmitterProviderCustomizer, logEmitterProviderCustomizer);
return this;
}
/**
* Adds a {@link BiFunction} to invoke with the default autoconfigured {@link LogExporter} to
* allow customization. The return value of the {@link BiFunction} will replace the passed-in
* argument.
*
* <p>Multiple calls will execute the customizers in order.
*/
@Override
public AutoConfiguredOpenTelemetrySdkBuilder addLogExporterCustomizer(
BiFunction<? super LogExporter, ConfigProperties, ? extends LogExporter>
logExporterCustomizer) {
requireNonNull(logExporterCustomizer, "logExporterCustomizer");
this.logExporterCustomizer = mergeCustomizer(this.logExporterCustomizer, logExporterCustomizer);
return this;
}
/**
* Control the registration of a shutdown hook to shut down the SDK when appropriate. By default,
* the shutdown hook is registered.
@ -288,9 +327,13 @@ public final class AutoConfiguredOpenTelemetrySdkBuilder implements AutoConfigur
tracerProviderBuilder = tracerProviderCustomizer.apply(tracerProviderBuilder, config);
SdkTracerProvider tracerProvider = tracerProviderBuilder.build();
SdkLogEmitterProvider logEmitterProvider =
LogEmitterProviderConfiguration.configureLogEmitterProvider(
resource, config, meterProvider);
SdkLogEmitterProviderBuilder logEmitterProviderBuilder = SdkLogEmitterProvider.builder();
logEmitterProviderBuilder.setResource(resource);
LogEmitterProviderConfiguration.configureLogEmitterProvider(
logEmitterProviderBuilder, config, meterProvider, logExporterCustomizer);
logEmitterProviderBuilder =
logEmitterProviderCustomizer.apply(logEmitterProviderBuilder, config);
SdkLogEmitterProvider logEmitterProvider = logEmitterProviderBuilder.build();
if (registerShutdownHook) {
Runtime.getRuntime()

View File

@ -10,28 +10,29 @@ import static io.opentelemetry.sdk.autoconfigure.LogExporterConfiguration.config
import io.opentelemetry.api.metrics.MeterProvider;
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
import io.opentelemetry.sdk.logs.LogProcessor;
import io.opentelemetry.sdk.logs.SdkLogEmitterProvider;
import io.opentelemetry.sdk.logs.SdkLogEmitterProviderBuilder;
import io.opentelemetry.sdk.logs.export.BatchLogProcessor;
import io.opentelemetry.sdk.logs.export.LogExporter;
import io.opentelemetry.sdk.logs.export.SimpleLogProcessor;
import io.opentelemetry.sdk.resources.Resource;
import java.util.ArrayList;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.function.BiFunction;
final class LogEmitterProviderConfiguration {
static SdkLogEmitterProvider configureLogEmitterProvider(
Resource resource, ConfigProperties config, MeterProvider meterProvider) {
SdkLogEmitterProviderBuilder builder = SdkLogEmitterProvider.builder().setResource(resource);
static void configureLogEmitterProvider(
SdkLogEmitterProviderBuilder logEmitterProviderBuilder,
ConfigProperties config,
MeterProvider meterProvider,
BiFunction<? super LogExporter, ConfigProperties, ? extends LogExporter>
logExporterCustomizer) {
Map<String, LogExporter> exportersByName =
configureLogExporters(config, meterProvider, logExporterCustomizer);
Map<String, LogExporter> exportersByName = configureLogExporters(config, meterProvider);
configureLogProcessors(exportersByName, meterProvider).forEach(builder::addLogProcessor);
return builder.build();
configureLogProcessors(exportersByName, meterProvider)
.forEach(logEmitterProviderBuilder::addLogProcessor);
}
// Visible for testing

View File

@ -23,6 +23,7 @@ import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Set;
import java.util.function.BiFunction;
import javax.annotation.Nullable;
class LogExporterConfiguration {
@ -31,7 +32,10 @@ class LogExporterConfiguration {
// Visible for test
static Map<String, LogExporter> configureLogExporters(
ConfigProperties config, MeterProvider meterProvider) {
ConfigProperties config,
MeterProvider meterProvider,
BiFunction<? super LogExporter, ConfigProperties, ? extends LogExporter>
logExporterCustomizer) {
Set<String> exporterNames = DefaultConfigProperties.getSet(config, "otel.logs.exporter");
// Default to no exporter
@ -51,7 +55,8 @@ class LogExporterConfiguration {
for (String name : exporterNames) {
LogExporter logExporter = configureExporter(name, config, meterProvider);
if (logExporter != null) {
exportersByName.put(name, logExporter);
LogExporter customizedLogExporter = logExporterCustomizer.apply(logExporter, config);
exportersByName.put(name, customizedLogExporter);
}
}

View File

@ -23,6 +23,8 @@ import io.opentelemetry.context.propagation.TextMapGetter;
import io.opentelemetry.context.propagation.TextMapPropagator;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.common.CompletableResultCode;
import io.opentelemetry.sdk.logs.LogProcessor;
import io.opentelemetry.sdk.logs.SdkLogEmitterProvider;
import io.opentelemetry.sdk.metrics.SdkMeterProvider;
import io.opentelemetry.sdk.metrics.export.MetricReader;
import io.opentelemetry.sdk.metrics.export.MetricReaderFactory;
@ -61,6 +63,7 @@ class AutoConfiguredOpenTelemetrySdkTest {
@Mock private SpanExporter spanExporter2;
@Mock private MetricReaderFactory metricReaderFactory;
@Mock private MetricReader metricReader;
@Mock private LogProcessor logProcessor;
private AutoConfiguredOpenTelemetrySdkBuilder builder;
@ -229,6 +232,26 @@ class AutoConfiguredOpenTelemetrySdkTest {
// TODO: add test for addMetricExporterCustomizer once OTLP export is enabled by default
@Test
void builder_addLogEmitterProviderCustomizer() {
Mockito.lenient().when(logProcessor.shutdown()).thenReturn(CompletableResultCode.ofSuccess());
when(logProcessor.forceFlush()).thenReturn(CompletableResultCode.ofSuccess());
SdkLogEmitterProvider sdkLogEmitterProvider =
builder
.addLogEmitterProviderCustomizer(
(logEmitterProviderBuilder, configProperties) ->
logEmitterProviderBuilder.addLogProcessor(logProcessor))
.build()
.getOpenTelemetrySdk()
.getSdkLogEmitterProvider();
sdkLogEmitterProvider.forceFlush().join(10, TimeUnit.SECONDS);
verify(logProcessor).forceFlush();
}
// TODO: add test for addLogExporterCustomizer once OTLP export is enabled by default
@Test
void builder_setResultAsGlobalFalse() {
GlobalOpenTelemetry.set(OpenTelemetry.noop());

View File

@ -7,11 +7,10 @@ package io.opentelemetry.sdk.autoconfigure;
import static org.assertj.core.api.Assertions.assertThat;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.metrics.MeterProvider;
import io.opentelemetry.sdk.logs.LogProcessor;
import io.opentelemetry.sdk.logs.SdkLogEmitterProvider;
import io.opentelemetry.sdk.resources.Resource;
import io.opentelemetry.sdk.logs.SdkLogEmitterProviderBuilder;
import java.util.Collections;
import java.util.Map;
import org.junit.jupiter.api.Test;
@ -22,22 +21,24 @@ class LogEmitterProviderConfigurationTest {
void configureLogEmitterProvider() {
Map<String, String> properties = Collections.singletonMap("otel.logs.exporter", "none");
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.
SdkLogEmitterProvider logEmitterProvider =
LogEmitterProviderConfiguration.configureLogEmitterProvider(
resource, DefaultConfigProperties.createForTest(properties), MeterProvider.noop());
SdkLogEmitterProviderBuilder builder = SdkLogEmitterProvider.builder();
LogEmitterProviderConfiguration.configureLogEmitterProvider(
builder,
DefaultConfigProperties.createForTest(properties),
MeterProvider.noop(),
(a, unused) -> a);
SdkLogEmitterProvider logEmitterProvider = builder.build();
try {
assertThat(logEmitterProvider)
.extracting("sharedState")
.satisfies(
sharedState -> {
assertThat(sharedState).extracting("resource").isEqualTo(resource);
assertThat(sharedState)
.extracting("logProcessor")
.isEqualTo(LogProcessor.composite());
});
sharedState ->
assertThat(sharedState)
.extracting("logProcessor")
.isEqualTo(LogProcessor.composite()));
} finally {
logEmitterProvider.shutdown();
}

View File

@ -21,7 +21,9 @@ class LogExporterConfigurationTest {
DefaultConfigProperties.createForTest(ImmutableMap.of("otel.logs.exporter", "otlp,otlp"));
assertThatThrownBy(
() -> LogExporterConfiguration.configureLogExporters(config, MeterProvider.noop()))
() ->
LogExporterConfiguration.configureLogExporters(
config, MeterProvider.noop(), (a, unused) -> a))
.isInstanceOf(ConfigurationException.class)
.hasMessageContaining("otel.logs.exporter contains duplicates: [otlp]");
}
@ -32,7 +34,9 @@ class LogExporterConfigurationTest {
DefaultConfigProperties.createForTest(ImmutableMap.of("otel.logs.exporter", "foo"));
assertThatThrownBy(
() -> LogExporterConfiguration.configureLogExporters(config, MeterProvider.noop()))
() ->
LogExporterConfiguration.configureLogExporters(
config, MeterProvider.noop(), (a, unused) -> a))
.isInstanceOf(ConfigurationException.class)
.hasMessageContaining("Unrecognized value for otel.logs.exporter: foo");
}
@ -43,7 +47,9 @@ class LogExporterConfigurationTest {
DefaultConfigProperties.createForTest(ImmutableMap.of("otel.logs.exporter", "otlp,none"));
assertThatThrownBy(
() -> LogExporterConfiguration.configureLogExporters(config, MeterProvider.noop()))
() ->
LogExporterConfiguration.configureLogExporters(
config, MeterProvider.noop(), (a, unused) -> a))
.isInstanceOf(ConfigurationException.class)
.hasMessageContaining("otel.logs.exporter contains none along with other exporters");
}

View File

@ -23,6 +23,9 @@ import io.opentelemetry.extension.aws.AwsXrayPropagator;
import io.opentelemetry.extension.trace.propagation.B3Propagator;
import io.opentelemetry.extension.trace.propagation.JaegerPropagator;
import io.opentelemetry.extension.trace.propagation.OtTracePropagator;
import io.opentelemetry.proto.collector.logs.v1.ExportLogsServiceRequest;
import io.opentelemetry.proto.collector.logs.v1.ExportLogsServiceResponse;
import io.opentelemetry.proto.collector.logs.v1.LogsServiceGrpc;
import io.opentelemetry.proto.collector.metrics.v1.ExportMetricsServiceRequest;
import io.opentelemetry.proto.collector.metrics.v1.ExportMetricsServiceResponse;
import io.opentelemetry.proto.collector.metrics.v1.MetricsServiceGrpc;
@ -31,9 +34,13 @@ import io.opentelemetry.proto.collector.trace.v1.ExportTraceServiceResponse;
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.logs.v1.LogRecord;
import io.opentelemetry.proto.metrics.v1.InstrumentationLibraryMetrics;
import io.opentelemetry.proto.metrics.v1.Metric;
import io.opentelemetry.proto.metrics.v1.ResourceMetrics;
import io.opentelemetry.sdk.logs.LogEmitter;
import io.opentelemetry.sdk.logs.SdkLogEmitterProvider;
import io.opentelemetry.sdk.logs.data.Severity;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;
@ -50,6 +57,8 @@ class FullConfigTest {
new LinkedBlockingDeque<>();
private static final BlockingQueue<ExportMetricsServiceRequest> otlpMetricsRequests =
new LinkedBlockingDeque<>();
private static final BlockingQueue<ExportLogsServiceRequest> otlpLogsRequests =
new LinkedBlockingDeque<>();
@RegisterExtension
public static final ServerExtension server =
@ -103,24 +112,56 @@ class FullConfigTest {
responseObserver.onCompleted();
}
})
// OTLP logs
.addService(
new LogsServiceGrpc.LogsServiceImplBase() {
@Override
public void export(
ExportLogsServiceRequest request,
StreamObserver<ExportLogsServiceResponse> responseObserver) {
try {
RequestHeaders headers =
ServiceRequestContext.current().request().headers();
assertThat(headers.get("cat")).isEqualTo("meow");
assertThat(headers.get("dog")).isEqualTo("bark");
} catch (Throwable t) {
responseObserver.onError(t);
return;
}
if (request.getResourceLogsCount() > 0) {
otlpLogsRequests.add(request);
}
responseObserver.onNext(ExportLogsServiceResponse.getDefaultInstance());
responseObserver.onCompleted();
}
})
.useBlockingTaskExecutor(true)
.build());
sb.decorator(LoggingService.newDecorator());
}
};
private SdkLogEmitterProvider logEmitterProvider;
@BeforeEach
void setUp() {
otlpTraceRequests.clear();
otlpMetricsRequests.clear();
}
otlpLogsRequests.clear();
@Test
void configures() throws Exception {
String endpoint = "http://localhost:" + server.httpPort();
System.setProperty("otel.exporter.otlp.endpoint", endpoint);
System.setProperty("otel.exporter.otlp.timeout", "10000");
// SdkLogEmitterProvider isn't globally accessible so we initialize here to get a reference
logEmitterProvider =
AutoConfiguredOpenTelemetrySdk.initialize()
.getOpenTelemetrySdk()
.getSdkLogEmitterProvider();
}
@Test
void configures() throws Exception {
Collection<String> fields =
GlobalOpenTelemetry.get().getPropagators().getTextMapPropagator().fields();
List<String> keys = new ArrayList<>();
@ -149,6 +190,10 @@ class FullConfigTest {
meter.counterBuilder("my-metric").build().add(1);
meter.counterBuilder("my-other-metric").build().add(1);
LogEmitter logEmitter = logEmitterProvider.get("test");
logEmitter.logBuilder().setBody("debug log message").setSeverity(Severity.DEBUG).emit();
logEmitter.logBuilder().setBody("info log message").setSeverity(Severity.INFO).emit();
await().untilAsserted(() -> assertThat(otlpTraceRequests).hasSize(1));
ExportTraceServiceRequest traceRequest = otlpTraceRequests.take();
@ -222,6 +267,23 @@ class FullConfigTest {
}
}
});
await().untilAsserted(() -> assertThat(otlpLogsRequests).hasSize(1));
ExportLogsServiceRequest logRequest = otlpLogsRequests.take();
assertThat(logRequest.getResourceLogs(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());
// MetricExporterCustomizer filters logs not whose level is less than Severity.INFO
LogRecord log = logRequest.getResourceLogs(0).getInstrumentationLibraryLogs(0).getLogs(0);
assertThat(log.getBody().getStringValue()).isEqualTo("info log message");
assertThat(log.getSeverityNumberValue()).isEqualTo(Severity.INFO.getSeverityNumber());
}
private static List<KeyValue> getFirstDataPointLabels(Metric metric) {

View File

@ -8,15 +8,14 @@ package io.opentelemetry.sdk.autoconfigure;
import static org.assertj.core.api.Assertions.assertThat;
import com.google.common.collect.ImmutableMap;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.api.metrics.MeterProvider;
import io.opentelemetry.exporter.logging.SystemOutLogExporter;
import io.opentelemetry.exporter.otlp.logs.OtlpGrpcLogExporter;
import io.opentelemetry.sdk.logs.SdkLogEmitterProvider;
import io.opentelemetry.sdk.logs.SdkLogEmitterProviderBuilder;
import io.opentelemetry.sdk.logs.export.BatchLogProcessor;
import io.opentelemetry.sdk.logs.export.LogExporter;
import io.opentelemetry.sdk.logs.export.SimpleLogProcessor;
import io.opentelemetry.sdk.resources.Resource;
import java.util.Collections;
import java.util.Map;
import java.util.concurrent.ArrayBlockingQueue;
@ -29,36 +28,38 @@ class LogEmitterProviderConfigurationTest {
void configureLogEmitterProvider() {
Map<String, String> properties = Collections.singletonMap("otel.logs.exporter", "otlp");
Resource resource = Resource.create(Attributes.builder().put("cat", "meow").build());
SdkLogEmitterProvider logEmitterProvider =
LogEmitterProviderConfiguration.configureLogEmitterProvider(
resource, DefaultConfigProperties.createForTest(properties), MeterProvider.noop());
SdkLogEmitterProviderBuilder builder = SdkLogEmitterProvider.builder();
LogEmitterProviderConfiguration.configureLogEmitterProvider(
builder,
DefaultConfigProperties.createForTest(properties),
MeterProvider.noop(),
(a, unused) -> a);
SdkLogEmitterProvider logEmitterProvider = builder.build();
try {
assertThat(logEmitterProvider)
.extracting("sharedState")
.satisfies(
sharedState -> {
assertThat(sharedState).extracting("resource").isEqualTo(resource);
assertThat(sharedState)
.extracting("logProcessor")
.isInstanceOf(BatchLogProcessor.class)
.extracting("worker")
.satisfies(
worker -> {
assertThat(worker)
.extracting("scheduleDelayNanos")
.isEqualTo(TimeUnit.MILLISECONDS.toNanos(200));
assertThat(worker)
.extracting("exporterTimeoutNanos")
.isEqualTo(TimeUnit.MILLISECONDS.toNanos(30000));
assertThat(worker).extracting("maxExportBatchSize").isEqualTo(512);
assertThat(worker)
.extracting("queue")
.isInstanceOfSatisfying(
ArrayBlockingQueue.class,
queue -> assertThat(queue.remainingCapacity()).isEqualTo(2048));
});
});
sharedState ->
assertThat(sharedState)
.extracting("logProcessor")
.isInstanceOf(BatchLogProcessor.class)
.extracting("worker")
.satisfies(
worker -> {
assertThat(worker)
.extracting("scheduleDelayNanos")
.isEqualTo(TimeUnit.MILLISECONDS.toNanos(200));
assertThat(worker)
.extracting("exporterTimeoutNanos")
.isEqualTo(TimeUnit.MILLISECONDS.toNanos(30000));
assertThat(worker).extracting("maxExportBatchSize").isEqualTo(512);
assertThat(worker)
.extracting("queue")
.isInstanceOfSatisfying(
ArrayBlockingQueue.class,
queue -> assertThat(queue.remainingCapacity()).isEqualTo(2048));
}));
} finally {
logEmitterProvider.shutdown();
}

View File

@ -0,0 +1,46 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/
package io.opentelemetry.sdk.autoconfigure;
import io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizer;
import io.opentelemetry.sdk.autoconfigure.spi.AutoConfigurationCustomizerProvider;
import io.opentelemetry.sdk.common.CompletableResultCode;
import io.opentelemetry.sdk.logs.data.LogData;
import io.opentelemetry.sdk.logs.data.Severity;
import io.opentelemetry.sdk.logs.export.LogExporter;
import java.util.Collection;
import java.util.stream.Collectors;
public class LogExporterCustomizer implements AutoConfigurationCustomizerProvider {
@Override
public void customize(AutoConfigurationCustomizer autoConfiguration) {
autoConfiguration.addLogExporterCustomizer(
(delegate, config) ->
new LogExporter() {
@Override
public CompletableResultCode export(Collection<LogData> logs) {
Collection<LogData> filtered =
logs.stream()
.filter(
log ->
log.getSeverity().getSeverityNumber()
>= Severity.INFO.getSeverityNumber())
.collect(Collectors.toList());
return delegate.export(filtered);
}
@Override
public CompletableResultCode flush() {
return delegate.flush();
}
@Override
public CompletableResultCode shutdown() {
return delegate.shutdown();
}
});
}
}

View File

@ -1,2 +1,3 @@
io.opentelemetry.sdk.autoconfigure.SpanExporterCustomizer
io.opentelemetry.sdk.autoconfigure.MetricExporterCustomizer
io.opentelemetry.sdk.autoconfigure.MetricExporterCustomizer
io.opentelemetry.sdk.autoconfigure.LogExporterCustomizer