1use std::io::Write;
2use std::time::SystemTime;
3use std::{io, thread};
4
5use chrono::{DateTime, Utc};
6use env_logger::fmt::{Color, Formatter};
7use log::{Record, SetLoggerError};
8
9pub struct LogFormatter;
11
12impl LogFormatter {
13 pub fn format(buf: &mut Formatter, record: &Record) -> io::Result<()> {
15 let metadata = record.metadata();
16 let target = metadata.target();
17 let time: DateTime<Utc> = SystemTime::now().into();
18 let time = time.format("%+");
19 let current_thread = thread::current();
20 let thread_name = current_thread
21 .name()
22 .map(|s| s.to_string())
23 .unwrap_or(format!("tid-{:?}", current_thread.id()));
24
25 let level_style = buf.default_styled_level(record.level());
26 let time_style = buf
27 .style()
28 .set_color(Color::Black)
29 .set_intense(true)
30 .clone();
31 let thread_name_style = buf
32 .style()
33 .set_color(Color::Magenta)
34 .set_intense(false)
35 .clone();
36 let args_style = buf
37 .style()
38 .set_color(Color::White)
39 .set_intense(true)
40 .clone();
41 let target_style = buf.style().set_color(Color::Cyan).set_intense(true).clone();
42
43 writeln!(
44 buf,
45 "{} [{}] ({}@{}) {}",
46 level_style,
47 time_style.value(time),
48 thread_name_style.value(thread_name),
49 target_style.value(target),
50 args_style.value(record.args())
51 )
52 }
53}
54
55pub fn try_init_from_env() -> Result<(), SetLoggerError> {
57 env_logger::Builder::from_env(env_logger::Env::default().default_filter_or("info"))
58 .format(LogFormatter::format)
59 .try_init()
60}
61
62pub fn init_from_env() {
64 let _ = try_init_from_env();
65}