Skip to content
Merged
Show file tree
Hide file tree
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
22 changes: 22 additions & 0 deletions packages/metrics/src/gauge.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,14 @@ impl Gauge {
pub fn set(&mut self, value: f64) {
self.0 = value;
}

pub fn increment(&mut self, value: f64) {
self.0 += value;
}

pub fn decrement(&mut self, value: f64) {
self.0 -= value;
}
}

impl From<f64> for Gauge {
Expand Down Expand Up @@ -72,6 +80,20 @@ mod tests {
assert_relative_eq!(gauge.value(), 1.0);
}

#[test]
fn it_could_be_incremented() {
let mut gauge = Gauge::new(0.0);
gauge.increment(1.0);
assert_relative_eq!(gauge.value(), 1.0);
}

#[test]
fn it_could_be_decremented() {
let mut gauge = Gauge::new(1.0);
gauge.decrement(1.0);
assert_relative_eq!(gauge.value(), 0.0);
}

#[test]
fn it_serializes_to_prometheus() {
let counter = Gauge::new(42.0);
Expand Down
8 changes: 8 additions & 0 deletions packages/metrics/src/metric/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,14 @@ impl Metric<Gauge> {
pub fn set(&mut self, label_set: &LabelSet, value: f64, time: DurationSinceUnixEpoch) {
self.sample_collection.set(label_set, value, time);
}

pub fn increment(&mut self, label_set: &LabelSet, time: DurationSinceUnixEpoch) {
self.sample_collection.increment(label_set, time);
}

pub fn decrement(&mut self, label_set: &LabelSet, time: DurationSinceUnixEpoch) {
self.sample_collection.decrement(label_set, time);
}
}

impl<T: PrometheusSerializable> PrometheusSerializable for Metric<T> {
Expand Down
62 changes: 62 additions & 0 deletions packages/metrics/src/metric_collection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -136,6 +136,38 @@ impl MetricCollection {
Ok(())
}

/// # Errors
///
/// Return an error if a metrics of a different type with the same name
/// already exists.
pub fn increase_gauge(&mut self, name: &MetricName, label_set: &LabelSet, time: DurationSinceUnixEpoch) -> Result<(), Error> {
if self.counters.metrics.contains_key(name) {
return Err(Error::MetricNameCollisionAdding {
metric_name: name.clone(),
});
}

self.gauges.increment(name, label_set, time);

Ok(())
}

/// # Errors
///
/// Return an error if a metrics of a different type with the same name
/// already exists.
pub fn decrease_gauge(&mut self, name: &MetricName, label_set: &LabelSet, time: DurationSinceUnixEpoch) -> Result<(), Error> {
if self.counters.metrics.contains_key(name) {
return Err(Error::MetricNameCollisionAdding {
metric_name: name.clone(),
});
}

self.gauges.decrement(name, label_set, time);

Ok(())
}

pub fn ensure_gauge_exists(&mut self, name: &MetricName) {
self.gauges.ensure_metric_exists(name);
}
Expand Down Expand Up @@ -353,6 +385,36 @@ impl MetricKindCollection<Gauge> {
metric.set(label_set, value, time);
}

/// Increments the gauge for the given metric name and labels.
///
/// If the metric name does not exist, it will be created.
///
/// # Panics
///
/// Panics if the metric does not exist and it could not be created.
pub fn increment(&mut self, name: &MetricName, label_set: &LabelSet, time: DurationSinceUnixEpoch) {
self.ensure_metric_exists(name);

let metric = self.metrics.get_mut(name).expect("Gauge metric should exist");

metric.increment(label_set, time);
}

/// Decrements the gauge for the given metric name and labels.
///
/// If the metric name does not exist, it will be created.
///
/// # Panics
///
/// Panics if the metric does not exist and it could not be created.
pub fn decrement(&mut self, name: &MetricName, label_set: &LabelSet, time: DurationSinceUnixEpoch) {
self.ensure_metric_exists(name);

let metric = self.metrics.get_mut(name).expect("Gauge metric should exist");

metric.decrement(label_set, time);
}

#[must_use]
pub fn get_value(&self, name: &MetricName, label_set: &LabelSet) -> Option<Gauge> {
self.metrics
Expand Down
38 changes: 37 additions & 1 deletion packages/metrics/src/sample.rs
Original file line number Diff line number Diff line change
Expand Up @@ -64,6 +64,14 @@ impl Sample<Gauge> {
pub fn set(&mut self, value: f64, time: DurationSinceUnixEpoch) {
self.measurement.set(value, time);
}

pub fn increment(&mut self, time: DurationSinceUnixEpoch) {
self.measurement.increment(time);
}

pub fn decrement(&mut self, time: DurationSinceUnixEpoch) {
self.measurement.decrement(time);
}
}

#[derive(Debug, Clone, PartialEq, Serialize, Deserialize)]
Expand Down Expand Up @@ -121,6 +129,16 @@ impl Measurement<Gauge> {
self.value.set(value);
self.set_recorded_at(time);
}

pub fn increment(&mut self, time: DurationSinceUnixEpoch) {
self.value.increment(1.0);
self.set_recorded_at(time);
}

pub fn decrement(&mut self, time: DurationSinceUnixEpoch) {
self.value.decrement(1.0);
self.set_recorded_at(time);
}
}

/// Serializes the `recorded_at` field as a string in ISO 8601 format (RFC 3339).
Expand Down Expand Up @@ -273,14 +291,32 @@ mod tests {
}

#[test]
fn it_should_allow_incrementing_the_counter() {
fn it_should_allow_setting_a_value() {
let mut sample = Sample::new(Gauge::default(), DurationSinceUnixEpoch::default(), LabelSet::default());

sample.set(1.0, updated_at_time());

assert_eq!(sample.value(), &Gauge::new(1.0));
}

#[test]
fn it_should_allow_incrementing_the_value() {
let mut sample = Sample::new(Gauge::new(0.0), DurationSinceUnixEpoch::default(), LabelSet::default());

sample.increment(updated_at_time());

assert_eq!(sample.value(), &Gauge::new(1.0));
}

#[test]
fn it_should_allow_decrementing_the_value() {
let mut sample = Sample::new(Gauge::new(1.0), DurationSinceUnixEpoch::default(), LabelSet::default());

sample.decrement(updated_at_time());

assert_eq!(sample.value(), &Gauge::new(0.0));
}

#[test]
fn it_should_record_the_latest_update_time_when_the_counter_is_incremented() {
let mut sample = Sample::new(Gauge::default(), DurationSinceUnixEpoch::default(), LabelSet::default());
Expand Down
70 changes: 58 additions & 12 deletions packages/metrics/src/sample_collection.rs
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,24 @@ impl SampleCollection<Gauge> {

sample.set(value, time);
}

pub fn increment(&mut self, label_set: &LabelSet, time: DurationSinceUnixEpoch) {
let sample = self
.samples
.entry(label_set.clone())
.or_insert_with(|| Measurement::new(Gauge::default(), time));

sample.increment(time);
}

pub fn decrement(&mut self, label_set: &LabelSet, time: DurationSinceUnixEpoch) {
let sample = self
.samples
.entry(label_set.clone())
.or_insert_with(|| Measurement::new(Gauge::default(), time));

sample.decrement(time);
}
}

impl<T: Serialize> Serialize for SampleCollection<T> {
Expand Down Expand Up @@ -278,7 +296,7 @@ mod tests {
#[test]
fn it_should_increment_the_counter_for_a_preexisting_label_set() {
let label_set = LabelSet::default();
let mut collection = SampleCollection::default();
let mut collection = SampleCollection::<Counter>::default();

// Initialize the sample
collection.increment(&label_set, sample_update_time());
Expand All @@ -296,7 +314,7 @@ mod tests {
#[test]
fn it_should_allow_increment_the_counter_for_a_non_existent_label_set() {
let label_set = LabelSet::default();
let mut collection = SampleCollection::default();
let mut collection = SampleCollection::<Counter>::default();

// Increment a non-existent label
collection.increment(&label_set, sample_update_time());
Expand All @@ -312,7 +330,7 @@ mod tests {
let label_set = LabelSet::default();
let initial_time = sample_update_time();

let mut collection = SampleCollection::default();
let mut collection = SampleCollection::<Counter>::default();
collection.increment(&label_set, initial_time);

// Increment with a new time
Expand All @@ -330,7 +348,7 @@ mod tests {
let label2 = LabelSet::from([("name", "value2")]);
let now = sample_update_time();

let mut collection = SampleCollection::default();
let mut collection = SampleCollection::<Counter>::default();

collection.increment(&label1, now);
collection.increment(&label2, now);
Expand All @@ -351,9 +369,9 @@ mod tests {
use crate::gauge::Gauge;

#[test]
fn it_should_increment_the_gauge_for_a_preexisting_label_set() {
fn it_should_allow_setting_the_gauge_for_a_preexisting_label_set() {
let label_set = LabelSet::default();
let mut collection = SampleCollection::default();
let mut collection = SampleCollection::<Gauge>::default();

// Initialize the sample
collection.set(&label_set, 1.0, sample_update_time());
Expand All @@ -369,9 +387,9 @@ mod tests {
}

#[test]
fn it_should_allow_increment_the_gauge_for_a_non_existent_label_set() {
fn it_should_allow_setting_the_gauge_for_a_non_existent_label_set() {
let label_set = LabelSet::default();
let mut collection = SampleCollection::default();
let mut collection = SampleCollection::<Gauge>::default();

// Set a non-existent label
collection.set(&label_set, 1.0, sample_update_time());
Expand All @@ -383,11 +401,11 @@ mod tests {
}

#[test]
fn it_should_update_the_latest_update_time_when_incremented() {
fn it_should_update_the_latest_update_time_when_setting() {
let label_set = LabelSet::default();
let initial_time = sample_update_time();

let mut collection = SampleCollection::default();
let mut collection = SampleCollection::<Gauge>::default();
collection.set(&label_set, 1.0, initial_time);

// Set with a new time
Expand All @@ -400,12 +418,12 @@ mod tests {
}

#[test]
fn it_should_increment_the_gauge_for_multiple_labels() {
fn it_should_allow_setting_the_gauge_for_multiple_labels() {
let label1 = LabelSet::from([("name", "value1")]);
let label2 = LabelSet::from([("name", "value2")]);
let now = sample_update_time();

let mut collection = SampleCollection::default();
let mut collection = SampleCollection::<Gauge>::default();

collection.set(&label1, 1.0, now);
collection.set(&label2, 2.0, now);
Expand All @@ -414,5 +432,33 @@ mod tests {
assert_eq!(collection.get(&label2).unwrap().value(), &Gauge::new(2.0));
assert_eq!(collection.len(), 2);
}

#[test]
fn it_should_allow_incrementing_the_gauge() {
let label_set = LabelSet::default();
let mut collection = SampleCollection::<Gauge>::default();

// Initialize the sample
collection.set(&label_set, 1.0, sample_update_time());

// Increment
collection.increment(&label_set, sample_update_time());
let sample = collection.get(&label_set).unwrap();
assert_eq!(*sample.value(), Gauge::new(2.0));
}

#[test]
fn it_should_allow_decrementing_the_gauge() {
let label_set = LabelSet::default();
let mut collection = SampleCollection::<Gauge>::default();

// Initialize the sample
collection.set(&label_set, 1.0, sample_update_time());

// Increment
collection.decrement(&label_set, sample_update_time());
let sample = collection.get(&label_set).unwrap();
assert_eq!(*sample.value(), Gauge::new(0.0));
}
}
}
Loading