Configurable temporality (#3960)

* Allow configuration of preferred temporality in LoggingMetricExporter and OtlpJsonLoggingMetricExporter

* Make InMemoryMetricReader preferred temporality configurable

* Add create() methods to LoggingSpanExporter, LoggingMetricExporter, and SystemOutLogExporter, deprecate public constructors
This commit is contained in:
jack-berg 2021-12-07 22:58:59 -06:00 committed by GitHub
parent 76ae8d21d1
commit 53030b7266
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
15 changed files with 158 additions and 23 deletions

View File

@ -1,2 +1,5 @@
Comparing source compatibility of against
No changes.
*** 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)
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.metrics.data.AggregationTemporality getPreferredTemporality()

View File

@ -1,2 +1,18 @@
Comparing source compatibility of against
No changes.
*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.logging.LoggingMetricExporter (not serializable)
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
=== UNCHANGED CONSTRUCTOR: PUBLIC LoggingMetricExporter()
+++ NEW ANNOTATION: java.lang.Deprecated
+++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.exporter.logging.LoggingMetricExporter create()
+++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.exporter.logging.LoggingMetricExporter create(io.opentelemetry.sdk.metrics.data.AggregationTemporality)
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.metrics.data.AggregationTemporality getPreferredTemporality()
*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.exporter.logging.LoggingSpanExporter (not serializable)
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
=== UNCHANGED CONSTRUCTOR: PUBLIC LoggingSpanExporter()
+++ NEW ANNOTATION: java.lang.Deprecated
+++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.exporter.logging.LoggingSpanExporter create()
*** MODIFIED CLASS: PUBLIC io.opentelemetry.exporter.logging.SystemOutLogExporter (not serializable)
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
=== UNCHANGED CONSTRUCTOR: PUBLIC SystemOutLogExporter()
+++ NEW ANNOTATION: java.lang.Deprecated
+++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.exporter.logging.SystemOutLogExporter create()

View File

@ -11,6 +11,7 @@ import com.fasterxml.jackson.core.JsonGenerator;
import com.fasterxml.jackson.core.io.SegmentedStringWriter;
import io.opentelemetry.exporter.otlp.internal.metrics.ResourceMetricsMarshaler;
import io.opentelemetry.sdk.common.CompletableResultCode;
import io.opentelemetry.sdk.metrics.data.AggregationTemporality;
import io.opentelemetry.sdk.metrics.data.MetricData;
import io.opentelemetry.sdk.metrics.export.MetricExporter;
import java.io.IOException;
@ -27,12 +28,32 @@ public final class OtlpJsonLoggingMetricExporter implements MetricExporter {
private static final Logger logger =
Logger.getLogger(OtlpJsonLoggingMetricExporter.class.getName());
/** Returns a new {@link OtlpJsonLoggingMetricExporter}. */
private final AggregationTemporality preferredTemporality;
/**
* Returns a new {@link OtlpJsonLoggingMetricExporter} with a preferred temporality of {@link
* AggregationTemporality#CUMULATIVE}.
*/
public static MetricExporter create() {
return new OtlpJsonLoggingMetricExporter();
return new OtlpJsonLoggingMetricExporter(AggregationTemporality.CUMULATIVE);
}
private OtlpJsonLoggingMetricExporter() {}
/**
* Returns a new {@link OtlpJsonLoggingMetricExporter} with the given {@code
* preferredTemporality}.
*/
public static MetricExporter create(AggregationTemporality preferredTemporality) {
return new OtlpJsonLoggingMetricExporter(preferredTemporality);
}
private OtlpJsonLoggingMetricExporter(AggregationTemporality preferredTemporality) {
this.preferredTemporality = preferredTemporality;
}
@Override
public AggregationTemporality getPreferredTemporality() {
return preferredTemporality;
}
@Override
public CompletableResultCode export(Collection<MetricData> metrics) {

View File

@ -65,6 +65,16 @@ class OtlpJsonLoggingMetricExporterTest {
exporter = OtlpJsonLoggingMetricExporter.create();
}
@Test
void preferredTemporality() {
assertThat(OtlpJsonLoggingMetricExporter.create().getPreferredTemporality())
.isEqualTo(AggregationTemporality.CUMULATIVE);
assertThat(
OtlpJsonLoggingMetricExporter.create(AggregationTemporality.DELTA)
.getPreferredTemporality())
.isEqualTo(AggregationTemporality.DELTA);
}
@Test
void log() throws Exception {
exporter.export(Arrays.asList(METRIC1, METRIC2));

View File

@ -6,6 +6,7 @@
package io.opentelemetry.exporter.logging;
import io.opentelemetry.sdk.common.CompletableResultCode;
import io.opentelemetry.sdk.metrics.data.AggregationTemporality;
import io.opentelemetry.sdk.metrics.data.MetricData;
import io.opentelemetry.sdk.metrics.export.MetricExporter;
import java.util.Collection;
@ -16,6 +17,40 @@ import java.util.logging.Logger;
public final class LoggingMetricExporter implements MetricExporter {
private static final Logger logger = Logger.getLogger(LoggingMetricExporter.class.getName());
private final AggregationTemporality preferredTemporality;
/**
* Returns a new {@link LoggingMetricExporter} with a preferred temporality of {@link
* AggregationTemporality#CUMULATIVE}.
*/
public static LoggingMetricExporter create() {
return create(AggregationTemporality.CUMULATIVE);
}
/** Returns a new {@link LoggingMetricExporter} with the given {@code preferredTemporality}. */
public static LoggingMetricExporter create(AggregationTemporality preferredTemporality) {
return new LoggingMetricExporter(preferredTemporality);
}
/**
* Class constructor with a preferred temporality of {@link AggregationTemporality#CUMULATIVE}.
*
* @deprecated Use {@link #create()}.
*/
@Deprecated
public LoggingMetricExporter() {
this(AggregationTemporality.CUMULATIVE);
}
private LoggingMetricExporter(AggregationTemporality preferredTemporality) {
this.preferredTemporality = preferredTemporality;
}
@Override
public AggregationTemporality getPreferredTemporality() {
return preferredTemporality;
}
@Override
public CompletableResultCode export(Collection<MetricData> metrics) {
logger.info("Received a collection of " + metrics.size() + " metrics for export.");

View File

@ -18,6 +18,19 @@ import java.util.logging.Logger;
public final class LoggingSpanExporter implements SpanExporter {
private static final Logger logger = Logger.getLogger(LoggingSpanExporter.class.getName());
/** Returns a new {@link LoggingSpanExporter}. */
public static LoggingSpanExporter create() {
return new LoggingSpanExporter();
}
/**
* Class constructor.
*
* @deprecated Use {@link #create()}.
*/
@Deprecated
public LoggingSpanExporter() {}
@Override
public CompletableResultCode export(Collection<SpanData> spans) {
// We always have 32 + 16 + name + several whitespace, 60 seems like an OK initial guess.

View File

@ -27,6 +27,19 @@ import java.util.Collection;
public class SystemOutLogExporter implements LogExporter {
private static final DateTimeFormatter ISO_FORMAT = DateTimeFormatter.ISO_DATE_TIME;
/** Returns a new {@link SystemOutLogExporter}. */
public static SystemOutLogExporter create() {
return new SystemOutLogExporter();
}
/**
* Class constructor.
*
* @deprecated Use {@link #create()}.
*/
@Deprecated
public SystemOutLogExporter() {}
@Override
public CompletableResultCode export(Collection<LogData> logs) {
StringBuilder stringBuilder = new StringBuilder(60);

View File

@ -39,7 +39,7 @@ class LoggingMetricExporterTest {
@BeforeEach
void setUp() {
exporter = new LoggingMetricExporter();
exporter = LoggingMetricExporter.create();
}
@AfterEach
@ -47,6 +47,14 @@ class LoggingMetricExporterTest {
exporter.shutdown();
}
@Test
void preferredTemporality() {
assertThat(LoggingMetricExporter.create().getPreferredTemporality())
.isEqualTo(AggregationTemporality.CUMULATIVE);
assertThat(LoggingMetricExporter.create(AggregationTemporality.DELTA).getPreferredTemporality())
.isEqualTo(AggregationTemporality.DELTA);
}
@Test
void testExport() {
long nowEpochNanos = System.currentTimeMillis() * 1000 * 1000;

View File

@ -91,7 +91,7 @@ class LoggingSpanExporterTest {
@BeforeEach
void setUp() {
exporter = new LoggingSpanExporter();
exporter = LoggingSpanExporter.create();
}
@AfterEach

View File

@ -30,7 +30,7 @@ class SystemOutLogExporterTest {
@Test
void returnCodes() {
SystemOutLogExporter exporter = new SystemOutLogExporter();
SystemOutLogExporter exporter = SystemOutLogExporter.create();
CompletableResultCode resultCode =
exporter.export(singletonList(sampleLog(System.currentTimeMillis())));
assertThat(resultCode).isSameAs(CompletableResultCode.ofSuccess());

View File

@ -75,7 +75,7 @@ final class MetricExporterConfiguration {
private static void configureLoggingMetrics(
ConfigProperties config, SdkMeterProviderBuilder sdkMeterProviderBuilder) {
configurePeriodicMetricReader(config, sdkMeterProviderBuilder, new LoggingMetricExporter());
configurePeriodicMetricReader(config, sdkMeterProviderBuilder, LoggingMetricExporter.create());
}
// Visible for testing

View File

@ -115,7 +115,7 @@ final class SpanExporterConfiguration {
"io.opentelemetry.exporter.logging.LoggingSpanExporter",
"Logging Trace Exporter",
"opentelemetry-exporter-logging");
return new LoggingSpanExporter();
return LoggingSpanExporter.create();
default:
SpanExporter spiExporter = spiExporters.get(name);
if (spiExporter == null) {

View File

@ -114,7 +114,7 @@ public class ConfigurableSpanExporterTest {
void configureSpanProcessors_simpleSpanProcessor() {
String exporterName = "logging";
Map<String, String> propMap = Collections.singletonMap("otel.traces.exporter", exporterName);
SpanExporter exporter = new LoggingSpanExporter();
SpanExporter exporter = LoggingSpanExporter.create();
ConfigProperties properties = DefaultConfigProperties.createForTest(propMap);
assertThat(
@ -177,7 +177,7 @@ public class ConfigurableSpanExporterTest {
@Test
void configureSpanProcessors_multipleExportersWithLogging() {
SpanExporter loggingExporter = new LoggingSpanExporter();
SpanExporter loggingExporter = LoggingSpanExporter.create();
SpanExporter zipkinExporter = ZipkinSpanExporter.builder().build();
ConfigProperties properties =
DefaultConfigProperties.createForTest(

View File

@ -55,17 +55,24 @@ import java.util.concurrent.ConcurrentLinkedQueue;
*/
public final class InMemoryMetricExporter implements MetricExporter {
private final Queue<MetricData> finishedMetricItems = new ConcurrentLinkedQueue<>();
private final AggregationTemporality preferredTemporality;
private boolean isStopped = false;
private InMemoryMetricExporter() {}
private InMemoryMetricExporter(AggregationTemporality preferredTemporality) {
this.preferredTemporality = preferredTemporality;
}
/**
* Returns a new instance of the {@code InMemoryMetricExporter}.
*
* @return a new instance of the {@code InMemoryMetricExporter}.
* Returns a new {@link InMemoryMetricExporter} with a preferred temporality of {@link
* AggregationTemporality#CUMULATIVE}.
*/
public static InMemoryMetricExporter create() {
return new InMemoryMetricExporter();
return create(AggregationTemporality.CUMULATIVE);
}
/** Returns a new {@link InMemoryMetricExporter} with the given {@code preferredTemporality}. */
public static InMemoryMetricExporter create(AggregationTemporality preferredTemporality) {
return new InMemoryMetricExporter(preferredTemporality);
}
/**
@ -88,7 +95,7 @@ public final class InMemoryMetricExporter implements MetricExporter {
@Override
public AggregationTemporality getPreferredTemporality() {
return AggregationTemporality.CUMULATIVE;
return preferredTemporality;
}
/**

View File

@ -43,7 +43,16 @@ class InMemoryMetricExporterTest {
}
@Test
void test_getFinishedMetricItems() {
void preferredTemporality() {
assertThat(InMemoryMetricExporter.create().getPreferredTemporality())
.isEqualTo(AggregationTemporality.CUMULATIVE);
assertThat(
InMemoryMetricExporter.create(AggregationTemporality.DELTA).getPreferredTemporality())
.isEqualTo(AggregationTemporality.DELTA);
}
@Test
void getFinishedMetricItems() {
List<MetricData> metrics = new ArrayList<MetricData>();
metrics.add(generateFakeMetric());
metrics.add(generateFakeMetric());
@ -56,7 +65,7 @@ class InMemoryMetricExporterTest {
}
@Test
void test_reset() {
void reset() {
List<MetricData> metrics = new ArrayList<MetricData>();
metrics.add(generateFakeMetric());
metrics.add(generateFakeMetric());
@ -73,7 +82,7 @@ class InMemoryMetricExporterTest {
}
@Test
void test_shutdown() {
void shutdown() {
List<MetricData> metrics = new ArrayList<MetricData>();
metrics.add(generateFakeMetric());
metrics.add(generateFakeMetric());
@ -87,7 +96,7 @@ class InMemoryMetricExporterTest {
}
@Test
void testShutdown_export() {
void shutdown_ThenExport() {
List<MetricData> metrics = new ArrayList<MetricData>();
metrics.add(generateFakeMetric());
metrics.add(generateFakeMetric());
@ -99,7 +108,7 @@ class InMemoryMetricExporterTest {
}
@Test
void test_flush() {
void flush() {
assertThat(exporter.flush().isSuccess()).isTrue();
}
}