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
111
112
113
114
115
extern crate ansi_term;
extern crate log;
use ansi_term::Color;
use log::*;
use std::sync::atomic::*;
static INSTANCE: Logger = Logger {
quiet: AtomicBool::new(false),
verbosity: AtomicUsize::new(0),
};
struct Logger {
quiet: AtomicBool,
verbosity: AtomicUsize,
}
impl Log for Logger {
fn enabled(&self, _: &Metadata) -> bool {
true
}
fn log(&self, record: &Record) {
let (name, color) = match record.metadata().level() {
Level::Error => ("error", Color::Red),
Level::Warn => ("warn", Color::Purple),
Level::Info => ("info", Color::Yellow),
Level::Debug => ("debug", Color::Cyan),
Level::Trace => ("trace", Color::Blue),
};
eprintln!("{}: {}", color.paint(name), record.args());
}
fn flush(&self) {}
}
pub fn init() {
try_init().expect("logger failed to initialize");
}
pub fn try_init() -> Result<(), SetLoggerError> {
update_max_level();
set_logger(&INSTANCE)
}
pub fn quiet() -> bool {
INSTANCE.quiet.load(Ordering::SeqCst)
}
pub fn set_quiet(enabled: bool) {
INSTANCE.quiet.store(enabled, Ordering::SeqCst);
update_max_level();
}
pub fn verbosity() -> usize {
INSTANCE.verbosity.load(Ordering::SeqCst)
}
pub fn set_verbosity(verbosity: usize) {
INSTANCE.verbosity.store(verbosity, Ordering::SeqCst);
update_max_level();
}
fn update_max_level() {
set_max_level(if quiet() {
LevelFilter::Off
} else {
match verbosity() {
0 => LevelFilter::Warn,
1 => LevelFilter::Info,
2 => LevelFilter::Debug,
_ => LevelFilter::Trace,
}
});
}