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
use slog::{o, Drain, FilterLevel, Level, Logger, OwnedKVList, Record};
use slog_envlogger::LogBuilder;
use slog_scope::set_global_logger;
use std::{cell::RefCell, io, mem, sync::Mutex};
pub fn set_simple_logger(debug_module: &str) {
mem::forget(set_global_logger(create_simple_logger(debug_module)));
}
fn create_simple_logger(debug_module: &str) -> Logger {
let drain = SimpleDrain.fuse();
let mut builder = LogBuilder::new(drain);
builder = builder.filter(None, FilterLevel::Info);
builder = builder.filter(Some(debug_module), FilterLevel::Debug);
if let Ok(s) = ::std::env::var("RUST_LOG") {
builder = builder.parse(&s);
}
let envlogger = builder.build();
Logger::root(Mutex::new(envlogger).fuse(), o!())
}
struct SimpleDrain;
impl Drain for SimpleDrain {
type Ok = ();
type Err = io::Error;
fn log(&self, record: &Record, _values: &OwnedKVList) -> Result<Self::Ok, Self::Err> {
let now = chrono::Local::now();
PREFIX.with(|prefix| {
let borrowed = prefix.borrow();
let prefix = if let Some(ref prefix) = *borrowed {
&prefix[..]
} else {
""
};
println!(
"{}{}{} {}",
char_for_level(record.level()),
now.format("%M:%S%.6f"),
prefix,
record.msg()
)
});
Ok(())
}
}
fn char_for_level(l: Level) -> char {
match l {
Level::Critical => 'C',
Level::Error => 'E',
Level::Warning => 'W',
Level::Info => 'I',
Level::Debug => 'D',
Level::Trace => 'T',
}
}
thread_local! {
pub static PREFIX: RefCell<Option<String>> = RefCell::new(None);
}
pub fn set_simple_logger_prefix(id: String) {
PREFIX.with(|x| x.replace(Option::Some(id)));
}