1use std::thread;
2
3use log::LevelFilter;
4use log::SetLoggerError;
5use log::Record;
6use crate::TuiLoggerFile;
7use crate::CircularBuffer;
8
9use crate::TUI_LOGGER;
10
11#[derive(Debug)]
13pub enum TuiLoggerError {
14 SetLoggerError(SetLoggerError),
15 ThreadError(std::io::Error),
16}
17impl std::error::Error for TuiLoggerError {
18 fn description(&self) -> &str {
19 match self {
20 TuiLoggerError::SetLoggerError(_) => "SetLoggerError",
21 TuiLoggerError::ThreadError(_) => "ThreadError",
22 }
23 }
24 fn cause(&self) -> Option<&dyn std::error::Error> {
25 match self {
26 TuiLoggerError::SetLoggerError(_) => None,
27 TuiLoggerError::ThreadError(err) => Some(err),
28 }
29 }
30}
31impl std::fmt::Display for TuiLoggerError {
32 fn fmt(&self, f: &mut std::fmt::Formatter<'_>) -> std::fmt::Result {
33 match self {
34 TuiLoggerError::SetLoggerError(err) => write!(f, "SetLoggerError({})", err),
35 TuiLoggerError::ThreadError(err) => write!(f, "ThreadError({})", err),
36 }
37 }
38}
39
40pub fn init_logger(max_level: LevelFilter) -> Result<(), TuiLoggerError> {
42 let join_handle = thread::Builder::new()
43 .name("tui-logger::move_events".into())
44 .spawn(|| {
45 let duration = std::time::Duration::from_millis(10);
46 loop {
47 thread::park_timeout(duration);
48 TUI_LOGGER.move_events();
49 }
50 })
51 .map_err(|err| TuiLoggerError::ThreadError(err))?;
52 TUI_LOGGER.hot_log.lock().mover_thread = Some(join_handle);
53 if cfg!(feature = "tracing-support") {
54 set_default_level(max_level);
55 Ok(())
56 } else {
57 log::set_max_level(max_level);
58 log::set_logger(&*TUI_LOGGER).map_err(|err| TuiLoggerError::SetLoggerError(err))
59 }
60}
61
62pub fn set_hot_buffer_depth(depth: usize) {
65 TUI_LOGGER.inner.lock().hot_depth = depth;
66}
67
68pub fn set_buffer_depth(depth: usize) {
71 TUI_LOGGER.inner.lock().events = CircularBuffer::new(depth);
72}
73
74pub fn set_log_file(file_options: TuiLoggerFile) {
76 TUI_LOGGER.inner.lock().dump = Some(file_options);
77}
78
79pub fn set_default_level(levelfilter: LevelFilter) {
81 TUI_LOGGER.hot_select.lock().default = levelfilter;
82 TUI_LOGGER.inner.lock().default = levelfilter;
83}
84
85pub fn set_level_for_target(target: &str, levelfilter: LevelFilter) {
87 let h = fxhash::hash64(&target);
88 TUI_LOGGER.inner.lock().targets.set(target, levelfilter);
89 let mut hs = TUI_LOGGER.hot_select.lock();
90 hs.hashtable.insert(h, levelfilter);
91}
92
93pub fn move_events() {
95 TUI_LOGGER.move_events();
96}
97
98#[derive(Default)]
100pub struct Drain;
101
102impl Drain {
103 pub fn new() -> Self {
105 Drain
106 }
107 pub fn log(&self, record: &Record) {
109 TUI_LOGGER.raw_log(record)
110 }
111}