From 16d0dd9590151d0d32da04d7671ebb062d90e276 Mon Sep 17 00:00:00 2001 From: Teja Date: Fri, 27 Jun 2025 00:04:47 -0400 Subject: [PATCH 1/4] wip: low allocation marshalers for json exporters. --- .../opentelemetry-exporter-logging-otlp.txt | 10 ++++++- .../OtlpJsonLoggingLogRecordExporter.java | 19 ++++++++++++++ .../otlp/OtlpJsonLoggingMetricExporter.java | 26 +++++++++++++++++-- .../otlp/OtlpJsonLoggingSpanExporter.java | 23 ++++++++++++++-- 4 files changed, 73 insertions(+), 5 deletions(-) diff --git a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging-otlp.txt b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging-otlp.txt index e330cf8fe9a..ef5d8d65d1e 100644 --- a/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging-otlp.txt +++ b/docs/apidiffs/current_vs_latest/opentelemetry-exporter-logging-otlp.txt @@ -1,2 +1,10 @@ Comparing source compatibility of opentelemetry-exporter-logging-otlp-1.52.0-SNAPSHOT.jar against opentelemetry-exporter-logging-otlp-1.51.0.jar -No changes. \ No newline at end of file +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.logging.otlp.OtlpJsonLoggingLogRecordExporter (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.logs.export.LogRecordExporter create(boolean) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.logging.otlp.OtlpJsonLoggingMetricExporter (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.metrics.export.MetricExporter create(io.opentelemetry.sdk.metrics.data.AggregationTemporality, boolean) +*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.logging.otlp.OtlpJsonLoggingSpanExporter (not serializable) + === CLASS FILE FORMAT VERSION: 52.0 <- 52.0 + +++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.trace.export.SpanExporter create(boolean) diff --git a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingLogRecordExporter.java b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingLogRecordExporter.java index 0c00cca908e..6a5e740a8c8 100644 --- a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingLogRecordExporter.java +++ b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingLogRecordExporter.java @@ -8,6 +8,7 @@ import io.opentelemetry.exporter.logging.otlp.internal.logs.OtlpStdoutLogRecordExporter; import io.opentelemetry.exporter.logging.otlp.internal.logs.OtlpStdoutLogRecordExporterBuilder; import io.opentelemetry.sdk.common.CompletableResultCode; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.logs.data.LogRecordData; import io.opentelemetry.sdk.logs.export.LogRecordExporter; import java.util.Collection; @@ -33,6 +34,24 @@ public static LogRecordExporter create() { return new OtlpJsonLoggingLogRecordExporter(delegate); } + /** + * Returns a new {@link OtlpJsonLoggingLogRecordExporter}. + * + * @param wrapperJsonObject whether to wrap the JSON object in an outer JSON "resourceLogs" + * object. When {@code true}, uses low allocation OTLP marshalers with {@link + * MemoryMode#REUSABLE_DATA}. When {@code false}, uses {@link MemoryMode#IMMUTABLE_DATA}. + */ + public static LogRecordExporter create(boolean wrapperJsonObject) { + MemoryMode memoryMode = + wrapperJsonObject ? MemoryMode.REUSABLE_DATA : MemoryMode.IMMUTABLE_DATA; + OtlpStdoutLogRecordExporter delegate = + new OtlpStdoutLogRecordExporterBuilder(logger) + .setWrapperJsonObject(wrapperJsonObject) + .setMemoryMode(memoryMode) + .build(); + return new OtlpJsonLoggingLogRecordExporter(delegate); + } + OtlpJsonLoggingLogRecordExporter(OtlpStdoutLogRecordExporter delegate) { this.delegate = delegate; } diff --git a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingMetricExporter.java b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingMetricExporter.java index b42ef4acab7..45c24fe478f 100644 --- a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingMetricExporter.java +++ b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingMetricExporter.java @@ -8,6 +8,7 @@ import io.opentelemetry.exporter.logging.otlp.internal.metrics.OtlpStdoutMetricExporter; import io.opentelemetry.exporter.logging.otlp.internal.metrics.OtlpStdoutMetricExporterBuilder; import io.opentelemetry.sdk.common.CompletableResultCode; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.metrics.InstrumentType; import io.opentelemetry.sdk.metrics.data.AggregationTemporality; import io.opentelemetry.sdk.metrics.data.MetricData; @@ -46,6 +47,27 @@ public static MetricExporter create(AggregationTemporality aggregationTemporalit return new OtlpJsonLoggingMetricExporter(delegate, aggregationTemporality); } + /** + * Returns a new {@link OtlpJsonLoggingMetricExporter} with the given {@code + * aggregationTemporality}. + * + * @param aggregationTemporality the aggregation temporality to use + * @param wrapperJsonObject whether to wrap the JSON object in an outer JSON "resourceMetrics" + * object. When {@code true}, uses low allocation OTLP marshalers with {@link + * MemoryMode#REUSABLE_DATA}. When {@code false}, uses {@link MemoryMode#IMMUTABLE_DATA}. + */ + public static MetricExporter create( + AggregationTemporality aggregationTemporality, boolean wrapperJsonObject) { + MemoryMode memoryMode = + wrapperJsonObject ? MemoryMode.REUSABLE_DATA : MemoryMode.IMMUTABLE_DATA; + OtlpStdoutMetricExporter delegate = + new OtlpStdoutMetricExporterBuilder(logger) + .setWrapperJsonObject(wrapperJsonObject) + .setMemoryMode(memoryMode) + .build(); + return new OtlpJsonLoggingMetricExporter(delegate, aggregationTemporality); + } + OtlpJsonLoggingMetricExporter( OtlpStdoutMetricExporter delegate, AggregationTemporality aggregationTemporality) { this.delegate = delegate; @@ -53,8 +75,8 @@ public static MetricExporter create(AggregationTemporality aggregationTemporalit } @Override - public CompletableResultCode export(Collection logs) { - return delegate.export(logs); + public CompletableResultCode export(Collection metrics) { + return delegate.export(metrics); } @Override diff --git a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingSpanExporter.java b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingSpanExporter.java index 63901351326..785c55ac1dd 100644 --- a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingSpanExporter.java +++ b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingSpanExporter.java @@ -8,6 +8,7 @@ import io.opentelemetry.exporter.logging.otlp.internal.traces.OtlpStdoutSpanExporter; import io.opentelemetry.exporter.logging.otlp.internal.traces.OtlpStdoutSpanExporterBuilder; import io.opentelemetry.sdk.common.CompletableResultCode; +import io.opentelemetry.sdk.common.export.MemoryMode; import io.opentelemetry.sdk.trace.data.SpanData; import io.opentelemetry.sdk.trace.export.SpanExporter; import java.util.Collection; @@ -31,13 +32,31 @@ public static SpanExporter create() { return new OtlpJsonLoggingSpanExporter(delegate); } + /** + * Returns a new {@link OtlpJsonLoggingSpanExporter}. + * + * @param wrapperJsonObject whether to wrap the JSON object in an outer JSON "resourceSpans" + * object. When {@code true}, uses low allocation OTLP marshalers with {@link + * MemoryMode#REUSABLE_DATA}. When {@code false}, uses {@link MemoryMode#IMMUTABLE_DATA}. + */ + public static SpanExporter create(boolean wrapperJsonObject) { + MemoryMode memoryMode = + wrapperJsonObject ? MemoryMode.REUSABLE_DATA : MemoryMode.IMMUTABLE_DATA; + OtlpStdoutSpanExporter delegate = + new OtlpStdoutSpanExporterBuilder(logger) + .setWrapperJsonObject(wrapperJsonObject) + .setMemoryMode(memoryMode) + .build(); + return new OtlpJsonLoggingSpanExporter(delegate); + } + OtlpJsonLoggingSpanExporter(OtlpStdoutSpanExporter delegate) { this.delegate = delegate; } @Override - public CompletableResultCode export(Collection logs) { - return delegate.export(logs); + public CompletableResultCode export(Collection spans) { + return delegate.export(spans); } @Override From af4af1f2eeedea43b1918914bde461ae8e43fd13 Mon Sep 17 00:00:00 2001 From: Teja Date: Fri, 27 Jun 2025 00:10:03 -0400 Subject: [PATCH 2/4] polish: retaining the original naming convention. --- .../exporter/logging/otlp/OtlpJsonLoggingMetricExporter.java | 4 ++-- .../exporter/logging/otlp/OtlpJsonLoggingSpanExporter.java | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingMetricExporter.java b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingMetricExporter.java index 45c24fe478f..a9319def90b 100644 --- a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingMetricExporter.java +++ b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingMetricExporter.java @@ -75,8 +75,8 @@ public static MetricExporter create( } @Override - public CompletableResultCode export(Collection metrics) { - return delegate.export(metrics); + public CompletableResultCode export(Collection logs) { + return delegate.export(logs); } @Override diff --git a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingSpanExporter.java b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingSpanExporter.java index 785c55ac1dd..f74da49c62e 100644 --- a/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingSpanExporter.java +++ b/exporters/logging-otlp/src/main/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingSpanExporter.java @@ -55,8 +55,8 @@ public static SpanExporter create(boolean wrapperJsonObject) { } @Override - public CompletableResultCode export(Collection spans) { - return delegate.export(spans); + public CompletableResultCode export(Collection logs) { + return delegate.export(logs); } @Override From 831474335d794a5aa806148db124c76ef0496d22 Mon Sep 17 00:00:00 2001 From: Teja Date: Fri, 27 Jun 2025 00:17:01 -0400 Subject: [PATCH 3/4] polish: adding tests. --- .../OtlpJsonLoggingLogRecordExporterTest.java | 30 +++++++++ .../OtlpJsonLoggingMetricExporterTest.java | 66 +++++++++++++++++++ .../otlp/OtlpJsonLoggingSpanExporterTest.java | 30 +++++++++ 3 files changed, 126 insertions(+) diff --git a/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingLogRecordExporterTest.java b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingLogRecordExporterTest.java index 75677620dbb..7395e38430d 100644 --- a/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingLogRecordExporterTest.java +++ b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingLogRecordExporterTest.java @@ -45,6 +45,36 @@ void log() throws Exception { assertThat(message).doesNotContain("\n"); } + @Test + void logWithWrapperJsonObjectFalse() throws Exception { + // Test that wrapperJsonObject=false produces the same output as the default create() + LogRecordExporter exporterWithoutWrapper = OtlpJsonLoggingLogRecordExporter.create(false); + testDataExporter.export(exporterWithoutWrapper); + + assertThat(logs.getEvents()) + .hasSize(1) + .allSatisfy(log -> assertThat(log.getLevel()).isEqualTo(Level.INFO)); + String message = logs.getEvents().get(0).getMessage(); + String expectedJson = testDataExporter.getExpectedJson(false); + JSONAssert.assertEquals("Got \n" + message, expectedJson, message, /* strict= */ false); + assertThat(message).doesNotContain("\n"); + } + + @Test + void logWithWrapperJsonObjectTrue() throws Exception { + // Test that wrapperJsonObject=true produces wrapper format (enables low allocation) + LogRecordExporter exporterWithWrapper = OtlpJsonLoggingLogRecordExporter.create(true); + testDataExporter.export(exporterWithWrapper); + + assertThat(logs.getEvents()) + .hasSize(1) + .allSatisfy(log -> assertThat(log.getLevel()).isEqualTo(Level.INFO)); + String message = logs.getEvents().get(0).getMessage(); + String expectedJson = testDataExporter.getExpectedJson(true); + JSONAssert.assertEquals("Got \n" + message, expectedJson, message, /* strict= */ false); + assertThat(message).doesNotContain("\n"); + } + @Test void shutdown() { assertThat(exporter.shutdown().isSuccess()).isTrue(); diff --git a/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingMetricExporterTest.java b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingMetricExporterTest.java index ccbfdb26dce..496543f8f3b 100644 --- a/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingMetricExporterTest.java +++ b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingMetricExporterTest.java @@ -47,6 +47,27 @@ void getAggregationTemporality() { .isEqualTo(AggregationTemporality.DELTA); } + @Test + void getAggregationTemporalityWithWrapperJsonObject() { + // Test that the new create method with wrapperJsonObject parameter maintains correct aggregation temporality + assertThat( + OtlpJsonLoggingMetricExporter.create(AggregationTemporality.CUMULATIVE, false) + .getAggregationTemporality(InstrumentType.COUNTER)) + .isEqualTo(AggregationTemporality.CUMULATIVE); + assertThat( + OtlpJsonLoggingMetricExporter.create(AggregationTemporality.DELTA, false) + .getAggregationTemporality(InstrumentType.COUNTER)) + .isEqualTo(AggregationTemporality.DELTA); + assertThat( + OtlpJsonLoggingMetricExporter.create(AggregationTemporality.CUMULATIVE, true) + .getAggregationTemporality(InstrumentType.COUNTER)) + .isEqualTo(AggregationTemporality.CUMULATIVE); + assertThat( + OtlpJsonLoggingMetricExporter.create(AggregationTemporality.DELTA, true) + .getAggregationTemporality(InstrumentType.COUNTER)) + .isEqualTo(AggregationTemporality.DELTA); + } + @Test void log() throws Exception { testDataExporter.export(exporter); @@ -60,6 +81,51 @@ void log() throws Exception { assertThat(message).doesNotContain("\n"); } + @Test + void logWithWrapperJsonObjectFalse() throws Exception { + // Test that wrapperJsonObject=false produces the same output as the default create() + MetricExporter exporterWithoutWrapper = OtlpJsonLoggingMetricExporter.create(AggregationTemporality.CUMULATIVE, false); + testDataExporter.export(exporterWithoutWrapper); + + assertThat(logs.getEvents()) + .hasSize(1) + .allSatisfy(log -> assertThat(log.getLevel()).isEqualTo(Level.INFO)); + String message = logs.getEvents().get(0).getMessage(); + String expectedJson = testDataExporter.getExpectedJson(false); + JSONAssert.assertEquals("Got \n" + message, expectedJson, message, /* strict= */ false); + assertThat(message).doesNotContain("\n"); + } + + @Test + void logWithWrapperJsonObjectTrue() throws Exception { + // Test that wrapperJsonObject=true produces wrapper format (enables low allocation) + MetricExporter exporterWithWrapper = OtlpJsonLoggingMetricExporter.create(AggregationTemporality.CUMULATIVE, true); + testDataExporter.export(exporterWithWrapper); + + assertThat(logs.getEvents()) + .hasSize(1) + .allSatisfy(log -> assertThat(log.getLevel()).isEqualTo(Level.INFO)); + String message = logs.getEvents().get(0).getMessage(); + String expectedJson = testDataExporter.getExpectedJson(true); + JSONAssert.assertEquals("Got \n" + message, expectedJson, message, /* strict= */ false); + assertThat(message).doesNotContain("\n"); + } + + @Test + void logWithWrapperJsonObjectTrueAndDeltaTemporality() throws Exception { + // Test that wrapperJsonObject=true works with DELTA temporality too + MetricExporter exporterWithWrapper = OtlpJsonLoggingMetricExporter.create(AggregationTemporality.DELTA, true); + testDataExporter.export(exporterWithWrapper); + + assertThat(logs.getEvents()) + .hasSize(1) + .allSatisfy(log -> assertThat(log.getLevel()).isEqualTo(Level.INFO)); + String message = logs.getEvents().get(0).getMessage(); + String expectedJson = testDataExporter.getExpectedJson(true); + JSONAssert.assertEquals("Got \n" + message, expectedJson, message, /* strict= */ false); + assertThat(message).doesNotContain("\n"); + } + @Test void flush() { assertThat(exporter.flush().isSuccess()).isTrue(); diff --git a/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingSpanExporterTest.java b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingSpanExporterTest.java index ac3129f4a1c..66ed9e3b188 100644 --- a/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingSpanExporterTest.java +++ b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingSpanExporterTest.java @@ -46,6 +46,36 @@ void log() throws Exception { assertThat(message).doesNotContain("\n"); } + @Test + void logWithWrapperJsonObjectFalse() throws Exception { + // Test that wrapperJsonObject=false produces the same output as the default create() + SpanExporter exporterWithoutWrapper = OtlpJsonLoggingSpanExporter.create(false); + testDataExporter.export(exporterWithoutWrapper); + + assertThat(logs.getEvents()) + .hasSize(1) + .allSatisfy(log -> assertThat(log.getLevel()).isEqualTo(Level.INFO)); + String message = logs.getEvents().get(0).getMessage(); + String expectedJson = testDataExporter.getExpectedJson(false); + JSONAssert.assertEquals("Got \n" + message, expectedJson, message, /* strict= */ false); + assertThat(message).doesNotContain("\n"); + } + + @Test + void logWithWrapperJsonObjectTrue() throws Exception { + // Test that wrapperJsonObject=true produces wrapper format (enables low allocation) + SpanExporter exporterWithWrapper = OtlpJsonLoggingSpanExporter.create(true); + testDataExporter.export(exporterWithWrapper); + + assertThat(logs.getEvents()) + .hasSize(1) + .allSatisfy(log -> assertThat(log.getLevel()).isEqualTo(Level.INFO)); + String message = logs.getEvents().get(0).getMessage(); + String expectedJson = testDataExporter.getExpectedJson(true); + JSONAssert.assertEquals("Got \n" + message, expectedJson, message, /* strict= */ false); + assertThat(message).doesNotContain("\n"); + } + @Test void flush() { assertThat(exporter.flush().isSuccess()).isTrue(); From 09915ebcebbc1496444b5d8716ef58238c04dae1 Mon Sep 17 00:00:00 2001 From: Teja Date: Fri, 27 Jun 2025 00:21:14 -0400 Subject: [PATCH 4/4] polish: spotless apply. --- .../otlp/OtlpJsonLoggingMetricExporterTest.java | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingMetricExporterTest.java b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingMetricExporterTest.java index 496543f8f3b..69b11aa0b60 100644 --- a/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingMetricExporterTest.java +++ b/exporters/logging-otlp/src/test/java/io/opentelemetry/exporter/logging/otlp/OtlpJsonLoggingMetricExporterTest.java @@ -49,7 +49,8 @@ void getAggregationTemporality() { @Test void getAggregationTemporalityWithWrapperJsonObject() { - // Test that the new create method with wrapperJsonObject parameter maintains correct aggregation temporality + // Test that the new create method with wrapperJsonObject parameter maintains correct + // aggregation temporality assertThat( OtlpJsonLoggingMetricExporter.create(AggregationTemporality.CUMULATIVE, false) .getAggregationTemporality(InstrumentType.COUNTER)) @@ -84,7 +85,8 @@ void log() throws Exception { @Test void logWithWrapperJsonObjectFalse() throws Exception { // Test that wrapperJsonObject=false produces the same output as the default create() - MetricExporter exporterWithoutWrapper = OtlpJsonLoggingMetricExporter.create(AggregationTemporality.CUMULATIVE, false); + MetricExporter exporterWithoutWrapper = + OtlpJsonLoggingMetricExporter.create(AggregationTemporality.CUMULATIVE, false); testDataExporter.export(exporterWithoutWrapper); assertThat(logs.getEvents()) @@ -99,7 +101,8 @@ void logWithWrapperJsonObjectFalse() throws Exception { @Test void logWithWrapperJsonObjectTrue() throws Exception { // Test that wrapperJsonObject=true produces wrapper format (enables low allocation) - MetricExporter exporterWithWrapper = OtlpJsonLoggingMetricExporter.create(AggregationTemporality.CUMULATIVE, true); + MetricExporter exporterWithWrapper = + OtlpJsonLoggingMetricExporter.create(AggregationTemporality.CUMULATIVE, true); testDataExporter.export(exporterWithWrapper); assertThat(logs.getEvents()) @@ -114,7 +117,8 @@ void logWithWrapperJsonObjectTrue() throws Exception { @Test void logWithWrapperJsonObjectTrueAndDeltaTemporality() throws Exception { // Test that wrapperJsonObject=true works with DELTA temporality too - MetricExporter exporterWithWrapper = OtlpJsonLoggingMetricExporter.create(AggregationTemporality.DELTA, true); + MetricExporter exporterWithWrapper = + OtlpJsonLoggingMetricExporter.create(AggregationTemporality.DELTA, true); testDataExporter.export(exporterWithWrapper); assertThat(logs.getEvents())