]> git.proxmox.com Git - proxmox-backup.git/commitdiff
proxmox-rrd: cleanup error handling
authorDietmar Maurer <dietmar@proxmox.com>
Thu, 7 Oct 2021 06:01:12 +0000 (08:01 +0200)
committerDietmar Maurer <dietmar@proxmox.com>
Thu, 7 Oct 2021 06:01:12 +0000 (08:01 +0200)
proxmox-rrd/src/rrd.rs

index c31572a4d8dc58ca7b6974aaa2d2808d9092e1e6..f4c0890985b9427cef678f33e390e1775ea53590 100644 (file)
@@ -3,7 +3,7 @@
 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};
@@ -127,19 +127,15 @@ impl RRA {
         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
@@ -150,13 +146,13 @@ impl RRA {
             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
             };
@@ -166,6 +162,8 @@ impl RRA {
 
         self.delete_old(time);
         self.compute_new_value(time, value);
+
+        Ok(())
     }
 }
 
@@ -343,26 +341,32 @@ impl RRD {
     /// 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);
     }
 }