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
#[macro_use]
extern crate log;
use futures::prelude::*;
use log::Level;
use metrics_core::{AsyncSnapshotProvider, Recorder, Snapshot, SnapshotProvider};
use std::error::Error;
use std::thread;
use std::time::Duration;
use tokio_timer::Interval;
pub struct LogExporter<C, R> {
controller: C,
recorder: R,
level: Level,
}
impl<C, R> LogExporter<C, R>
where
R: Recorder + Clone + Into<String>,
{
pub fn new(controller: C, recorder: R, level: Level) -> Self {
LogExporter {
controller,
recorder,
level,
}
}
pub fn run(&mut self, interval: Duration)
where
C: SnapshotProvider,
C::SnapshotError: Error,
{
loop {
thread::sleep(interval);
self.turn();
}
}
pub fn turn(&self)
where
C: SnapshotProvider,
C::SnapshotError: Error,
{
match self.controller.get_snapshot() {
Ok(snapshot) => {
let mut recorder = self.recorder.clone();
snapshot.record(&mut recorder);
let output = recorder.into();
log!(self.level, "{}", output);
}
Err(e) => log!(Level::Error, "failed to get snapshot: {}", e),
}
}
pub fn into_future(self, interval: Duration) -> impl Future<Item = (), Error = ()>
where
C: AsyncSnapshotProvider,
C::SnapshotError: Error,
{
let controller = self.controller;
let recorder = self.recorder;
let level = self.level;
Interval::new_interval(interval)
.map_err(|_| ())
.for_each(move |_| {
let mut recorder = recorder.clone();
controller
.get_snapshot_async()
.and_then(move |snapshot| {
snapshot.record(&mut recorder);
let output = recorder.into();
log!(level, "{}", output);
Ok(())
})
.map_err(|e| error!("failed to get snapshot: {}", e))
})
}
}