io.prometheus.client.Counter Maven / Gradle / Ivy
package io.prometheus.client;
import java.util.ArrayList;
import java.util.Collections;
import java.util.List;
import java.util.Map;
/**
* Counter metric, to track counts of events or running totals.
*
* Example of Counters include:
*
* - Number of requests processed
* - Number of items that were inserted into a queue
* - Total amount of data a system has processed
*
*
* Counters can only go up (and be reset), if your use case can go down you should use a {@link Gauge} instead.
* Use the rate()
function in Prometheus to calculate the rate of increase of a Counter.
* By convention, the names of Counters are suffixed by _total
.
*
*
* An example Counter:
*
* {@code
* class YourClass {
* static final Counter requests = Counter.build()
* .name("requests_total").help("Total requests.").register();
* static final Counter failedRequests = Counter.build()
* .name("requests_failed_total").help("Total failed requests.").register();
*
* void processRequest() {
* requests.inc();
* try {
* // Your code here.
* } catch (Exception e) {
* failedRequests.inc();
* throw e;
* }
* }
* }
* }
*
*
*
* You can also use labels to track different types of metric:
*
* {@code
* class YourClass {
* static final Counter requests = Counter.build()
* .name("requests_total").help("Total requests.")
* .labelNames("method").register();
*
* void processGetRequest() {
* requests.labels("get").inc();
* // Your code here.
* }
* void processPostRequest() {
* requests.labels("post").inc();
* // Your code here.
* }
* }
* }
*
* These can be aggregated and processed together much more easily in the Prometheus
* server than individual metrics for each labelset.
*/
public class Counter extends SimpleCollector implements Collector.Describable {
Counter(Builder b) {
super(b);
}
public static class Builder extends SimpleCollector.Builder {
@Override
public Counter create() {
return new Counter(this);
}
}
/**
* Return a Builder to allow configuration of a new Counter. Ensures required fields are provided.
*
* @param name The name of the metric
* @param help The help string of the metric
*/
public static Builder build(String name, String help) {
return new Builder().name(name).help(help);
}
/**
* Return a Builder to allow configuration of a new Counter.
*/
public static Builder build() {
return new Builder();
}
@Override
protected Child newChild() {
return new Child();
}
/**
* The value of a single Counter.
*
* Warning: References to a Child become invalid after using
* {@link SimpleCollector#remove} or {@link SimpleCollector#clear},
*/
public static class Child {
private final DoubleAdder value = new DoubleAdder();
/**
* Increment the counter by 1.
*/
public void inc() {
inc(1);
}
/**
* Increment the counter by the given amount.
* @throws IllegalArgumentException If amt is negative.
*/
public void inc(double amt) {
if (amt < 0) {
throw new IllegalArgumentException("Amount to increment must be non-negative.");
}
value.add(amt);
}
/**
* Get the value of the counter.
*/
public double get() {
return value.sum();
}
}
// Convenience methods.
/**
* Increment the counter with no labels by 1.
*/
public void inc() {
inc(1);
}
/**
* Increment the counter with no labels by the given amount.
* @throws IllegalArgumentException If amt is negative.
*/
public void inc(double amt) {
noLabelsChild.inc(amt);
}
/**
* Get the value of the counter.
*/
public double get() {
return noLabelsChild.get();
}
@Override
public List collect() {
List samples = new ArrayList(children.size());
for(Map.Entry, Child> c: children.entrySet()) {
samples.add(new MetricFamilySamples.Sample(fullname, labelNames, c.getKey(), c.getValue().get()));
}
return familySamplesList(Type.COUNTER, samples);
}
@Override
public List describe() {
return Collections.singletonList(new CounterMetricFamily(fullname, help, labelNames));
}
}