src/rrd/rrd.rs: implement DST_COUNTER

This commit is contained in:
Dietmar Maurer 2020-05-25 08:14:30 +02:00
parent 2b55de407e
commit 736edc7a7e
1 changed files with 36 additions and 14 deletions

View File

@ -14,6 +14,7 @@ bitflags!{
// Data Source Types // Data Source Types
const DST_GAUGE = 1; const DST_GAUGE = 1;
const DST_DERIVE = 2; const DST_DERIVE = 2;
const DST_COUNTER = 4;
const DST_MASK = 255; // first 8 bits const DST_MASK = 255; // first 8 bits
// Consolidation Functions // Consolidation Functions
@ -68,19 +69,11 @@ impl RRA {
} }
} }
fn compute_new_value(&mut self, time: f64, mut value: f64) { fn compute_new_value(&mut self, time: f64, value: f64) {
let epoch = time as u64; let epoch = time as u64;
let time_diff = time - self.last_update;
let last_update = self.last_update as u64; let last_update = self.last_update as u64;
let reso = self.resolution; let reso = self.resolution;
// derive counter value
if self.flags.contains(RRAFlags::DST_DERIVE) {
let diff = if self.counter_value.is_nan() { 0.0 } else { value - self.counter_value };
self.counter_value = value;
value = diff/time_diff;
}
let index = ((epoch/reso) % (RRD_DATA_ENTRIES as u64)) as usize; let index = ((epoch/reso) % (RRD_DATA_ENTRIES as u64)) as usize;
let last_index = ((last_update/reso) % (RRD_DATA_ENTRIES as u64)) as usize; let last_index = ((last_update/reso) % (RRD_DATA_ENTRIES as u64)) as usize;
@ -118,17 +111,46 @@ impl RRA {
self.last_update = time; self.last_update = time;
} }
fn update(&mut self, epoch: f64, value: f64) { fn update(&mut self, time: f64, mut value: f64) {
if epoch <= self.last_update {
eprintln!("rrdb update failed - time in past ({} < {})", epoch, self.last_update); if time <= self.last_update {
eprintln!("rrdb update failed - time in past ({} < {})", time, self.last_update);
} }
if value.is_nan() { if value.is_nan() {
eprintln!("rrdb update failed - new value is NAN"); eprintln!("rrdb update failed - new value is NAN");
return; return;
} }
self.delete_old(epoch); // derive counter value
self.compute_new_value(epoch, value); if self.flags.intersects(RRAFlags::DST_DERIVE | RRAFlags::DST_COUNTER) {
let time_diff = time - self.last_update;
let diff = if self.counter_value.is_nan() {
0.0
} else {
if self.flags.contains(RRAFlags::DST_COUNTER) { // check for overflow
if value < 0.0 {
eprintln!("rrdb update failed - got negative value for counter");
return;
}
// Note: We do not try automatic overflow corrections
if value < self.counter_value { // overflow or counter reset
self.counter_value = value;
eprintln!("rrdb update failed - conter overflow/reset detected");
return;
} else {
value - self.counter_value
}
} else {
value - self.counter_value
}
};
self.counter_value = value;
value = diff/time_diff;
}
self.delete_old(time);
self.compute_new_value(time, value);
} }
} }