use std::io::Read;
use std::path::Path;
-use anyhow::Error;
+use anyhow::{bail, Error};
use bitflags::bitflags;
use proxmox::tools::{fs::replace_file, fs::CreateOptions};
self.last_update = time;
}
- fn update(&mut self, time: f64, mut value: f64, log_time_in_past: &mut bool) {
+ // Note: This may update the state even in case of errors (see counter overflow)
+ fn update(&mut self, time: f64, mut value: f64) -> Result<(), Error> {
if time <= self.last_update {
- if *log_time_in_past {
- log::warn!("rrdb update failed - time in past ({} < {})", time, self.last_update);
- *log_time_in_past = false; // avoid logging this multiple times inside a RRD
- }
- return;
+ bail!("time in past ({} < {})", time, self.last_update);
}
if value.is_nan() {
- log::warn!("rrdb update failed - new value is NAN");
- return;
+ bail!("new value is NAN");
}
// derive counter value
let diff = if self.counter_value.is_nan() {
0.0
} else if is_counter && value < 0.0 {
- log::warn!("rrdb update failed - got negative value for counter");
- return;
+ bail!("got negative value for counter");
} else if is_counter && value < self.counter_value {
- // Note: We do not try automatic overflow corrections
+ // Note: We do not try automatic overflow corrections, but
+ // we update counter_value anyways, so that we can compute the diff
+ // next time.
self.counter_value = value;
- log::warn!("rrdb update failed - conter overflow/reset detected");
- return;
+ bail!("conter overflow/reset detected");
} else {
value - self.counter_value
};
self.delete_old(time);
self.compute_new_value(time, value);
+
+ Ok(())
}
}
/// Note: This does not call [Self::save].
pub fn update(&mut self, time: f64, value: f64) {
- if value.is_nan() {
- log::warn!("rrdb update failed - new value is NAN");
- return;
- }
+ let mut log_error = true;
- let mut log_time_in_past = true;
+ let mut update_rra = |rra: &mut RRA| {
+ if let Err(err) = rra.update(time, value) {
+ if log_error {
+ log::error!("rrd update failed: {}", err);
+ // we only log the first error, because it is very
+ // likely other calls produce the same error
+ log_error = false;
+ }
+ }
+ };
- self.hour_avg.update(time, value, &mut log_time_in_past);
- self.hour_max.update(time, value, &mut log_time_in_past);
+ update_rra(&mut self.hour_avg);
+ update_rra(&mut self.hour_max);
- self.day_avg.update(time, value, &mut log_time_in_past);
- self.day_max.update(time, value, &mut log_time_in_past);
+ update_rra(&mut self.day_avg);
+ update_rra(&mut self.day_max);
- self.week_avg.update(time, value, &mut log_time_in_past);
- self.week_max.update(time, value, &mut log_time_in_past);
+ update_rra(&mut self.week_avg);
+ update_rra(&mut self.week_max);
- self.month_avg.update(time, value, &mut log_time_in_past);
- self.month_max.update(time, value, &mut log_time_in_past);
+ update_rra(&mut self.month_avg);
+ update_rra(&mut self.month_max);
- self.year_avg.update(time, value, &mut log_time_in_past);
- self.year_max.update(time, value, &mut log_time_in_past);
+ update_rra(&mut self.year_avg);
+ update_rra(&mut self.year_max);
}
}