chiark / gitweb /
915d7e7057bf0c18cccec26c00bb9b1bcb94844a
[hippotat.git] / src / reporter.rs
1 // Copyright 2021 Ian Jackson and contributors to Hippotat
2 // SPDX-License-Identifier: GPL-3.0-or-later
3 // There is NO WARRANTY.
4
5 use crate::prelude::*;
6
7 pub struct Reporter<'r> {
8   ic: &'r InstanceConfig,
9   successes: u64,
10   last_report: Option<Report>,
11 }
12
13 #[derive(Debug)]
14 struct Report {
15   when: Instant,
16   ok: Result<(),()>,
17 }         
18
19 // Reporting strategy
20 //   - report all errors
21 //   - report first success after a period of lack of messages
22 //   - if error, report last success
23
24 impl<'r> Reporter<'r> {
25   pub fn new(ic: &'r InstanceConfig) -> Self { Reporter {
26     ic,
27     successes: 0,
28     last_report: None,
29   } }
30   
31   pub fn success(&mut self) {
32     self.successes += 1;
33     let now = Instant::now();
34     if let Some(rep) = &self.last_report {
35       if now - rep.when < match rep.ok {
36         Ok(()) => Duration::from_secs(3600),
37         Err(()) => Duration::from_secs(30),
38       } {
39         return
40       }
41     }
42     
43     info!("{} ({}ok): running", self.ic, self.successes);
44     self.last_report = Some(Report { when: now, ok: Ok(()) });
45   }
46
47   pub fn filter<T>(&mut self, req_num: Option<ReqNum>, r: Result<T,AE>)
48                    -> Option<T> {
49     let now = Instant::now();
50     match r {
51       Ok(t) => {
52         // xxx something something success
53         Some(t)
54       },
55       Err(e) => {
56         // xxx something something error
57         let m = (||{
58           let mut m = self.ic.to_string();
59           if let Some(req_num) = req_num {
60             write!(m, " #{}", req_num)?;
61           }
62           if self.successes > 0 {
63             write!(m, " ({}ok)", self.successes)?;
64             self.successes = 0;
65           }
66           write!(m, ": {:?}", e)?;
67           Ok::<_,fmt::Error>(m)
68         })().unwrap();
69         warn!("{}", m);
70         self.last_report = Some(Report { when: now, ok: Err(()) });
71         None
72       },
73     }
74   }
75 }