Imports name this capability’s declared dependencies, which fune builds next to it in your project; each one links to its page.
use super::funejson::Value; ← the fune runtime: the JSON value the test vectors use; fune build keeps it only where a signature takes one
use super::monitor_series_window::{samples_from_value, MetricSample}; ← from monitor.series-window ^1.0.0 · built alongside by fune
/// How much a counter grew over the samples, Prometheus-style: a drop means
/// the counter restarted from zero, so the value after it is all increase. No
/// extrapolation to window edges, so the answer is a whole number.
///
/// # Panics
/// Panics on misordered samples or a negative counter value.
pub fn counter_increase(samples: &[MetricSample]) -> CounterIncrease {
let mut increase: i64 = 0;
let mut resets: i64 = 0;
for (i, s) in samples.iter().enumerate() {
if i > 0 && s.at <= samples[i - 1].at {
panic!("samples must be in strictly ascending time order: {} follows {}", s.at, samples[i - 1].at);
}
if s.value < 0 {
panic!("counter value must not be negative: {} at {}", s.value, s.at);
}
if i == 0 {
continue;
}
let prev = samples[i - 1].value;
if s.value >= prev {
increase += s.value - prev;
} else {
resets += 1;
increase += s.value;
}
}
if samples.is_empty() {
return CounterIncrease { increase: 0, resets: 0, rate_per_second_milli: None, first_at: None, last_at: None };
}
let first_at = samples[0].at;
let last_at = samples[samples.len() - 1].at;
let rate = if samples.len() >= 2 {
// increase * 1000 can pass i64 for a large byte counter: i128.
let n = increase as i128 * 1000;
let d = (last_at - first_at) as i128;
Some(((2 * n + d) / (2 * d)) as i64)
} else {
None
};
CounterIncrease { increase, resets, rate_per_second_milli: rate, first_at: Some(first_at), last_at: Some(last_at) }
}
fn opt(v: Option<i64>) -> Value {
match v {
Some(i) => Value::Int(i),
None => Value::Null,
}
}
pub fn counter_increase_to_value(c: &CounterIncrease) -> Value {
Value::obj(vec![
("increase", Value::Int(c.increase)),
("resets", Value::Int(c.resets)),
("ratePerSecondMilli", opt(c.rate_per_second_milli)),
("firstAt", opt(c.first_at)),
("lastAt", opt(c.last_at)),
])
}
pub fn fune_vector(args: &[Value]) -> Value {
counter_increase_to_value(&counter_increase(&samples_from_value(&args[0])))
}