Metrics exporter
Introduction
A metrics exporter must extend the abstract class MetricExporter implementing the export
method:
which for purposes of brevity is:
import java.util.Collection;
import io.opencensus.exporter.metrics.util.MetricExporter;
public void export(Collection<Metric> metrics);
The sole method export
will be used to process and translate a collection of Metric to your desired monitoring backend’s data.
Implementation
The Metric class contains a MetricDescriptor, which describes the type of metric and also contains a name, description, and units. Metric
also includes a list of TimeSeries objects that contain the metric data.
In this example, the metrics will be written to the log, which will send output to the console when running from the command line
StringBuffer sb = new StringBuffer();
for (Point p : ts.getPoints()) {
Timestamp t = p.getTimestamp();
long s = t.getSeconds();
long nanos = t.getNanos();
String line = s + "\t" + nanos + "\t" + p.getValue();
sb.append(line);
}
logger.info("Timeseries to export:\n" + sb);
The IntervalMetricReader class conveniently provides a service that runs in the background and writes out the metric values that have been received during the collection interval. It may be useful to keep a reference to it to shutdown the background thread gracefully.
Runnable example
Following the previous description, here is a ful runnable example, that we’ll run using Maven. Create the Java class in the file src/main/java/io/opencensus/examples/exporter/stats/ExampleStatsExporter.java
.
package io.opencensus.examples.exporter.stats;
import io.opencensus.common.Timestamp;
import io.opencensus.exporter.metrics.util.IntervalMetricReader;
import io.opencensus.exporter.metrics.util.MetricExporter;
import io.opencensus.exporter.metrics.util.MetricReader;
import io.opencensus.metrics.LabelKey;
import io.opencensus.metrics.LabelValue;
import io.opencensus.metrics.Metrics;
import io.opencensus.metrics.export.Metric;
import io.opencensus.metrics.export.MetricDescriptor;
import io.opencensus.metrics.export.Point;
import io.opencensus.metrics.export.TimeSeries;
import io.opencensus.stats.Aggregation;
import io.opencensus.stats.Aggregation.Distribution;
import io.opencensus.stats.BucketBoundaries;
import io.opencensus.stats.Measure.MeasureLong;
import io.opencensus.stats.Stats;
import io.opencensus.stats.StatsRecorder;
import io.opencensus.stats.View;
import io.opencensus.stats.View.Name;
import io.opencensus.stats.ViewManager;
import io.opencensus.tags.TagKey;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;
import java.util.List;
import java.util.Random;
import java.util.logging.Logger;
/**
* Example OpenCensus Stats Exporter.
*/
public final class ExampleStatsExporter extends MetricExporter {
private static final String EXAMPLE_STATS_EXPORTER = "ExampleStatsExporter";
private static final Logger logger = Logger.getLogger(ExampleStatsExporter.class.getName());
private static final MeasureLong M_LATENCY_MS =
MeasureLong.create("example/latency", "A measure to test the exporter", "ms");
private static final StatsRecorder statsRecorder = Stats.getStatsRecorder();
private final IntervalMetricReader intervalMetricReader;
/** Entry point from the command line to test the exporter. */
public static void main(String... args) {
ExampleStatsExporter exporter = ExampleStatsExporter.createAndRegister();
registerAllViews();
// Collect some data to test the exporter
Random rand = new Random();
try {
for (int i = 0; i < 100; i++) {
long latency = rand.nextInt(20); // A random value to test the exporter
statsRecorder.newMeasureMap().put(M_LATENCY_MS, latency).record();
Thread.sleep(latency);
}
exporter.stop();
} catch (InterruptedException e) {
logger.info("Got an error: " + e.getMessage());
}
}
/** Creates and registers the ExampleStatsExporter. */
public static ExampleStatsExporter createAndRegister() {
return new ExampleStatsExporter();
}
private ExampleStatsExporter() {
IntervalMetricReader.Options.Builder options = IntervalMetricReader.Options.builder();
MetricReader reader =
MetricReader.create(
MetricReader.Options.builder()
.setMetricProducerManager(Metrics.getExportComponent().getMetricProducerManager())
.setSpanName(EXAMPLE_STATS_EXPORTER)
.build());
intervalMetricReader = IntervalMetricReader.create(this, reader, options.build());
}
/**
* Exports the list of given {@link Metric} objects.
*
* @param metrics the list of {@link Metric} to be exported.
*/
@Override
public void export(Collection<Metric> metrics) {
logger.info("Exporting metrics");
for (Metric metric : metrics) {
MetricDescriptor md = metric.getMetricDescriptor();
MetricDescriptor.Type type = md.getType();
logger.info("Name: " + md.getName() + ", type: " + type);
List<LabelKey> keys = md.getLabelKeys();
StringBuffer keysSb = new StringBuffer("Keys: ");
for (LabelKey k : keys) {
keysSb.append(k.getKey() + " ");
}
logger.info("Keys: " + keysSb);
StringBuffer sb = new StringBuffer();
sb.append("Seconds\tNanos\tValue\n");
List<TimeSeries> tss = metric.getTimeSeriesList();
for (TimeSeries ts : tss) {
Timestamp start = ts.getStartTimestamp();
logger.info("Start " + start + "\n");
List<LabelValue> lvs = ts.getLabelValues();
StringBuffer lvSb = new StringBuffer("Keys: ");
for (LabelValue v : lvs) {
lvSb.append(v.getValue() + " ");
}
logger.info("Label values: " + lvSb + "\n");
for (Point p : ts.getPoints()) {
Timestamp t = p.getTimestamp();
long s = t.getSeconds();
long nanos = t.getNanos();
String line = s + "\t" + nanos + "\t" + p.getValue();
sb.append(line);
}
logger.info("Timeseries to export:\n" + sb);
}
}
}
private static void registerAllViews() {
// Defining the distribution aggregations
Aggregation latencyDistribution =
Distribution.create(BucketBoundaries.create(Arrays.asList(0.0, 5.0, 10.0, 15.0, 20.0)));
// Define the views
List<TagKey> noKeys = new ArrayList<TagKey>();
View[] views =
new View[] {
View.create(
Name.create("ocjavaexporter/latency"),
"The distribution of latencies",
M_LATENCY_MS,
latencyDistribution,
noKeys)
};
// Create the view manager
ViewManager vmgr = Stats.getViewManager();
// Then finally register the views
for (View view : views) {
vmgr.registerView(view);
}
}
public void stop() {
intervalMetricReader.stop();
}
}
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/maven-v4_0_0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>io.opencensus</groupId>
<artifactId>exporter-stats-example</artifactId>
<packaging>jar</packaging>
<version>1.0-SNAPSHOT</version>
<name>quickstart</name>
<url>http://maven.apache.org</url>
<properties>
<project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
<opencensus.version>0.19.2</opencensus.version> <!-- The OpenCensus version to use -->
</properties>
<dependencies>
<dependency>
<groupId>io.opencensus</groupId>
<artifactId>opencensus-api</artifactId>
<version>${opencensus.version}</version>
</dependency>
<dependency>
<groupId>io.opencensus</groupId>
<artifactId>opencensus-impl</artifactId>
<version>${opencensus.version}</version>
</dependency>
<dependency>
<groupId>io.opencensus</groupId>
<artifactId>opencensus-exporter-metrics-util</artifactId>
<version>${opencensus.version}</version>
</dependency>
</dependencies>
<build>
<extensions>
<extension>
<groupId>kr.motd.maven</groupId>
<artifactId>os-maven-plugin</artifactId>
<version>1.5.0.Final</version>
</extension>
</extensions>
<pluginManagement>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<version>3.7.0</version>
<configuration>
<source>1.8</source>
<target>1.8</target>
</configuration>
</plugin>
<plugin>
<groupId>org.codehaus.mojo</groupId>
<artifactId>appassembler-maven-plugin</artifactId>
<version>1.10</version>
<configuration>
<programs>
<program>
<id>ExampleStatsExporter</id>
<mainClass>io.opencensus.examples.exporter.stats.ExampleStatsExporter</mainClass>
</program>
</programs>
</configuration>
</plugin>
</plugins>
</pluginManagement>
</build>
</project>
Run the example with the command and observe the exported metrics output to the console
mvn install
mvn exec:java -Dexec.mainClass=io.opencensus.examples.exporter.stats.ExampleStatsExporter
...
INFO: Timeseries to export:
Seconds Nanos Value
1550971415 491000000 ValueDistribution{value=Distribution{count=100, sum=865.0, sumOfSquaredDeviations=3068.7500000000005, bucketOptions=ExplicitOptions{bucketBoundaries=[5.0, 10.0, 15.0, 20.0]}, buckets=[Bucket{count=25, exemplar=null}, Bucket{count=33, exemplar=null}, Bucket{count=24, exemplar=null}, Bucket{count=18, exemplar=null}, Bucket{count=0, exemplar=null}]}}
References
Name | Link |
---|---|
Exporter Utilities JavaDoc | io.opencensus.exporter.metrics.util.* |
OpenCensus JavaDoc | io.opencensus.* |
OpenCensus Java exporters | Some OpenCensus Java exporters |