1#![feature(rustc_private)]
3#[macro_use]
4extern crate serde_derive;
5extern crate log;
6
7extern crate toml;
8
9#[cfg(windows)]
10extern crate wincolor;
11
12#[macro_use]
13extern crate lazy_static;
14
15mod event;
16mod config;
17mod writer;
18mod appender;
19mod color;
20
21pub mod filter;
22pub mod logger;
23
24use std::fmt::Arguments;
25use std::io::Write;
26use std::path::PathBuf;
27use std::str::FromStr;
28
29pub use crate::{
30 logger::{ThreadLocalLogger, Logger, SendEvent},
31 event::Event,
32 filter::FilterLevel,
33};
34
35thread_local! {
36 pub static LOG_SENDER: ThreadLocalLogger = ThreadLocalLogger::new();
37}
38
39pub fn init(path: String) -> Result<(), log::SetLoggerError> {
40 config::Config::create_instance(Some(PathBuf::from(path)));
41
42 log::set_boxed_logger(CombineLogger::new())?;
43 let filter = config::Config::instance().global_max_level();
44 let level = log::LevelFilter::from_str(filter.as_str()).unwrap_or(log::LevelFilter::Trace);
45 log::set_max_level(level);
46
47 Ok(())
48}
49
50pub fn close() {
51 Logger::close();
52}
53
54pub struct CombineLogger {
55 file_filter: filter::Filters,
56 console_filter: filter::Filters,
57}
58
59impl CombineLogger {
60 pub fn new() -> Box<Self> {
61 let console_conf = config::Config::instance().console_conf();
62 let file_conf = config::Config::instance().file_conf();
63 let logger = CombineLogger {
64 file_filter: filter::Filters::new(file_conf),
65 console_filter: filter::Filters::new(console_conf),
66 };
67
68 Box::new(logger)
69 }
70}
71
72impl log::Log for CombineLogger {
73 fn enabled(&self, metadata: &log::Metadata) -> bool {
74 let filter = metadata.level().into();
75 if self.file_filter.is_pass(filter) || self.console_filter.is_pass(filter) {
76 return true
77 }
78
79 false
80 }
81
82 fn log(&self, record: &log::Record) {
83 if self.enabled(record.metadata()) {
84 send_record(record);
85 }
86 }
87
88 fn flush(&self) {
89 let _ = std::io::stdout().flush();
90 }
91}
92
93#[allow(unused)]
94pub fn send_event(level: FilterLevel, file: &'static str, line: u32, msg: Arguments) {
95 LOG_SENDER.with(|s| {
96 let ev = Event::new(level, s.get_thread_tag(), file, line, msg);
97 s.get_sender().send_event(ev);
98 });
99}
100
101#[allow(unused)]
102pub fn send_record(record: &log::Record) {
103 LOG_SENDER.with(|s| {
104 let ev = Event::from_record(s.get_thread_tag(), record);
105 s.get_sender().send_event(ev);
106 });
107}
108
109mod test {
110
111 #[test]
112 fn multi_test() {
113 use std::time::{Duration};
114 use std::thread;
115 use std::path::PathBuf;
116 use crate::{Logger, init};
118
119 init();
120 Logger::load_config(PathBuf::from("./"));
121
122 let mut ths = Vec::new();
123
124 let max_format_count = 50_0000;
125 let t1 = max_format_count.clone();
126
127 println!("mutlt test");
128 for _i in 0..8 {
130 ths.push(thread::spawn(
131 move || {
132 for idx in 0..t1 {
134 warn!("199999999999999-=dfghjkl;'kald;ngtohbjgbtesting {}...99=====.{}....mmmmmmm{}m .... {}", 1,2,3, idx);
135 debug!("1234567890-=dfghjkl;'kald;ngtohbjgbtesting {}...99=====.{}....mmmmmmm{}m .... {}", 1,2,3, idx);
136 error!("1234567890-=dfghjkl;'kald;ngtohbjgbtesting {}...99=====.{}....mmmmmmm{}m ********* {}", 1,2,3, idx);
137 info!("1234567890-=dfghjkl;'ka0000000000;ngtohbjgbtesting {}...99=====.{}....mmmmmmm{}m ********* {}", 1,2,3, idx);
138 trace!("1234567890-=dfghjkl;'ka0000000000;ngtohbjgbtesting {}...99=====.{}....mmmmmmm{}m ********* {}", 1,2,3, idx);
139 }
140 }));
141 }
142 thread::sleep(Duration::from_secs(2));
143 }
144}