Skip to content

Commit e009336

Browse files
authored
add logs filtering (#1823)
1 parent b3fbfe3 commit e009336

File tree

4 files changed

+150
-0
lines changed

4 files changed

+150
-0
lines changed

Diff for: processors/README.md

+4
Original file line numberDiff line numberDiff line change
@@ -28,6 +28,10 @@ logger_provider:
2828
- event_to_span_event_bridge:
2929
```
3030
31+
## Filtering Log Processor
32+
33+
`FilteringLogRecordProcessor` is a `LogRecordProcessor` that only keep logs based on a predicate
34+
3135
## Component owners
3236

3337
- [Cesar Munoz](https://github.com/LikeTheSalad), Elastic

Diff for: processors/build.gradle.kts

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

0 commit comments

Comments
 (0)