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
extern crate fern;
extern crate log;
extern crate serde;
#[macro_use]
extern crate serde_derive;
extern crate serde_json;
use std::fmt::Arguments;
use log::{Level, Record};
fn map_level_to_stackdriver_string(level: Level) -> &'static str {
match level {
Level::Error => "ERROR",
Level::Warn => "WARNING",
Level::Info => "INFO",
Level::Debug => "DEBUG",
Level::Trace => "DEBUG",
}
}
impl<'a, 'b> From<(&'b Arguments<'a>, &'b Record<'a>)> for StackdriverLogLine {
fn from((args, record): (&'b Arguments<'a>, &'b Record<'a>)) -> Self {
StackdriverLogLine {
severity: Some(map_level_to_stackdriver_string(record.level()).into()),
message: format!("{}", args),
file: record.file().map(String::from),
line: record.line(),
module_path: record.module_path().map(String::from),
target: Some(record.target().into()),
}
}
}
#[derive(Serialize)]
pub struct StackdriverLogLine {
severity: Option<String>,
message: String,
file: Option<String>,
line: Option<u32>,
module_path: Option<String>,
target: Option<String>,
}
pub fn init_default_logger() {
fern::Dispatch::new()
.format(|out, message, record| {
let stackdriver_log_line = StackdriverLogLine::from((message, record));
out.finish(format_args!(
"{}",
serde_json::to_string(&stackdriver_log_line).unwrap()
))
})
.level(log::LevelFilter::Debug)
.level_for("hyper", log::LevelFilter::Info)
.level_for("mio", log::LevelFilter::Info)
.level_for("tokio_core", log::LevelFilter::Info)
.level_for("tokio_reactor", log::LevelFilter::Info)
.chain(std::io::stdout())
.apply()
.unwrap();
}