Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add basic metrics support #360

Merged
merged 11 commits into from
Dec 19, 2018
Prev Previous commit
Next Next commit
Add javadoc
felixbarny committed Dec 17, 2018

Verified

This commit was created on GitHub.com and signed with GitHub’s verified signature. The key has expired.
commit 35f100661808579c10e920f62fc135c4c1991523
Original file line number Diff line number Diff line change
@@ -26,23 +26,68 @@
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
* A registry for metrics.
* <p>
* Currently only holds gauges.
* There are plans to add support for histogram-based timers.
* </p>
*/
public class MetricRegistry {

private static final byte NEW_LINE = '\n';

/**
* Groups {@link MetricSet}s by their unique tags.
*/
private final ConcurrentMap<Map<String, String>, MetricSet> metricSets = new ConcurrentHashMap<>();
felixbarny marked this conversation as resolved.
Show resolved Hide resolved

/**
* Same as {@link #add(String, Map, DoubleSupplier)} but only adds the metric
* if the {@link DoubleSupplier} does not return {@link Double#NaN}
*
* @param name the name of the metric
* @param tags tags for the metric.
* Tags can be used to create different graphs based for each value of a specific tag name, using a terms aggregation.
* Note that there will be a {@link MetricSet} created for each distinct set of tags.
* @param metric this supplier will be called for every reporting cycle
* ({@link co.elastic.apm.agent.report.ReporterConfiguration#metricsInterval metrics_interval)})
* @see #add(String, Map, DoubleSupplier)
*/
public void addUnlessNan(String name, Map<String, String> tags, DoubleSupplier metric) {
if (!Double.isNaN(metric.get())) {
add(name, tags, metric);
}
}

/**
* Same as {@link #add(String, Map, DoubleSupplier)} but only adds the metric
* if the {@link DoubleSupplier} returns a positive number or zero.
*
* @param name the name of the metric
* @param tags tags for the metric.
* Tags can be used to create different graphs based for each value of a specific tag name, using a terms aggregation.
* Note that there will be a {@link MetricSet} created for each distinct set of tags.
* @param metric this supplier will be called for every reporting cycle
* ({@link co.elastic.apm.agent.report.ReporterConfiguration#metricsInterval metrics_interval)})
* @see #add(String, Map, DoubleSupplier)
*/
public void addUnlessNegative(String name, Map<String, String> tags, DoubleSupplier metric) {
if (metric.get() >= 0) {
add(name, tags, metric);
}
}

/**
* Adds a gauge to the metric registry.
*
* @param name the name of the metric
* @param tags tags for the metric.
* Tags can be used to create different graphs based for each value of a specific tag name, using a terms aggregation.
* Note that there will be a {@link MetricSet} created for each distinct set of tags.
* @param metric this supplier will be called for every reporting cycle
* ({@link co.elastic.apm.agent.report.ReporterConfiguration#metricsInterval metrics_interval)})
*/
public void add(String name, Map<String, String> tags, DoubleSupplier metric) {
MetricSet metricSet = metricSets.get(tags);
if (metricSet == null) {
Original file line number Diff line number Diff line change
@@ -28,6 +28,20 @@
import java.util.concurrent.ConcurrentHashMap;
import java.util.concurrent.ConcurrentMap;

/**
* A metric set is a collection of metrics which have the same tags.
* <p>
* A metric set corresponds to one document per
* {@link co.elastic.apm.agent.report.ReporterConfiguration#metricsInterval metrics_interval} in Elasticsearch.
* An alternative would be to have one document per metric but having one document for all metrics with the same tags saves disk space.
* </p>
* Example of some serialized metric sets:
* <pre>
* {"metricset":{"timestamp":1545047730692000,"samples":{"jvm.gc.alloc":{"value":24089200.0}}}}
* {"metricset":{"timestamp":1545047730692000,"tags":{"name":"G1 Young Generation"},"samples":{"jvm.gc.time":{"value":0.0},"jvm.gc.count":{"value":0.0}}}}
* {"metricset":{"timestamp":1545047730692000,"tags":{"name":"G1 Old Generation"}, "samples":{"jvm.gc.time":{"value":0.0},"jvm.gc.count":{"value":0.0}}}}
* </pre>
*/
public class MetricSet {
felixbarny marked this conversation as resolved.
Show resolved Hide resolved
private final Map<String, String> tags;
private final ConcurrentMap<String, DoubleSupplier> samples = new ConcurrentHashMap<>();