rvlib/
tracing_setup.rs

1use crate::{cfg::get_log_folder, file_util::DEFAULT_HOMEDIR};
2use backtrace::Backtrace;
3use std::{cell::RefCell, io};
4use tracing::Level;
5use tracing_appender::non_blocking::WorkerGuard;
6use tracing_subscriber::{
7    fmt::{writer::MakeWriterExt, Layer},
8    prelude::*,
9};
10
11thread_local! {
12    pub static BACKTRACE: RefCell<Option<Backtrace>> = const { RefCell::new(None) };
13}
14/// # Panics
15/// In case tracing cannot be setup properly.
16pub fn tracing_setup() -> WorkerGuard {
17    let log_folder = get_log_folder(&DEFAULT_HOMEDIR);
18    let file_appender = tracing_appender::rolling::daily(log_folder, "log");
19    let (file_appender, guard_flush_file) = tracing_appender::non_blocking(file_appender);
20    let file_appender = Layer::new()
21        .with_writer(file_appender.with_max_level(Level::INFO))
22        .with_line_number(true)
23        .compact()
24        .with_ansi(false)
25        .with_file(true);
26    #[cfg(not(feature = "print_debug"))]
27    let stdout = Layer::new()
28        .with_writer(io::stdout.with_max_level(Level::INFO))
29        .with_file(true)
30        .with_line_number(true);
31    #[cfg(feature = "print_debug")]
32    let stdout = Layer::new()
33        .with_writer(io::stdout.with_max_level(Level::DEBUG))
34        .with_file(true)
35        .with_line_number(true);
36    tracing_subscriber::registry()
37        .with(file_appender)
38        .with(stdout)
39        .init();
40    std::panic::set_hook(Box::new(|_| {
41        let trace = Backtrace::new();
42        BACKTRACE.with(move |b| b.borrow_mut().replace(trace));
43    }));
44    guard_flush_file
45}
46
47use std::sync::Once;
48static INIT: Once = Once::new();
49
50pub fn init_tracing_for_tests() {
51    INIT.call_once(|| {
52        tracing_subscriber::fmt()
53            .with_max_level(tracing::Level::DEBUG)
54            .with_test_writer()
55            .init();
56    });
57}