Skip to content

Commit

Permalink
Add MetricProducer interface and explain how to use (#856)
Browse files Browse the repository at this point in the history
* Add MetriProducer interface and explain how to use

Signed-off-by: Bogdan Cristian Drutu <bogdandrutu@gmail.com>

* Clarify comment fro MetriExport.

Signed-off-by: Bogdan Cristian Drutu <bogdandrutu@gmail.com>

* Fix imports in pull example

Signed-off-by: Bogdan Cristian Drutu <bogdandrutu@gmail.com>
  • Loading branch information
bogdandrutu authored Feb 13, 2020
1 parent ea8f1d3 commit 3f2ad43
Show file tree
Hide file tree
Showing 3 changed files with 142 additions and 1 deletion.
Original file line number Diff line number Diff line change
Expand Up @@ -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.
*
* <p>All OpenTelemetry exporters should allow access to a {@code MetricExporter} instance.
*
* @since 0.1.0
*/
Expand Down
Original file line number Diff line number Diff line change
@@ -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<MetricData> getAllMetrics();
}
100 changes: 100 additions & 0 deletions sdk/src/main/java/io/opentelemetry/sdk/metrics/export/README.md
Original file line number Diff line number Diff line change
@@ -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<MetricData> 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<MetricProducer> 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<MetricData> metricsBuffer = new ArrayList<>();

@Override
synchronized ResultCode export(Collection<MetricData> metrics) {
metricsBuffer.addAll(metrics);
return ResultCode.SUCCESS;
}

synchronized Collection<MetricData> getAllMetrics() {
List<MetricData> ret = metricsBuffer;
metricsBuffer = new ArrayList<>();
return ret;
}
}

public final class PullExporter {
private final PullMetricExporter metricExporter;
private final Collection<MetricProducer> producers;

public PushExporter(Collection<MetricProducer> producers) {
metricExporter = new PullMetricExporter();
producers = Collections.unmodifiableCollection(new ArrayList<MetricProducer>(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.
}
}
```

0 comments on commit 3f2ad43

Please sign in to comment.