Skip to content

Commit 64b31fc

Browse files
committed
add logs filtering
1 parent 40c3ab5 commit 64b31fc

File tree

4 files changed

+130
-0
lines changed

4 files changed

+130
-0
lines changed

processors/README.md

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,9 @@ logger_provider:
2727
processors:
2828
- event_to_span_event_bridge:
2929
```
30+
## Filtering Log Processor
31+
`FilteringLogRecordProcessor` is a `LogRecordProcessor` which only keeps logs if they have an associated span which is sample
32+
3033

3134
## Component owners
3235

processors/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,4 +24,5 @@ dependencies {
2424
testImplementation("io.opentelemetry:opentelemetry-sdk-testing")
2525
testImplementation("io.opentelemetry:opentelemetry-sdk-extension-autoconfigure")
2626
testImplementation("io.opentelemetry:opentelemetry-sdk-extension-incubator")
27+
testImplementation("io.opentelemetry:opentelemetry-exporter-logging")
2728
}
Lines changed: 25 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,25 @@
1+
package io.opentelemetry.contrib.filter;
2+
3+
import io.opentelemetry.context.Context;
4+
import io.opentelemetry.sdk.logs.LogRecordProcessor;
5+
import io.opentelemetry.sdk.logs.ReadWriteLogRecord;
6+
import io.opentelemetry.sdk.logs.data.LogRecordData;
7+
import java.util.function.Predicate;
8+
9+
public class FilteringLogRecordProcessor implements LogRecordProcessor {
10+
11+
public final LogRecordProcessor delegate;
12+
public final Predicate<LogRecordData> predicate;
13+
14+
public FilteringLogRecordProcessor(LogRecordProcessor delegate, Predicate<LogRecordData> predicate) {
15+
this.delegate = delegate;
16+
this.predicate = predicate;
17+
}
18+
19+
@Override
20+
public void onEmit(Context context, ReadWriteLogRecord readWriteLogRecord) {
21+
if (predicate.test(readWriteLogRecord.toLogRecordData())) {
22+
delegate.onEmit(context, readWriteLogRecord);
23+
}
24+
}
25+
}
Lines changed: 101 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,101 @@
1+
package io.opentelemetry.contrib.filter;
2+
3+
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
5+
import io.opentelemetry.api.logs.Logger;
6+
import io.opentelemetry.api.trace.Span;
7+
import io.opentelemetry.api.trace.SpanContext;
8+
import io.opentelemetry.api.trace.Tracer;
9+
import io.opentelemetry.context.Scope;
10+
import io.opentelemetry.sdk.OpenTelemetrySdk;
11+
import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdk;
12+
import io.opentelemetry.sdk.autoconfigure.AutoConfiguredOpenTelemetrySdkBuilder;
13+
import io.opentelemetry.sdk.autoconfigure.spi.ConfigProperties;
14+
import io.opentelemetry.sdk.logs.LogRecordProcessor;
15+
import io.opentelemetry.sdk.logs.SdkLoggerProvider;
16+
import io.opentelemetry.sdk.logs.SdkLoggerProviderBuilder;
17+
import io.opentelemetry.sdk.logs.data.LogRecordData;
18+
import io.opentelemetry.sdk.logs.export.SimpleLogRecordProcessor;
19+
import io.opentelemetry.sdk.testing.exporter.InMemoryLogRecordExporter;
20+
import io.opentelemetry.sdk.testing.exporter.InMemorySpanExporter;
21+
import io.opentelemetry.sdk.trace.data.SpanData;
22+
import java.util.HashMap;
23+
import java.util.List;
24+
import java.util.Map;
25+
import java.util.function.BiFunction;
26+
import org.junit.jupiter.api.BeforeEach;
27+
import org.junit.jupiter.api.Test;
28+
29+
public class FilteringLogRecordProcessorTest {
30+
31+
private final InMemoryLogRecordExporter memoryLogRecordExporter = InMemoryLogRecordExporter.create();;
32+
private final LogRecordProcessor logRecordProcessor = SimpleLogRecordProcessor.create(memoryLogRecordExporter);;
33+
private final InMemorySpanExporter spansExporter = InMemorySpanExporter.create();
34+
private AutoConfiguredOpenTelemetrySdkBuilder sdkBuilder ;
35+
private Logger logger;
36+
37+
38+
@BeforeEach
39+
void setUp() {
40+
sdkBuilder = AutoConfiguredOpenTelemetrySdk.builder();
41+
sdkBuilder.addPropertiesSupplier(()->{
42+
Map<String, String> configMap = new HashMap<>();
43+
configMap.put("otel.metrics.exporter", "none");
44+
configMap.put("otel.traces.exporter", "logging");
45+
configMap.put("otel.logs.exporter", "logging");
46+
return configMap;
47+
})
48+
.addSpanExporterCustomizer((exporter,c)->spansExporter)
49+
.addLogRecordExporterCustomizer(
50+
(logRecordExporter, configProperties) -> memoryLogRecordExporter)
51+
.addLoggerProviderCustomizer(
52+
new BiFunction<SdkLoggerProviderBuilder, ConfigProperties, SdkLoggerProviderBuilder>() {
53+
@Override
54+
public SdkLoggerProviderBuilder apply(
55+
SdkLoggerProviderBuilder sdkLoggerProviderBuilder,
56+
ConfigProperties configProperties) {
57+
return sdkLoggerProviderBuilder.addLogRecordProcessor(new FilteringLogRecordProcessor(
58+
logRecordProcessor, logRecordData -> logRecordData.getSpanContext().isSampled()));
59+
}
60+
});
61+
62+
logger =
63+
SdkLoggerProvider.builder()
64+
.addLogRecordProcessor(new FilteringLogRecordProcessor(logRecordProcessor,
65+
logRecordData -> {
66+
SpanContext spanContext =logRecordData.getSpanContext();
67+
return spanContext.isSampled();
68+
}) {})
69+
.build()
70+
.get("TestScope");
71+
}
72+
73+
@Test
74+
void verifyLogFilteringExistSpanContext() {
75+
76+
try (OpenTelemetrySdk sdk = sdkBuilder.build().getOpenTelemetrySdk()) {
77+
Tracer tracer = sdk.getTracer("test");
78+
Span span = tracer.spanBuilder("test").startSpan();
79+
sdk.getLogsBridge().get("test").logRecordBuilder().setBody("One Log").emit();
80+
List<LogRecordData> finishedLogRecordItems = memoryLogRecordExporter.getFinishedLogRecordItems();
81+
assertEquals(1, finishedLogRecordItems.size());
82+
try (Scope scope = span.makeCurrent()) {
83+
84+
} finally {
85+
span.end();
86+
}
87+
List<SpanData> finishedSpans = spansExporter.getFinishedSpanItems();
88+
assertEquals(1, finishedSpans.size());
89+
}
90+
}
91+
92+
@Test
93+
void verifyFilteringNotExitSpanContext() {
94+
logger.logRecordBuilder().setBody("One Log").emit();
95+
List<LogRecordData> finishedLogRecordItems = memoryLogRecordExporter.getFinishedLogRecordItems();
96+
assertEquals(0,finishedLogRecordItems.size());
97+
98+
}
99+
100+
101+
}

0 commit comments

Comments
 (0)