1
2use std::env;
3use std::io::{Write};
4use std::fs;
5use lazy_static::lazy_static;
7use chrono::{Local,Timelike,Datelike};
8use std::sync::RwLock;
9
10
11
12fn _ecsimple_get_environ_var(envname :&str) -> String {
13 match env::var(envname) {
14 Ok(v) => {
15 format!("{}",v)
16 },
17 Err(_e) => {
18 String::from("")
19 }
20 }
21}
22
23#[allow(dead_code)]
24struct LogVar {
25 level :i32,
26 nostderr : bool,
27 wfile : Option<fs::File>,
28 wfilename :String,
29 baklevel :i32,
30 baknostderr :bool,
31}
32
33
34fn ecsimple_proc_log_init(prefix :&str) -> LogVar {
35 let mut getv :String;
36 let mut retv :i32 = 0;
37 let mut nostderr :bool = false;
38 let mut coptfile :Option<fs::File> = None;
39 let mut key :String;
40 let mut fname :String = "".to_string();
41
42 key = format!("{}_LEVEL", prefix);
43 getv = _ecsimple_get_environ_var(&key);
44 if getv.len() > 0 {
45 match getv.parse::<i32>() {
46 Ok(v) => {
47 retv = v;
48 },
49 Err(e) => {
50 retv = 0;
51 eprintln!("can not parse [{}] error[{}]", getv,e);
52 }
53 }
54 }
55
56 key = format!("{}_NOSTDERR",prefix);
57 getv = _ecsimple_get_environ_var(&key);
58 if getv.len() > 0 {
59 nostderr = true;
60 }
61
62
63
64 key = format!("{}_LOGFILE",prefix);
65 getv = _ecsimple_get_environ_var(&key);
66 if getv.len() > 0 {
67 fname = format!("{}",getv);
68 let fo = fs::File::create(&getv);
69 if fo.is_err() {
70 eprintln!("can not open [{}]", getv);
71 } else {
72 coptfile = Some(fo.unwrap());
73 }
74 }
75
76 return LogVar {
77 level : retv,
78 nostderr : nostderr,
79 wfile : coptfile,
80 wfilename : fname,
81 baklevel : 0,
82 baknostderr : true,
83 };
84}
85
86
87lazy_static! {
88 static ref ECSIMPLE_LOG_LEVEL : RwLock<LogVar> = {
89 RwLock::new(ecsimple_proc_log_init("ECSIMPLE"))
90 };
91}
92
93pub fn set_ecsimple_logger_disable() {
94 let mut ecsimpleref = ECSIMPLE_LOG_LEVEL.write().unwrap();
95 ecsimpleref.baknostderr = ecsimpleref.nostderr;
96 ecsimpleref.baklevel = ecsimpleref.level;
97 ecsimpleref.wfile = None;
98 ecsimpleref.level = 0;
99 ecsimpleref.nostderr = true;
100 return;
101}
102
103pub fn set_ecsimple_logger_enable() {
104 let mut ecsimpleref = ECSIMPLE_LOG_LEVEL.write().unwrap();
105 ecsimpleref.level = ecsimpleref.baklevel;
106 ecsimpleref.nostderr = ecsimpleref.baknostderr;
107 if ecsimpleref.wfilename.len() > 0 {
108 let fo = fs::File::create(&ecsimpleref.wfilename);
109 if fo.is_ok() {
110 ecsimpleref.wfile = Some(fo.unwrap());
111 }
112 }
113 return ;
114}
115
116
117#[allow(dead_code)]
118pub (crate) fn ecsimple_debug_out(level :i32, outs :&str) {
119 let refecsimple = ECSIMPLE_LOG_LEVEL.write().unwrap();
120 if refecsimple.level >= level {
121 let c = format!("{}\n",outs);
122 if !refecsimple.nostderr {
123 let _ = std::io::stderr().write_all(c.as_bytes());
124 }
125
126 if refecsimple.wfile.is_some() {
127 let mut wf = refecsimple.wfile.as_ref().unwrap();
128 let _ = wf.write(c.as_bytes());
129 }
130 }
131 return;
132}
133
134pub (crate) fn ecsimple_log_get_timestamp() -> String {
135 let now = Local::now();
136 return format!("{}/{}/{} {}:{}:{}",now.year(),now.month(),now.day(),now.hour(),now.minute(),now.second());
137}
138
139#[macro_export]
140macro_rules! ecsimple_log_error {
141 ($($arg:tt)+) => {
142 let mut c :String= format!("[ECSIMPLE]<ERROR>{}[{}:{}] ",ecsimple_log_get_timestamp(),file!(),line!());
143 c.push_str(&(format!($($arg)+)[..]));
144 ecsimple_debug_out(0,&c);
145 }
146}
147
148#[macro_export]
149macro_rules! ecsimple_log_warn {
150 ($($arg:tt)+) => {
151 let mut c :String= format!("[ECSIMPLE]<WARN>{}[{}:{}] ",ecsimple_log_get_timestamp(),file!(),line!());
152 c.push_str(&(format!($($arg)+)[..]));
153 ecsimple_debug_out(10,&c);
154 }
155}
156
157
158#[macro_export]
159macro_rules! ecsimple_log_info {
160 ($($arg:tt)+) => {
161 let mut c :String= format!("[ECSIMPLE]<INFO>{}[{}:{}] ",ecsimple_log_get_timestamp(),file!(),line!());
162 c.push_str(&(format!($($arg)+)[..]));
163 ecsimple_debug_out(20,&c);
164 }
165}
166
167#[cfg(feature="debug_mode")]
168#[macro_export]
169macro_rules! ecsimple_log_trace {
170 ($($arg:tt)+) => {
171 let mut _c :String= format!("[ECSIMPLE]<TRACE>{}[{}:{}] ",ecsimple_log_get_timestamp(),file!(),line!());
172 _c.push_str(&(format!($($arg)+)[..]));
173 ecsimple_debug_out(40, &_c);
174 }
175}
176
177#[cfg(not(feature="debug_mode"))]
178#[macro_export]
179macro_rules! ecsimple_log_trace {
180 ($($arg:tt)+) => {}
181}
182
183
184#[macro_export]
185macro_rules! ecsimple_assert {
186 ($v:expr , $($arg:tt)+) => {
187 if !($v) {
188 let mut _c :String= format!("[ECSIMPLE][{}:{}] ",file!(),line!());
189 _c.push_str(&(format!($($arg)+)[..]));
190 panic!("{}", _c);
191 }
192 }
193}
194
195
196#[macro_export]
197macro_rules! ecsimple_format_buffer_log {
198 ($buf:expr,$len:expr,$info:tt,$iv:expr,$($arg:tt)+) => {
199 let mut c :String = format!("[ECSIMPLE][{}:{}]",file!(),line!());
200 c.push_str(&format!("{} ",$info));
201 c.push_str(&ecsimple_log_get_timestamp());
202 c.push_str(": ");
203 c.push_str(&(format!($($arg)+)[..]));
204 let _ptr :*const u8 = $buf as *const u8;
205 let mut _ci :usize;
206 let _totallen: usize = $len as usize;
207 let mut _lasti :usize = 0;
208 let mut _nb :u8;
209 c.push_str(&format!(" buffer [{:?}][{}]",_ptr,_totallen));
210 _ci = 0;
211 while _ci < _totallen {
212 if (_ci % 16) == 0 {
213 if _ci > 0 {
214 c.push_str(" ");
215 while _lasti < _ci {
216 unsafe{
217 _nb = *_ptr.offset(_lasti as isize);
218 }
219
220 if _nb >= 0x20 && _nb <= 0x7e {
221 c.push(_nb as char);
222 } else {
223 c.push_str(".");
224 }
225 _lasti += 1;
226 }
227 }
228 c.push_str(&format!("\n0x{:08x}:", _ci));
229 }
230 unsafe {_nb = *_ptr.offset(_ci as isize);}
231 c.push_str(&format!(" 0x{:02x}",_nb));
232 _ci += 1;
233 }
234
235 if _lasti < _ci {
236 while (_ci % 16) != 0 {
237 c.push_str(" ");
238 _ci += 1;
239 }
240
241 c.push_str(" ");
242
243 while _lasti < _totallen {
244 unsafe {_nb = *_ptr.offset(_lasti as isize);}
245 if _nb >= 0x20 && _nb <= 0x7e {
246 c.push(_nb as char);
247 } else {
248 c.push_str(".");
249 }
250 _lasti += 1;
251 }
252 }
254 ecsimple_debug_out($iv,&c);
255 }
256}
257
258#[macro_export]
259macro_rules! ecsimple_debug_buffer_error {
260 ($buf:expr,$len:expr,$($arg:tt)+) => {
261 ecsimple_format_buffer_log!($buf,$len,"<ERROR>",0,$($arg)+);
262 }
263}
264
265#[macro_export]
266macro_rules! ecsimple_debug_buffer_warn {
267 ($buf:expr,$len:expr,$($arg:tt)+) => {
268 ecsimple_format_buffer_log!($buf,$len,"<WARN>",10,$($arg)+);
269 }
270}
271
272#[macro_export]
273macro_rules! ecsimple_debug_buffer_info {
274 ($buf:expr,$len:expr,$($arg:tt)+) => {
275 ecsimple_format_buffer_log!($buf,$len,"<INFO>",20,$($arg)+);
276 }
277}
278
279#[macro_export]
280macro_rules! ecsimple_debug_buffer_debug {
281 ($buf:expr,$len:expr,$($arg:tt)+) => {
282 ecsimple_format_buffer_log!($buf,$len,"<DEBUG>",30,$($arg)+);
283 }
284}
285
286#[cfg(feature="debug_mode")]
287#[macro_export]
288macro_rules! ecsimple_debug_buffer_trace {
289 ($buf:expr,$len:expr,$($arg:tt)+) => {
290 ecsimple_format_buffer_log!($buf,$len,"<TRACE>",40,$($arg)+);
291 }
292}
293
294#[cfg(not(feature="debug_mode"))]
295#[macro_export]
296macro_rules! ecsimple_debug_buffer_trace {
297 ($buf:expr,$len:expr,$($arg:tt)+) => {}
298}