Add log support to junit extensions (#5966)

This commit is contained in:
jack-berg 2023-11-09 10:03:36 -06:00 committed by GitHub
parent efcce14ba9
commit b03ec3aa62
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 149 additions and 5 deletions

View File

@ -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()

View File

@ -10,10 +10,14 @@ import io.opentelemetry.api.OpenTelemetry;
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;
@ -71,27 +75,38 @@ public final class OpenTelemetryRule extends ExternalResource {
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. */
@ -113,6 +128,15 @@ public final class OpenTelemetryRule extends ExternalResource {
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.
@ -130,12 +154,23 @@ public final class OpenTelemetryRule extends ExternalResource {
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

View File

@ -12,11 +12,15 @@ import io.opentelemetry.api.OpenTelemetry;
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;
@ -73,27 +77,38 @@ public final class OpenTelemetryExtension
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. */
@ -115,6 +130,15 @@ public final class OpenTelemetryExtension
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.
@ -140,10 +164,21 @@ public final class OpenTelemetryExtension
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

View File

@ -7,6 +7,7 @@ package io.opentelemetry.sdk.testing.junit4;
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;
@ -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
@ -83,4 +86,35 @@ public class OpenTelemetryRuleTest {
.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"));
}
}

View File

@ -10,6 +10,7 @@ import static org.assertj.core.api.Assertions.assertThatThrownBy;
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;
@ -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() {
@ -175,6 +177,37 @@ class OpenTelemetryExtensionTest {
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