1extern crate env_logger;
2
3pub fn initialize_logger() {
5 {
6 use std::sync::atomic::{AtomicBool, Ordering};
8 static LOGGER_INITIALIZED: AtomicBool = AtomicBool::new(false);
9 if LOGGER_INITIALIZED.swap(true, Ordering::SeqCst) {
10 return;
11 }
12 }
13
14 use std::io::IsTerminal;
15 use tracing_subscriber::prelude::*;
16 tracing_subscriber::registry()
17 .with(tracing_subscriber::EnvFilter::from_default_env())
18 .with(
19 tracing_tree::HierarchicalLayer::new(1)
20 .with_ansi(std::io::stderr().is_terminal())
21 .with_indent_lines(true)
22 .with_bracketed_fields(true)
23 .with_timer(tracing_tree::time::Uptime::default()),
24 )
25 .init();
26}
27
28#[macro_export]
29macro_rules! ansi_color {
30 (red) => {
31 "\x1b[31m"
32 };
33 (yellow) => {
34 "\x1b[33m"
35 };
36}
37
38#[macro_export]
42macro_rules! code_location {
43 ($color:ident) => {{
44 fn f() {}
45 fn type_name_of<T>(_: T) -> &'static str {
46 std::any::type_name::<T>()
47 }
48 let name = type_name_of(f);
49
50 let path: Vec<_> = name.split("::").collect();
51 let mut name = path.iter().rev().skip(1).next().unwrap().to_string();
53
54 let line = line!();
55 let file = file!();
56 let mut location = format!("{file}:{line}");
57
58 use std::io::IsTerminal;
59 if std::io::stderr().is_terminal() {
60 name = format!("{}{name}\x1b[39m", $crate::ansi_color!($color));
61 location = format!("\x1b[2m{location}\x1b[22m");
62 }
63 format!("in {name} at {location}")
64 }};
65}
66
67#[macro_export]
69macro_rules! trace {
70 ($($arg:tt)+) => {{
71 tracing::trace!("{}:\n{}", $crate::code_location!(yellow), format!($($arg)+))
72 }};
73 () => {{
74 tracing::trace!("{}", $crate::code_location!(yellow))
75 }};
76}
77
78#[macro_export]
80macro_rules! error {
81 ($($arg:tt)+) => {{
82 tracing::error!("{}:\n{}", $crate::code_location!(red), format!($($arg)+))
83 }};
84}
85
86#[macro_export]
88macro_rules! warn {
89 ($($arg:tt)+) => {{
90 tracing::warn!("{}:\n{}", $crate::code_location!(yellow), format!($($arg)+))
91 }};
92}
93
94#[macro_export]
96macro_rules! info {
97 ($($arg:tt)+) => {{
98 tracing::info!("{}: {}", $crate::code_location!(yellow), format!($($arg)+))
100 }};
101 () => {{
102 tracing::info!("{}", $crate::code_location!(yellow))
103 }};
104}