chiark / gitweb /
make success_report_interval configuraable
[hippotat.git] / src / reporter.rs
index af4a9249df1ea4ff7585c3aa9c2761f6d0f75bf6..24cd6b82822f44756b3b95aafc725e18a4445251 100644 (file)
@@ -1,27 +1,75 @@
 // Copyright 2021 Ian Jackson and contributors to Hippotat
-// SPDX-License-Identifier: AGPL-3.0-or-later
+// SPDX-License-Identifier: GPL-3.0-or-later
 // There is NO WARRANTY.
 
 use crate::prelude::*;
 
+// For clients only, really.
 pub struct Reporter<'r> {
   ic: &'r InstanceConfig,
+  successes: u64,
+  last_report: Option<Report>,
 }
 
+#[derive(Debug)]
+struct Report {
+  when: Instant,
+  ok: Result<(),()>,
+}         
+
+// Reporting strategy
+//   - report all errors
+//   - report first success after a period of lack of messages
+//   - if error, report last success
+
 impl<'r> Reporter<'r> {
   pub fn new(ic: &'r InstanceConfig) -> Self { Reporter {
-    ic
+    ic,
+    successes: 0,
+    last_report: None,
   } }
   
-  pub fn report<T>(&mut self, r: Result<T,AE>) -> Option<T> {
+  pub fn success(&mut self) {
+    self.successes += 1;
+    let now = Instant::now();
+    if let Some(rep) = &self.last_report {
+      if now - rep.when < match rep.ok {
+        Ok(()) => match self.ic.success_report_interval {
+          z if z == Duration::default() => return,
+          nonzero => nonzero,
+        },
+        Err(()) => self.ic.effective_http_timeout,
+      } {
+        return
+      }
+    }
+    
+    info!(target:"hippotat", "{} ({}ok): running", self.ic, self.successes);
+    self.last_report = Some(Report { when: now, ok: Ok(()) });
+  }
+
+  pub fn filter<T>(&mut self, req_num: Option<ReqNum>, r: Result<T,AE>)
+                   -> Option<T> {
+    let now = Instant::now();
     match r {
       Ok(t) => {
-        // xxx something something success
         Some(t)
       },
       Err(e) => {
-        // xxx something something error
-        error!("ERROR {} {:?}", self.ic, e);
+        let m = (||{
+          let mut m = self.ic.to_string();
+          if let Some(req_num) = req_num {
+            write!(m, " #{}", req_num)?;
+          }
+          if self.successes > 0 {
+            write!(m, " ({}ok)", self.successes)?;
+            self.successes = 0;
+          }
+          write!(m, ": {:?}", e)?;
+          Ok::<_,fmt::Error>(m)
+        })().unwrap();
+        warn!(target:"hippotat", "{}", m);
+        self.last_report = Some(Report { when: now, ok: Err(()) });
         None
       },
     }