1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
use holochain_locksmith::RwLock;
use std::sync::Arc;
#[derive(Debug, Clone, PartialEq)]
pub struct Metric {
pub name: String,
pub value: f64,
}
impl Metric {
pub fn new(name: &str, value: f64) -> Self {
Self {
name: name.to_string(),
value,
}
}
}
pub trait MetricPublisher: Sync + Send {
fn publish(&mut self, metric: &Metric);
}
pub type DefaultMetricPublisher = crate::logger::LoggerMetricPublisher;
#[macro_export]
macro_rules! with_latency_publishing {
($metric_prefix:expr, $publisher:expr, $f:expr, $($args:expr),* ) => {{
let clock = std::time::SystemTime::now();
let ret = ($f)($($args),*);
let latency = clock.elapsed().unwrap().as_millis();
let metric_name = format!("{}.latency", $metric_prefix);
let metric = $crate::Metric::new(metric_name.as_str(), latency as f64);
$publisher.write().unwrap().publish(&metric);
ret
}}
}
pub struct MetricPublishers(Vec<Arc<RwLock<dyn MetricPublisher>>>);
impl MetricPublisher for MetricPublishers {
fn publish(&mut self, metric: &Metric) {
for publisher in &self.0 {
publisher.write().unwrap().publish(&metric);
}
}
}
impl MetricPublishers {
pub fn new(publishers: Vec<Arc<RwLock<dyn MetricPublisher>>>) -> Self {
MetricPublishers(publishers)
}
pub fn empty() -> Self {
Self::new(vec![])
}
}
impl Default for MetricPublishers {
fn default() -> Self {
let publishers = vec![
crate::config::MetricPublisherConfig::default_logger().create_metric_publisher(),
crate::config::MetricPublisherConfig::default_cloudwatch_logs()
.create_metric_publisher(),
];
Self(publishers)
}
}
#[cfg(test)]
mod test {
use super::*;
use std::sync::{Arc, RwLock};
#[test]
fn can_publish_to_logger() {
let mut publisher = crate::logger::LoggerMetricPublisher;
let metric = Metric::new("latency", 100.0);
publisher.publish(&metric);
}
fn test_latency_fn(x: bool) -> bool {
x
}
#[test]
fn can_publish_latencies() {
let publisher = Arc::new(RwLock::new(crate::logger::LoggerMetricPublisher));
let ret = with_latency_publishing!("test", publisher, test_latency_fn, true);
assert!(ret)
}
}