• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (C) 2023 Huawei Device Co., Ltd.
3  * Licensed under the Apache License, Version 2.0 (the "License");
4  * you may not use this file except in compliance with the License.
5  * You may obtain a copy of the License at
6  *
7  *     http://www.apache.org/licenses/LICENSE-2.0
8  *
9  * Unless required by applicable law or agreed to in writing, software
10  * distributed under the License is distributed on an "AS IS" BASIS,
11  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12  * See the License for the specific language governing permissions and
13  * limitations under the License.
14  */
15 use std::io::Write;
16 use std::path::Path;
17 use std::sync::{Arc, Mutex};
18 use std::time::SystemTime;
19 
20 use hdc::config;
21 
22 #[derive(Default)]
23 
24 pub struct LoggerMeta {
25     stdout_require: bool,
26     run_in_server: bool, // scrolling dump only by server
27     current_size: usize,
28     log_file: std::path::PathBuf,
29 }
30 
31 type LoggerMeta_ = Arc<Mutex<LoggerMeta>>;
32 
33 struct HostLoggerMeta {}
34 impl HostLoggerMeta {
get_instance() -> LoggerMeta_35     fn get_instance() -> LoggerMeta_ {
36         static mut LOGGER_META: Option<LoggerMeta_> = None;
37         unsafe {
38             LOGGER_META
39                 .get_or_insert_with(|| Arc::new(Mutex::new(LoggerMeta::default())))
40                 .clone()
41         }
42     }
43 
init(run_in_server: bool, spawned_server: bool)44     fn init(run_in_server: bool, spawned_server: bool) {
45         let instance = Self::get_instance();
46         let mut meta = instance.lock().unwrap();
47         if run_in_server && !spawned_server {
48             meta.stdout_require = true;
49         }
50         meta.run_in_server = run_in_server;
51         meta.log_file = Path::new(&std::env::temp_dir()).join(config::LOG_FILE_NAME);
52         if run_in_server {
53             std::fs::File::create(&meta.log_file).unwrap();
54         }
55     }
56 
write_log(content: String)57     fn write_log(content: String) {
58         let instance = Self::get_instance();
59         let mut meta = instance.lock().unwrap();
60         if meta.run_in_server && meta.current_size > config::LOG_FILE_SIZE {
61             meta.current_size = 0;
62             // TODO: mv to new file
63         }
64         meta.current_size += content.len();
65         if let Ok(mut f) = std::fs::File::options().append(true).open(&meta.log_file) {
66             writeln!(&mut f, "{}", content).unwrap();
67         }
68         if meta.stdout_require {
69             println!("{}", content);
70         }
71     }
72 }
73 
74 struct SimpleHostLogger;
75 impl log::Log for SimpleHostLogger {
enabled(&self, metadata: &log::Metadata) -> bool76     fn enabled(&self, metadata: &log::Metadata) -> bool {
77         metadata.level() <= log::max_level()
78     }
log(&self, record: &log::Record)79     fn log(&self, record: &log::Record) {
80         if self.enabled(record.metadata()) {
81             let ts = humantime::format_rfc3339_millis(SystemTime::now()).to_string();
82             let level = &record.level().to_string()[..1];
83             let file = record.file().unwrap();
84             let content = format!(
85                 "{} {} {} {}:{} - {}",
86                 &ts[..10],
87                 &ts[11..23],
88                 level,
89                 file.split_once('/').unwrap().1,
90                 record.line().unwrap(),
91                 record.args()
92             );
93             HostLoggerMeta::write_log(content);
94         }
95     }
flush(&self)96     fn flush(&self) {}
97 }
98 
99 static LOGGER: SimpleHostLogger = SimpleHostLogger;
100 
logger_init(log_level: log::LevelFilter, run_in_server: bool, spawned_server: bool)101 pub fn logger_init(log_level: log::LevelFilter, run_in_server: bool, spawned_server: bool) {
102     HostLoggerMeta::init(run_in_server, spawned_server);
103     log::set_logger(&LOGGER).unwrap();
104     log::set_max_level(log_level);
105 }
106