metrics_exporter_log/
lib.rs

1//! Exports metrics via the `log` crate.
2//!
3//! This exporter can utilize observers that are able to be converted to a textual representation
4//! via [`Drain<String>`].  It will emit that output by logging via the `log` crate at the specified
5//! level.
6//!
7//! # Run Modes
8//! - Using `run` will block the current thread, capturing a snapshot and logging it based on the
9//! configured interval.
10//! - Using `async_run` will return a future that can be awaited on, mimicing the behavior of
11//! `run`.
12#![deny(missing_docs)]
13#[macro_use]
14extern crate log;
15
16use log::Level;
17use metrics_core::{Builder, Drain, Observe, Observer};
18use std::{thread, time::Duration};
19use tokio::time;
20
21/// Exports metrics by converting them to a textual representation and logging them.
22pub struct LogExporter<C, B>
23where
24    B: Builder,
25{
26    controller: C,
27    observer: B::Output,
28    level: Level,
29    interval: Duration,
30}
31
32impl<C, B> LogExporter<C, B>
33where
34    B: Builder,
35    B::Output: Drain<String> + Observer,
36    C: Observe,
37{
38    /// Creates a new [`LogExporter`] that logs at the configurable level.
39    ///
40    /// Observers expose their output by being converted into strings.
41    pub fn new(controller: C, builder: B, level: Level, interval: Duration) -> Self {
42        LogExporter {
43            controller,
44            observer: builder.build(),
45            level,
46            interval,
47        }
48    }
49
50    /// Runs this exporter on the current thread, logging output at the interval
51    /// given on construction.
52    pub fn run(&mut self) {
53        loop {
54            thread::sleep(self.interval);
55
56            self.turn();
57        }
58    }
59
60    /// Run this exporter, logging output only once.
61    pub fn turn(&mut self) {
62        self.controller.observe(&mut self.observer);
63        let output = self.observer.drain();
64        log!(self.level, "{}", output);
65    }
66
67    /// Converts this exporter into a future which logs output at the interval
68    /// given on construction.
69    pub async fn async_run(mut self) {
70        let mut interval = time::interval(self.interval);
71        loop {
72            interval.tick().await;
73            self.turn();
74        }
75    }
76}