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:
		
							parent
							
								
									76ae8d21d1
								
							
						
					
					
						commit
						53030b7266
					
				|  | @ -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() | ||||
|  |  | |||
|  | @ -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() | ||||
|  |  | |||
|  | @ -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) { | ||||
|  |  | |||
|  | @ -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)); | ||||
|  |  | |||
|  | @ -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."); | ||||
|  |  | |||
|  | @ -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. | ||||
|  |  | |||
|  | @ -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); | ||||
|  |  | |||
|  | @ -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; | ||||
|  |  | |||
|  | @ -91,7 +91,7 @@ class LoggingSpanExporterTest { | |||
| 
 | ||||
|   @BeforeEach | ||||
|   void setUp() { | ||||
|     exporter = new LoggingSpanExporter(); | ||||
|     exporter = LoggingSpanExporter.create(); | ||||
|   } | ||||
| 
 | ||||
|   @AfterEach | ||||
|  |  | |||
|  | @ -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()); | ||||
|  |  | |||
|  | @ -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 | ||||
|  |  | |||
|  | @ -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) { | ||||
|  |  | |||
|  | @ -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( | ||||
|  |  | |||
|  | @ -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; | ||||
|   } | ||||
| 
 | ||||
|   /** | ||||
|  |  | |||
|  | @ -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(); | ||||
|   } | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue