Skip to content
This repository has been archived by the owner on Oct 3, 2023. It is now read-only.

Metrics: Add specs on Gauge APIs #248

Open
wants to merge 8 commits into
base: master
Choose a base branch
from
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 100 additions & 0 deletions metrics/Gauge.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,100 @@
# Gauge Overview
A `Gauge` is used to record aggregated metrics that can go up and down. Typical examples of gauges would be the number of jobs/entries in a queue, number of threads in a running state or current memory usage etc.

The `Gauge` values can be negative. This document describes the key types and the overall behavior of API.

## Gauge API

The value that is published for gauges is an instantaneous measurement of an `int64` or `double` value. This API is useful when you want to manually increase and decrease values as per service requirements.

The following general operations MUST be provided by the API:
draffensperger marked this conversation as resolved.
Show resolved Hide resolved

* Defining a `name`, `description`, `unit`, `labelKeys`, `resource` and `constantLabels` which are fixed labels that always apply to a gauge. This should give back the gauge object to get or create time series, remove time series and clear all time series.
* `name`: a string describing the name of the metric, e.g. "vm_cpu_cycles" or "queue_size". Names MUST be unique within the library. It is recommended to use names compatible with the intended end usage.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Any restriction on the formatting of a name?

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

AFAIK there is no restriction on the length and it may contain any Unicode characters.

* `description`: an optional string describing the metric, e.g."Virtual cycles executed on VM". The default is set to "".
* `unit`: an optional string describing the unit used for the metric. Follows the format described by
[Unified Code for Units of Measure](http://unitsofmeasure.org/ucum.html). The default set to "1".
* `labelKeys`: an optional list of the label keys to track different types of metric. The default is set to empty list.
* `constantLabels`: an optional map of label keys and label values. The default is set to empty map.
* `resource`: an optional associated monitored resource information.
* Add a new time series with label values, which returns a `Point` (which is part of the `TimeSeries`). Each point represents an instantaneous measurement of a varying gauge value. Each Gauge Metric has one or more time series for a single metric.
* `labelValues`: the list of label values. The number of label values must be the same to that of the label keys.
* The `Point` class should provide functionalities to manually increment/decrement values. Example: `add(long amt)`, `set(long value)`.
* Remove a single time series from the gauge metric, if it is present.
* `labelValues`: the list of label values.
* Clear all time series from the gauge metric i.e. References to all previous point objects are invalid (not part of the metric).
* Get a default time series for a gauge with all labels not set, or default labels.

Example in Java:
```java
private static final MetricRegistry metricRegistry = Metrics.getMetricRegistry();

List<LabelKey> labelKeys = Arrays.asList(LabelKey.create("key1", "description"));
List<LabelValue> labelValues = Arrays.asList(LabelValue.create("queue1"));
LabelKey constantLabelKey = LabelKey.create("hostname", "hostname");
LabelValue constantLabelValue = LabelValue.create("localhost");

Map<LabelKey, LabelValue> constantLabels = Collections.singletonMap(constantLabelKey, constantLabelValue);

LongGauge gauge = metricRegistry.longGaugeBuilder()
.setName("queue_size")
.setDescription("The number of jobs")
.setLabelKeys(labelKeys)
.setConstantLabels(constantLabels)
.build();

LongPoint point = gauge.getOrCreateTimeSeries(labelValues);

void doSomeWork() {
point.set(15);
}
```
It is recommended to keep a reference of a point for manual operations instead of always calling `getOrCreateTimeSeries` method. The keys in `labelKeys` must not be present in `constantLabels` map. Also, `constantLabels` will be added to all the timeseries for the Metric.

## Derived Gauge API

The value that is published for gauges is an instantaneous measurement of an `int64` or `double` value. This gauge is self sufficient once created, so users should never need to interact with it. The value of the gauge is observed from the `object` and a `callback function`. The callback function is invoked whenever metrics are collected, meaning the reported value is up-to-date.

The following general operations MUST be provided by the API:
draffensperger marked this conversation as resolved.
Show resolved Hide resolved

* Defining a `name`, `description`, `unit`, `labelKeys`, `resource` and `constantLabels` which are fixed labels that always apply to a gauge. This should give back gauge object to add new time series, remove time series and clear all time series.
* `name`: same as above name.
* `description`: same as above description.
* `unit`: same as above unit.
* `labelKeys`: same as above labelKeys.
* `constantLabels`: same as above constantLabels.
* `resource`: same as above resource.
* Add a new time series with label values, an `object` and a `callback function`. The number of label values must be the same to that of the label keys.
* `labelValues`: the list of label values. The number of label values must be the same to that of the label keys.
* `object`: the state object from which the function derives a measurement.
* `function`: the callback function to be called.
* Remove a single time series from the gauge metric, if it is present.
* `labelValues`: the list of label values.
* Clear all time series from the gauge metric i.e. References to all previous point objects are invalid (not part of the metric).

Example in Java:
```java
private static final MetricRegistry metricRegistry = Metrics.getMetricRegistry();

List<LabelKey> labelKeys = Arrays.asList(LabelKey.create("key1", "description"));
List<LabelValue> labelValues = Arrays.asList(LabelValue.create("value1"));
LabelKey constantLabelKey = LabelKey.create("hostname", "hostname");
LabelValue constantLabelValue = LabelValue.create("localhost");

Map<LabelKey, LabelValue> constantLabels = Collections.singletonMap(constantLabelKey, constantLabelValue);

DerivedDoubleGauge gauge = metricRegistry.derivedDoubleGaugeBuilder()
.setName("vm_cpu_cycles")
.setDescription("Virtual cycles executed on VM")
.setLabelKeys(labelKeys)
.setConstantLabels(constantLabels)
.build();

gauge.createTimeSeries(labelValues, cpuInfo,
new ToDoubleFunction<CpuInfo>() {
{@literal @}Override
public double applyAsDouble(CpuInfo cpuInfo) {
return cpuInfo.cycles();
}
});
```