From 3f2ad43f785ecc12a8c13226942ab25b42de6f6e Mon Sep 17 00:00:00 2001 From: Bogdan Drutu Date: Thu, 13 Feb 2020 14:30:24 -0800 Subject: [PATCH] Add MetricProducer interface and explain how to use (#856) * Add MetriProducer interface and explain how to use Signed-off-by: Bogdan Cristian Drutu * Clarify comment fro MetriExport. Signed-off-by: Bogdan Cristian Drutu * Fix imports in pull example Signed-off-by: Bogdan Cristian Drutu --- .../sdk/metrics/export/MetricExporter.java | 5 +- .../sdk/metrics/export/MetricProducer.java | 38 +++++++ .../sdk/metrics/export/README.md | 100 ++++++++++++++++++ 3 files changed, 142 insertions(+), 1 deletion(-) create mode 100644 sdk/src/main/java/io/opentelemetry/sdk/metrics/export/MetricProducer.java create mode 100644 sdk/src/main/java/io/opentelemetry/sdk/metrics/export/README.md diff --git a/sdk/src/main/java/io/opentelemetry/sdk/metrics/export/MetricExporter.java b/sdk/src/main/java/io/opentelemetry/sdk/metrics/export/MetricExporter.java index a979dda2167..aeefed6e6b2 100644 --- a/sdk/src/main/java/io/opentelemetry/sdk/metrics/export/MetricExporter.java +++ b/sdk/src/main/java/io/opentelemetry/sdk/metrics/export/MetricExporter.java @@ -20,7 +20,10 @@ import java.util.Collection; /** - * Base interface that represents a metric exporter. + * {@code MetricExporter} is the interface that all "push based" metric libraries should use to + * export metrics to the OpenTelemetry exporters. + * + *

All OpenTelemetry exporters should allow access to a {@code MetricExporter} instance. * * @since 0.1.0 */ diff --git a/sdk/src/main/java/io/opentelemetry/sdk/metrics/export/MetricProducer.java b/sdk/src/main/java/io/opentelemetry/sdk/metrics/export/MetricProducer.java new file mode 100644 index 00000000000..5995143056b --- /dev/null +++ b/sdk/src/main/java/io/opentelemetry/sdk/metrics/export/MetricProducer.java @@ -0,0 +1,38 @@ +/* + * Copyright 2020, OpenTelemetry Authors + * + * Licensed under the Apache License, Version 2.0 (the "License"); + * you may not use this file except in compliance with the License. + * You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, + * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. + * See the License for the specific language governing permissions and + * limitations under the License. + */ + +package io.opentelemetry.sdk.metrics.export; + +import io.opentelemetry.sdk.metrics.data.MetricData; +import java.util.Collection; +import javax.annotation.concurrent.ThreadSafe; + +/** + * {@code MetricProducer} is the interface that all "pull based" metric libraries should implement + * in order to make data available to the OpenTelemetry exporters. + * + * @since 0.3.0 + */ +@ThreadSafe +public interface MetricProducer { + /** + * Returns a collection of produced {@link MetricData}s to be exported. + * + * @return a collection of produced {@link MetricData}s to be exported. + * @since 0.17 + */ + Collection getAllMetrics(); +} diff --git a/sdk/src/main/java/io/opentelemetry/sdk/metrics/export/README.md b/sdk/src/main/java/io/opentelemetry/sdk/metrics/export/README.md new file mode 100644 index 00000000000..1c08b9a2e9d --- /dev/null +++ b/sdk/src/main/java/io/opentelemetry/sdk/metrics/export/README.md @@ -0,0 +1,100 @@ +# OpenTelemetry metrics export framework + +The metrics world split between "pushed based" and "pull based" libraries and backends, and because +of this, the OpenTelemetry export framework needs to address all the possible combinations. + +To achieve the support for "pushed based" and "pull based" libraries the OpenTelemetry defines two +interfaces that helps with this: +* MetricProducer - is the interface that a "pull based" library should implement in order to make +data available to OpenTelemetry exporters. +* MetricExporter - is an interface that every OpenTelemetry exporter should implement in order to +allow "push based" libraries to push metrics to the backend. + +Here are some examples on how different libraries will interact with pull/push backends. + +**Push backend:** + +```java +import io.opentelemetry.sdk.metrics.export.MetricExporter; +import io.opentelemetry.sdk.metrics.export.MetricProducer; + +/** + * Simple implementation of the MetricExporter that pushes data to the backend. + */ +public final class PushMetricExporter implements MetricExporter { + @Override + ResultCode export(Collection metrics) { + // A "push based" library calls to export metrics + return pushToBackend(metrics); + } +} + +/** + * Class that periodically reads from all MetricProducers and pushes metrics using the + * PushMetricExporter. + */ +public final class PushExporter { + private final PushMetricExporter metricExporter; + // IntervalMetricReader reads metrics from all producers periodically. + private final IntervalMetricReader intervalMetricReader; + + public PushExporter(Collection producers) { + metricExporter = new PushMetricExporter(); + intervalMetricReader = + new IntervalMetricReader(producers, metricExporter, 60 /* export interval sec*/); + } + + // Can be accessed by any "push based" library to export metrics. + public MetricExporter getMetricExporter() { + return metricExporter; + } +} +``` + +**Pull backend:** + +```java +import io.opentelemetry.sdk.metrics.export.MetricExporter; +import io.opentelemetry.sdk.metrics.export.MetricProducer; +import java.util.ArrayList; +import java.util.Collections; + +/** + * Simple implementation of the MetricExporter that stores data in memory and makes them available + * via MetricProducer interface. + */ +public final class PullMetricExporter implements MetricExporter, MetricProducer { + private final List metricsBuffer = new ArrayList<>(); + + @Override + synchronized ResultCode export(Collection metrics) { + metricsBuffer.addAll(metrics); + return ResultCode.SUCCESS; + } + + synchronized Collection getAllMetrics() { + List ret = metricsBuffer; + metricsBuffer = new ArrayList<>(); + return ret; + } +} + +public final class PullExporter { + private final PullMetricExporter metricExporter; + private final Collection producers; + + public PushExporter(Collection producers) { + metricExporter = new PullMetricExporter(); + producers = Collections.unmodifiableCollection(new ArrayList(producers)); + } + + // Can be accessed by any "push based" library to export metrics. + public MetricExporter getMetricExporter() { + return metricExporter; + } + + private void OnPullRequest() { + // Iterate over all producers and the PullMetricExporter and export all metrics. + } +} +``` \ No newline at end of file