vapcore_logger/
rotating.rs1use std::env;
20use rlog::LevelFilter;
21use env_logger::Builder as LogBuilder;
22use arrayvec::ArrayVec;
23
24use parking_lot::{RwLock, RwLockReadGuard};
25
26lazy_static! {
27 static ref LOG_DUMMY: () = {
28 let mut builder = LogBuilder::new();
29 builder.filter(None, LevelFilter::Info);
30
31 if let Ok(log) = env::var("RUST_LOG") {
32 builder.parse(&log);
33 }
34
35 if !builder.try_init().is_ok() {
36 println!("logger initialization failed!");
37 }
38 };
39}
40
41pub fn init_log() {
43 *LOG_DUMMY
44}
45
46const LOG_SIZE : usize = 128;
47
48pub struct RotatingLogger {
50 levels: String,
52 logs: RwLock<ArrayVec<[String; LOG_SIZE]>>,
54}
55
56impl RotatingLogger {
57
58 pub fn new(levels: String) -> Self {
61 RotatingLogger {
62 levels: levels,
63 logs: RwLock::new(ArrayVec::<[_; LOG_SIZE]>::new()),
64 }
65 }
66
67 pub fn append(&self, log: String) {
69 let mut logs = self.logs.write();
70 if logs.is_full() {
71 logs.pop();
72 }
73 logs.insert(0, log);
74 }
75
76 pub fn levels(&self) -> &str {
78 &self.levels
79 }
80
81 pub fn logs(&self) -> RwLockReadGuard<ArrayVec<[String; LOG_SIZE]>> {
83 self.logs.read()
84 }
85
86}
87
88#[cfg(test)]
89mod test {
90 use super::RotatingLogger;
91
92 fn logger() -> RotatingLogger {
93 RotatingLogger::new("test".to_owned())
94 }
95
96 #[test]
97 fn should_return_log_levels() {
98 let logger = logger();
100
101 let levels = logger.levels();
103
104 assert_eq!(levels, "test");
106 }
107
108 #[test]
109 fn should_return_latest_logs() {
110 let logger = logger();
112
113 logger.append("a".to_owned());
115 logger.append("b".to_owned());
116
117 let logs = logger.logs();
119 assert_eq!(logs[0], "b".to_owned());
120 assert_eq!(logs[1], "a".to_owned());
121 assert_eq!(logs.len(), 2);
122 }
123}