Skip to content

Commit

Permalink
Stabilize MetricProducer, allow custom MetricReaders (#5835)
Browse files Browse the repository at this point in the history
  • Loading branch information
jack-berg authored Sep 27, 2023
1 parent 6c8f543 commit f421ef1
Show file tree
Hide file tree
Showing 21 changed files with 242 additions and 276 deletions.
11 changes: 11 additions & 0 deletions docs/apidiffs/current_vs_latest/opentelemetry-sdk-metrics.txt
Original file line number Diff line number Diff line change
@@ -1,10 +1,21 @@
Comparing source compatibility of against
*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.metrics.export.CollectionRegistration (not serializable)
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
+++ NEW METHOD: PUBLIC(+) java.util.Collection<io.opentelemetry.sdk.metrics.data.MetricData> collectAllMetrics()
+++ NEW METHOD: PUBLIC(+) STATIC(+) io.opentelemetry.sdk.metrics.export.CollectionRegistration noop()
*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.metrics.export.MetricExporter (not serializable)
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.common.export.MemoryMode getMemoryMode()
+++ NEW INTERFACE: PUBLIC(+) ABSTRACT(+) io.opentelemetry.sdk.metrics.export.MetricProducer (not serializable)
+++ CLASS FILE FORMAT VERSION: 52.0 <- n.a.
+++ NEW SUPERCLASS: java.lang.Object
+++ NEW METHOD: PUBLIC(+) ABSTRACT(+) java.util.Collection<io.opentelemetry.sdk.metrics.data.MetricData> produce(io.opentelemetry.sdk.resources.Resource)
*** MODIFIED INTERFACE: PUBLIC ABSTRACT io.opentelemetry.sdk.metrics.export.MetricReader (not serializable)
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.common.export.MemoryMode getMemoryMode()
*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.metrics.export.PeriodicMetricReader (not serializable)
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.common.export.MemoryMode getMemoryMode()
*** MODIFIED CLASS: PUBLIC FINAL io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder (not serializable)
=== CLASS FILE FORMAT VERSION: 52.0 <- 52.0
+++ NEW METHOD: PUBLIC(+) io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder registerMetricProducer(io.opentelemetry.sdk.metrics.export.MetricProducer)
Original file line number Diff line number Diff line change
Expand Up @@ -22,7 +22,6 @@
import io.opentelemetry.sdk.metrics.data.MetricData;
import io.opentelemetry.sdk.metrics.export.CollectionRegistration;
import io.opentelemetry.sdk.metrics.export.MetricReader;
import io.opentelemetry.sdk.metrics.internal.export.MetricProducer;
import java.io.IOException;
import java.io.OutputStream;
import java.io.UncheckedIOException;
Expand Down Expand Up @@ -60,7 +59,7 @@ public final class PrometheusHttpServer implements MetricReader {

private final HttpServer server;
private final ExecutorService executor;
private volatile MetricProducer metricProducer = MetricProducer.noop();
private volatile CollectionRegistration collectionRegistration = CollectionRegistration.noop();

/**
* Returns a new {@link PrometheusHttpServer} which can be registered to an {@link
Expand All @@ -83,7 +82,7 @@ public static PrometheusHttpServerBuilder builder() {
throw new UncheckedIOException("Could not create Prometheus HTTP server", e);
}
MetricsHandler metricsHandler =
new MetricsHandler(() -> getMetricProducer().collectAllMetrics());
new MetricsHandler(() -> collectionRegistration.collectAllMetrics());
server.createContext("/", metricsHandler);
server.createContext("/metrics", metricsHandler);
server.createContext("/-/healthy", HealthHandler.INSTANCE);
Expand All @@ -110,10 +109,6 @@ private static HttpServer createServer(String host, int port) throws IOException
throw exception;
}

private MetricProducer getMetricProducer() {
return metricProducer;
}

private void start() {
// server.start must be called from a daemon thread for it to be a daemon.
if (Thread.currentThread().isDaemon()) {
Expand All @@ -131,13 +126,13 @@ private void start() {
}

@Override
public void register(CollectionRegistration registration) {
this.metricProducer = MetricProducer.asMetricProducer(registration);
public AggregationTemporality getAggregationTemporality(InstrumentType instrumentType) {
return AggregationTemporality.CUMULATIVE;
}

@Override
public AggregationTemporality getAggregationTemporality(InstrumentType instrumentType) {
return AggregationTemporality.CUMULATIVE;
public void register(CollectionRegistration registration) {
this.collectionRegistration = registration;
}

@Override
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -26,17 +26,18 @@
import io.opentelemetry.sdk.common.InstrumentationScopeInfo;
import io.opentelemetry.sdk.metrics.data.AggregationTemporality;
import io.opentelemetry.sdk.metrics.data.MetricData;
import io.opentelemetry.sdk.metrics.export.CollectionRegistration;
import io.opentelemetry.sdk.metrics.internal.data.ImmutableDoublePointData;
import io.opentelemetry.sdk.metrics.internal.data.ImmutableGaugeData;
import io.opentelemetry.sdk.metrics.internal.data.ImmutableLongPointData;
import io.opentelemetry.sdk.metrics.internal.data.ImmutableMetricData;
import io.opentelemetry.sdk.metrics.internal.data.ImmutableSumData;
import io.opentelemetry.sdk.metrics.internal.export.MetricProducer;
import io.opentelemetry.sdk.resources.Resource;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.net.ServerSocket;
import java.nio.charset.StandardCharsets;
import java.util.Collection;
import java.util.Collections;
import java.util.List;
import java.util.concurrent.Executors;
Expand All @@ -56,7 +57,6 @@

class PrometheusHttpServerTest {
private static final AtomicReference<List<MetricData>> metricData = new AtomicReference<>();
private static final MetricProducer metricProducer = metricData::get;

static PrometheusHttpServer prometheusServer;
static WebClient client;
Expand All @@ -68,7 +68,13 @@ class PrometheusHttpServerTest {
static void beforeAll() {
// Register the SDK metric producer with the prometheus reader.
prometheusServer = PrometheusHttpServer.builder().setHost("localhost").setPort(0).build();
prometheusServer.register(metricProducer);
prometheusServer.register(
new CollectionRegistration() {
@Override
public Collection<MetricData> collectAllMetrics() {
return metricData.get();
}
});

client =
WebClient.builder("http://localhost:" + prometheusServer.getAddress().getPort())
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*
* Copyright The OpenTelemetry Authors
* SPDX-License-Identifier: Apache-2.0
*/

package io.opentelemetry.opencensusshim;

import io.opencensus.metrics.Metrics;
import io.opencensus.metrics.export.MetricProducerManager;
import io.opentelemetry.opencensusshim.internal.metrics.MetricAdapter;
import io.opentelemetry.sdk.metrics.SdkMeterProviderBuilder;
import io.opentelemetry.sdk.metrics.data.MetricData;
import io.opentelemetry.sdk.metrics.export.MetricProducer;
import io.opentelemetry.sdk.metrics.export.MetricReader;
import io.opentelemetry.sdk.resources.Resource;
import java.util.ArrayList;
import java.util.Collection;
import java.util.List;

/**
* {@link MetricProducer} for OpenCensus metrics, which allows {@link MetricReader}s to read from
* both OpenTelemetry and OpenCensus metrics.
*
* <p>To use, register with {@link SdkMeterProviderBuilder#registerMetricProducer(MetricProducer)}.
*/
public final class OpenCensusMetricProducer implements MetricProducer {
private final MetricProducerManager openCensusMetricStorage;

OpenCensusMetricProducer(MetricProducerManager openCensusMetricStorage) {
this.openCensusMetricStorage = openCensusMetricStorage;
}

/**
* Constructs a new {@link OpenCensusMetricProducer} that reports against the given {@link
* Resource}.
*/
public static MetricProducer create() {
return new OpenCensusMetricProducer(Metrics.getExportComponent().getMetricProducerManager());
}

@Override
public Collection<MetricData> produce(Resource resource) {
List<MetricData> result = new ArrayList<>();
openCensusMetricStorage
.getAllMetricProducer()
.forEach(
producer ->
producer
.getMetrics()
.forEach(metric -> result.add(MetricAdapter.convert(resource, metric))));
return result;
}
}

This file was deleted.

This file was deleted.

This file was deleted.

This file was deleted.

Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@
import io.opencensus.trace.TraceOptions;
import io.opencensus.trace.Tracestate;
import io.opentelemetry.api.common.Attributes;
import io.opentelemetry.sdk.metrics.internal.export.MetricProducer;
import io.opentelemetry.opencensusshim.OpenCensusMetricProducer;
import io.opentelemetry.sdk.metrics.export.MetricProducer;
import io.opentelemetry.sdk.resources.Resource;
import java.time.Duration;
import java.util.Arrays;
Expand All @@ -31,8 +32,7 @@
import org.junit.jupiter.api.Test;

class OpenCensusMetricProducerTest {
private final MetricProducer openCensusMetrics =
OpenCensusMetricProducer.create(Resource.empty());
private final MetricProducer openCensusMetrics = OpenCensusMetricProducer.create();

private static final Measure.MeasureLong LATENCY_MS =
Measure.MeasureLong.create("task_latency", "The task latency in milliseconds", "ms");
Expand Down Expand Up @@ -69,7 +69,7 @@ void extractHistogram() throws InterruptedException {
.atMost(Duration.ofSeconds(10))
.untilAsserted(
() ->
assertThat(openCensusMetrics.collectAllMetrics())
assertThat(openCensusMetrics.produce(Resource.empty()))
.satisfiesExactly(
metric ->
assertThat(metric)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
import io.opencensus.stats.Stats;
import io.opencensus.stats.StatsRecorder;
import io.opencensus.stats.View;
import io.opentelemetry.opencensusshim.OpenCensusMetricProducer;
import io.opentelemetry.sdk.metrics.SdkMeterProvider;
import io.opentelemetry.sdk.testing.exporter.InMemoryMetricReader;
import java.time.Duration;
Expand All @@ -26,7 +27,10 @@ class OpenCensusMetricsTest {
void capturesOpenCensusAndOtelMetrics() throws InterruptedException {
InMemoryMetricReader reader = InMemoryMetricReader.create();
SdkMeterProvider otelMetrics =
SdkMeterProvider.builder().registerMetricReader(OpenCensusMetrics.attachTo(reader)).build();
SdkMeterProvider.builder()
.registerMetricReader(reader)
.registerMetricProducer(OpenCensusMetricProducer.create())
.build();
// Record an otel metric.
otelMetrics.meterBuilder("otel").build().counterBuilder("otel.sum").build().add(1);
// Record an OpenCensus metric.
Expand All @@ -47,7 +51,7 @@ void capturesOpenCensusAndOtelMetrics() throws InterruptedException {
.untilAsserted(
() ->
assertThat(reader.collectAllMetrics())
.satisfiesExactly(
.satisfiesExactlyInAnyOrder(
metric ->
assertThat(metric).hasName("otel.sum").hasLongSumSatisfying(sum -> {}),
metric ->
Expand Down
Loading

0 comments on commit f421ef1

Please sign in to comment.