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 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 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 com.fasterxml.jackson.core.io.SegmentedStringWriter;
import io.opentelemetry.exporter.otlp.internal.metrics.ResourceMetricsMarshaler; import io.opentelemetry.exporter.otlp.internal.metrics.ResourceMetricsMarshaler;
import io.opentelemetry.sdk.common.CompletableResultCode; 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.data.MetricData;
import io.opentelemetry.sdk.metrics.export.MetricExporter; import io.opentelemetry.sdk.metrics.export.MetricExporter;
import java.io.IOException; import java.io.IOException;
@ -27,12 +28,32 @@ public final class OtlpJsonLoggingMetricExporter implements MetricExporter {
private static final Logger logger = private static final Logger logger =
Logger.getLogger(OtlpJsonLoggingMetricExporter.class.getName()); 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() { 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 @Override
public CompletableResultCode export(Collection<MetricData> metrics) { public CompletableResultCode export(Collection<MetricData> metrics) {

View File

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

View File

@ -6,6 +6,7 @@
package io.opentelemetry.exporter.logging; package io.opentelemetry.exporter.logging;
import io.opentelemetry.sdk.common.CompletableResultCode; 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.data.MetricData;
import io.opentelemetry.sdk.metrics.export.MetricExporter; import io.opentelemetry.sdk.metrics.export.MetricExporter;
import java.util.Collection; import java.util.Collection;
@ -16,6 +17,40 @@ import java.util.logging.Logger;
public final class LoggingMetricExporter implements MetricExporter { public final class LoggingMetricExporter implements MetricExporter {
private static final Logger logger = Logger.getLogger(LoggingMetricExporter.class.getName()); 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 @Override
public CompletableResultCode export(Collection<MetricData> metrics) { public CompletableResultCode export(Collection<MetricData> metrics) {
logger.info("Received a collection of " + metrics.size() + " metrics for export."); 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 { public final class LoggingSpanExporter implements SpanExporter {
private static final Logger logger = Logger.getLogger(LoggingSpanExporter.class.getName()); 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 @Override
public CompletableResultCode export(Collection<SpanData> spans) { public CompletableResultCode export(Collection<SpanData> spans) {
// We always have 32 + 16 + name + several whitespace, 60 seems like an OK initial guess. // 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 { public class SystemOutLogExporter implements LogExporter {
private static final DateTimeFormatter ISO_FORMAT = DateTimeFormatter.ISO_DATE_TIME; 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 @Override
public CompletableResultCode export(Collection<LogData> logs) { public CompletableResultCode export(Collection<LogData> logs) {
StringBuilder stringBuilder = new StringBuilder(60); StringBuilder stringBuilder = new StringBuilder(60);

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

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

View File

@ -43,7 +43,16 @@ class InMemoryMetricExporterTest {
} }
@Test @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>(); List<MetricData> metrics = new ArrayList<MetricData>();
metrics.add(generateFakeMetric()); metrics.add(generateFakeMetric());
metrics.add(generateFakeMetric()); metrics.add(generateFakeMetric());
@ -56,7 +65,7 @@ class InMemoryMetricExporterTest {
} }
@Test @Test
void test_reset() { void reset() {
List<MetricData> metrics = new ArrayList<MetricData>(); List<MetricData> metrics = new ArrayList<MetricData>();
metrics.add(generateFakeMetric()); metrics.add(generateFakeMetric());
metrics.add(generateFakeMetric()); metrics.add(generateFakeMetric());
@ -73,7 +82,7 @@ class InMemoryMetricExporterTest {
} }
@Test @Test
void test_shutdown() { void shutdown() {
List<MetricData> metrics = new ArrayList<MetricData>(); List<MetricData> metrics = new ArrayList<MetricData>();
metrics.add(generateFakeMetric()); metrics.add(generateFakeMetric());
metrics.add(generateFakeMetric()); metrics.add(generateFakeMetric());
@ -87,7 +96,7 @@ class InMemoryMetricExporterTest {
} }
@Test @Test
void testShutdown_export() { void shutdown_ThenExport() {
List<MetricData> metrics = new ArrayList<MetricData>(); List<MetricData> metrics = new ArrayList<MetricData>();
metrics.add(generateFakeMetric()); metrics.add(generateFakeMetric());
metrics.add(generateFakeMetric()); metrics.add(generateFakeMetric());
@ -99,7 +108,7 @@ class InMemoryMetricExporterTest {
} }
@Test @Test
void test_flush() { void flush() {
assertThat(exporter.flush().isSuccess()).isTrue(); assertThat(exporter.flush().isSuccess()).isTrue();
} }
} }