Skip to content

Commit

Permalink
Add log support to junit extensions (#5966)
Browse files Browse the repository at this point in the history
  • Loading branch information
jack-berg authored Nov 9, 2023
1 parent efcce14 commit b03ec3a
Show file tree
Hide file tree
Showing 5 changed files with 149 additions and 5 deletions.
Original file line number Diff line number Diff line change
@@ -1,2 +1,9 @@
Comparing source compatibility of against
No changes.
*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.testing.junit4.OpenTelemetryRule (not serializable)
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
+++ NEW METHOD: PUBLIC(+) void clearLogRecords()
+++ NEW METHOD: PUBLIC(+) java.util.List<io.opentelemetry.sdk.logs.data.LogRecordData> getLogRecords()
*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.testing.junit5.OpenTelemetryExtension (not serializable)
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
+++ NEW METHOD: PUBLIC(+) void clearLogRecords()
+++ NEW METHOD: PUBLIC(+) java.util.List<io.opentelemetry.sdk.logs.data.LogRecordData> getLogRecords()
Original file line number Diff line number Diff line change
Expand Up @@ -10,10 +10,14 @@
import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator;
import io.opentelemetry.context.propagation.ContextPropagators;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.logs.SdkLoggerProvider;
import io.opentelemetry.sdk.logs.data.LogRecordData;
import io.opentelemetry.sdk.logs.export.SimpleLogRecordProcessor;
import io.opentelemetry.sdk.metrics.SdkMeterProvider;
import io.opentelemetry.sdk.metrics.data.AggregationTemporality;
import io.opentelemetry.sdk.metrics.data.MetricData;
import io.opentelemetry.sdk.metrics.internal.SdkMeterProviderUtil;
import io.opentelemetry.sdk.testing.exporter.InMemoryLogRecordExporter;
import io.opentelemetry.sdk.testing.exporter.InMemoryMetricReader;
import io.opentelemetry.sdk.testing.exporter.InMemorySpanExporter;
import io.opentelemetry.sdk.trace.SdkTracerProvider;
Expand Down Expand Up @@ -71,27 +75,38 @@ public static OpenTelemetryRule create() {
SdkMeterProvider meterProvider =
SdkMeterProvider.builder().registerMetricReader(metricReader).build();

InMemoryLogRecordExporter logRecordExporter = InMemoryLogRecordExporter.create();

SdkLoggerProvider loggerProvider =
SdkLoggerProvider.builder()
.addLogRecordProcessor(SimpleLogRecordProcessor.create(logRecordExporter))
.build();

OpenTelemetrySdk openTelemetry =
OpenTelemetrySdk.builder()
.setPropagators(ContextPropagators.create(W3CTraceContextPropagator.getInstance()))
.setTracerProvider(tracerProvider)
.setMeterProvider(meterProvider)
.setLoggerProvider(loggerProvider)
.build();

return new OpenTelemetryRule(openTelemetry, spanExporter, metricReader);
return new OpenTelemetryRule(openTelemetry, spanExporter, metricReader, logRecordExporter);
}

private final OpenTelemetrySdk openTelemetry;
private final InMemorySpanExporter spanExporter;
private final InMemoryMetricReader metricReader;
private final InMemoryLogRecordExporter logRecordExporter;

private OpenTelemetryRule(
OpenTelemetrySdk openTelemetry,
InMemorySpanExporter spanExporter,
InMemoryMetricReader metricReader) {
InMemoryMetricReader metricReader,
InMemoryLogRecordExporter logRecordExporter) {
this.openTelemetry = openTelemetry;
this.spanExporter = spanExporter;
this.metricReader = metricReader;
this.logRecordExporter = logRecordExporter;
}

/** Returns the {@link OpenTelemetrySdk} created by this extension. */
Expand All @@ -113,6 +128,15 @@ public List<MetricData> getMetrics() {
return new ArrayList<>(metricReader.collectAllMetrics());
}

/**
* Returns all the exported {@link LogRecordData} so far.
*
* @since 1.32.0
*/
public List<LogRecordData> getLogRecords() {
return new ArrayList<>(logRecordExporter.getFinishedLogRecordItems());
}

/**
* Clears the collected exported {@link SpanData}. Consider making your test smaller instead of
* manually clearing state using this method.
Expand All @@ -130,12 +154,23 @@ public void clearMetrics() {
SdkMeterProviderUtil.resetForTest(openTelemetry.getSdkMeterProvider());
}

/**
* Clears the collected exported {@link LogRecordData}. Consider making your test smaller instead
* of manually clearing state using this method.
*
* @since 1.32.0
*/
public void clearLogRecords() {
logRecordExporter.reset();
}

@Override
protected void before() {
GlobalOpenTelemetry.resetForTest();
GlobalOpenTelemetry.set(openTelemetry);
clearSpans();
clearMetrics();
clearLogRecords();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,11 +12,15 @@
import io.opentelemetry.api.trace.propagation.W3CTraceContextPropagator;
import io.opentelemetry.context.propagation.ContextPropagators;
import io.opentelemetry.sdk.OpenTelemetrySdk;
import io.opentelemetry.sdk.logs.SdkLoggerProvider;
import io.opentelemetry.sdk.logs.data.LogRecordData;
import io.opentelemetry.sdk.logs.export.SimpleLogRecordProcessor;
import io.opentelemetry.sdk.metrics.SdkMeterProvider;
import io.opentelemetry.sdk.metrics.data.AggregationTemporality;
import io.opentelemetry.sdk.metrics.data.MetricData;
import io.opentelemetry.sdk.metrics.internal.SdkMeterProviderUtil;
import io.opentelemetry.sdk.testing.assertj.TracesAssert;
import io.opentelemetry.sdk.testing.exporter.InMemoryLogRecordExporter;
import io.opentelemetry.sdk.testing.exporter.InMemoryMetricReader;
import io.opentelemetry.sdk.testing.exporter.InMemorySpanExporter;
import io.opentelemetry.sdk.trace.SdkTracerProvider;
Expand Down Expand Up @@ -73,27 +77,38 @@ public static OpenTelemetryExtension create() {
SdkMeterProvider meterProvider =
SdkMeterProvider.builder().registerMetricReader(metricReader).build();

InMemoryLogRecordExporter logRecordExporter = InMemoryLogRecordExporter.create();

SdkLoggerProvider loggerProvider =
SdkLoggerProvider.builder()
.addLogRecordProcessor(SimpleLogRecordProcessor.create(logRecordExporter))
.build();

OpenTelemetrySdk openTelemetry =
OpenTelemetrySdk.builder()
.setPropagators(ContextPropagators.create(W3CTraceContextPropagator.getInstance()))
.setTracerProvider(tracerProvider)
.setMeterProvider(meterProvider)
.setLoggerProvider(loggerProvider)
.build();

return new OpenTelemetryExtension(openTelemetry, spanExporter, metricReader);
return new OpenTelemetryExtension(openTelemetry, spanExporter, metricReader, logRecordExporter);
}

private final OpenTelemetrySdk openTelemetry;
private final InMemorySpanExporter spanExporter;
private final InMemoryMetricReader metricReader;
private final InMemoryLogRecordExporter logRecordExporter;

private OpenTelemetryExtension(
OpenTelemetrySdk openTelemetry,
InMemorySpanExporter spanExporter,
InMemoryMetricReader metricReader) {
InMemoryMetricReader metricReader,
InMemoryLogRecordExporter logRecordExporter) {
this.openTelemetry = openTelemetry;
this.spanExporter = spanExporter;
this.metricReader = metricReader;
this.logRecordExporter = logRecordExporter;
}

/** Returns the {@link OpenTelemetrySdk} created by this extension. */
Expand All @@ -115,6 +130,15 @@ public List<MetricData> getMetrics() {
return new ArrayList<>(metricReader.collectAllMetrics());
}

/**
* Returns all the exported {@link LogRecordData} so far.
*
* @since 1.32.0
*/
public List<LogRecordData> getLogRecords() {
return new ArrayList<>(logRecordExporter.getFinishedLogRecordItems());
}

/**
* Returns a {@link TracesAssert} for asserting on the currently exported traces. This method
* requires AssertJ to be on the classpath.
Expand All @@ -140,10 +164,21 @@ public void clearMetrics() {
SdkMeterProviderUtil.resetForTest(openTelemetry.getSdkMeterProvider());
}

/**
* Clears the collected exported {@link LogRecordData}. Consider making your test smaller instead
* of manually clearing state using this method.
*
* @since 1.32.0
*/
public void clearLogRecords() {
logRecordExporter.reset();
}

@Override
public void beforeEach(ExtensionContext context) {
clearSpans();
clearMetrics();
clearLogRecords();
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@

import static org.assertj.core.api.Assertions.assertThat;

import io.opentelemetry.api.logs.Logger;
import io.opentelemetry.api.metrics.LongCounter;
import io.opentelemetry.api.metrics.Meter;
import io.opentelemetry.api.trace.Tracer;
Expand All @@ -21,11 +22,13 @@ public class OpenTelemetryRuleTest {

private Tracer tracer;
private Meter meter;
private Logger logger;

@Before
public void setup() {
tracer = otelTesting.getOpenTelemetry().getTracer("test");
meter = otelTesting.getOpenTelemetry().getMeter("test");
logger = otelTesting.getOpenTelemetry().getLogsBridge().get("test");
}

@Test
Expand Down Expand Up @@ -83,4 +86,35 @@ public void getMetricsAgain() {
.hasLongSumSatisfying(
sum -> sum.hasPointsSatisfying(point -> point.hasValue(1))));
}

@Test
public void getLogRecords() {
logger.logRecordBuilder().setBody("body").emit();

assertThat(otelTesting.getLogRecords())
.singleElement()
.satisfies(
logRecordData -> assertThat(logRecordData.getBody().asString()).isEqualTo("body"));
// Logs cleared between tests, not when retrieving
assertThat(otelTesting.getLogRecords())
.singleElement()
.satisfies(
logRecordData -> assertThat(logRecordData.getBody().asString()).isEqualTo("body"));
}

// We have two tests to verify logs get cleared up between tests.
@Test
public void getLogRecordsAgain() {
logger.logRecordBuilder().setBody("body").emit();

assertThat(otelTesting.getLogRecords())
.singleElement()
.satisfies(
logRecordData -> assertThat(logRecordData.getBody().asString()).isEqualTo("body"));
// Logs cleared between tests, not when retrieving
assertThat(otelTesting.getLogRecords())
.singleElement()
.satisfies(
logRecordData -> assertThat(logRecordData.getBody().asString()).isEqualTo("body"));
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@

import io.opentelemetry.api.GlobalOpenTelemetry;
import io.opentelemetry.api.OpenTelemetry;
import io.opentelemetry.api.logs.Logger;
import io.opentelemetry.api.metrics.LongCounter;
import io.opentelemetry.api.metrics.Meter;
import io.opentelemetry.api.trace.Span;
Expand All @@ -30,6 +31,7 @@ class OpenTelemetryExtensionTest {

private final Tracer tracer = otelTesting.getOpenTelemetry().getTracer("test");
private final Meter meter = otelTesting.getOpenTelemetry().getMeter("test");
private final Logger logger = otelTesting.getOpenTelemetry().getLogsBridge().get("test");

@Test
public void getSpans() {
Expand Down Expand Up @@ -175,6 +177,37 @@ void getMetricsAgain() {
sum -> sum.hasPointsSatisfying(point -> point.hasValue(1))));
}

@Test
public void getLogRecords() {
logger.logRecordBuilder().setBody("body").emit();

assertThat(otelTesting.getLogRecords())
.singleElement()
.satisfies(
logRecordData -> assertThat(logRecordData.getBody().asString()).isEqualTo("body"));
// Logs cleared between tests, not when retrieving
assertThat(otelTesting.getLogRecords())
.singleElement()
.satisfies(
logRecordData -> assertThat(logRecordData.getBody().asString()).isEqualTo("body"));
}

// We have two tests to verify spans get cleared up between tests.
@Test
public void getLogRecordsAgain() {
logger.logRecordBuilder().setBody("body").emit();

assertThat(otelTesting.getLogRecords())
.singleElement()
.satisfies(
logRecordData -> assertThat(logRecordData.getBody().asString()).isEqualTo("body"));
// Logs cleared between tests, not when retrieving
assertThat(otelTesting.getLogRecords())
.singleElement()
.satisfies(
logRecordData -> assertThat(logRecordData.getBody().asString()).isEqualTo("body"));
}

@Test
void afterAll() {
// Use a different instance of OpenTelemetryExtension to avoid interfering with other tests
Expand Down

0 comments on commit b03ec3a

Please sign in to comment.