atomic_bomb_engine/models/
http_error_stats.rs1use reqwest::Url;
2use serde::{Deserialize, Serialize};
3use std::collections::HashMap;
4use std::hash::{Hash, Hasher};
5use std::sync::Arc;
6use tokio::sync::Mutex;
7
8#[derive(Debug, Eq, Clone, Serialize, Deserialize)]
9pub struct HttpErrKey {
10 pub name: String,
11 pub code: u16,
12 pub msg: String,
13 pub url: String,
14 pub source: String,
15 pub host: String,
16 pub path: String,
17}
18
19impl PartialEq for HttpErrKey {
20 fn eq(&self, other: &Self) -> bool {
21 self.name == other.name
22 && self.url == other.url
23 && self.code == other.code
24 && self.msg == other.msg
25 && self.source == other.source
26 }
27}
28
29impl Hash for HttpErrKey {
30 fn hash<H: Hasher>(&self, state: &mut H) {
31 format!(
32 "{:?}{:?}{:?}{:?}{:?}",
33 self.name, self.url, self.code, self.msg, self.source
34 )
35 .hash(state);
36 }
37}
38
39pub struct HttpErrorStats {
40 pub(crate) errors: Arc<Mutex<HashMap<HttpErrKey, u32>>>,
41}
42
43impl HttpErrorStats {
44 pub(crate) fn new() -> Self {
45 HttpErrorStats {
46 errors: Arc::new(Mutex::new(HashMap::new())),
47 }
48 }
49
50 pub(crate) async fn increment(
51 &self,
52 name: String,
53 url_option: Option<&Url>,
54 code: u16,
55 msg: String,
56 source: String,
57 ) {
58 let mut url = "-".to_string();
59 let mut host = "-".to_string();
60 let mut path = "-".to_string();
61 if let Some(u) = url_option {
62 url = u.to_string();
63 if let Some(h) = u.host() {
64 host = h.to_string();
65 };
66 path = u.path().to_string();
67 };
68 let mut errors = self.errors.lock().await;
69 *errors
70 .entry(HttpErrKey {
71 name,
72 code,
73 msg,
74 url,
75 source,
76 host,
77 path,
78 })
79 .or_insert(0) += 1;
80 }
81}