ig_client/utils/
logger.rs1use std::env;
2use std::sync::Once;
3use tracing::Level;
4use tracing_subscriber::FmtSubscriber;
5
6static INIT: Once = Once::new();
7pub fn setup_logger() {
12 INIT.call_once(|| {
13 let log_level = env::var("LOGLEVEL")
14 .unwrap_or_else(|_| "INFO".to_string())
15 .to_uppercase();
16
17 let level = match log_level.as_str() {
18 "DEBUG" => Level::DEBUG,
19 "ERROR" => Level::ERROR,
20 "WARN" => Level::WARN,
21 "TRACE" => Level::TRACE,
22 _ => Level::INFO,
23 };
24
25 let subscriber = FmtSubscriber::builder().with_max_level(level).finish();
26
27 tracing::subscriber::set_global_default(subscriber)
28 .expect("Error setting default subscriber");
29
30 tracing::debug!("Log level set to: {}", level);
31 });
32}
33
34#[cfg(test)]
35mod tests_setup_logger {
36 use super::setup_logger;
37 use std::env;
38 use tracing::subscriber::set_global_default;
39 use tracing_subscriber::FmtSubscriber;
40
41 #[test]
42 fn test_logger_initialization_info() {
43 unsafe {
44 env::set_var("LOGLEVEL", "INFO");
45 }
46 setup_logger();
47
48 assert!(
52 set_global_default(FmtSubscriber::builder().finish()).is_err(),
53 "Logger should already be set"
54 );
55 }
56
57 #[test]
58 fn test_logger_initialization_debug() {
59 unsafe {
60 env::set_var("LOGLEVEL", "DEBUG");
61 }
62 setup_logger();
63
64 assert!(
66 set_global_default(FmtSubscriber::builder().finish()).is_err(),
67 "Logger should already be set"
68 );
69 }
70
71 #[test]
72 fn test_logger_initialization_default() {
73 unsafe {
74 env::remove_var("LOGLEVEL");
75 }
76 setup_logger();
77
78 assert!(
80 set_global_default(FmtSubscriber::builder().finish()).is_err(),
81 "Logger should already be set"
82 );
83 }
84
85 #[test]
86 fn test_logger_called_once() {
87 unsafe {
88 env::set_var("LOGLEVEL", "INFO");
89 }
90
91 setup_logger(); setup_logger(); assert!(
96 set_global_default(FmtSubscriber::builder().finish()).is_err(),
97 "Logger should already be set and should not be reset"
98 );
99 }
100}
101
102#[cfg(test)]
103mod tests_setup_logger_bis {
104 use super::*;
105 use std::sync::Mutex;
106 use tracing::info;
107 use tracing::subscriber::with_default;
108 use tracing_subscriber::Layer;
109 use tracing_subscriber::layer::SubscriberExt;
110
111 static TEST_MUTEX: Mutex<()> = Mutex::new(());
112
113 #[derive(Clone)]
114 struct TestLayer {
115 level: std::sync::Arc<Mutex<Option<Level>>>,
116 }
117
118 impl<S> Layer<S> for TestLayer
119 where
120 S: tracing::Subscriber,
121 {
122 fn on_event(
123 &self,
124 event: &tracing::Event<'_>,
125 _ctx: tracing_subscriber::layer::Context<'_, S>,
126 ) {
127 if let Ok(mut level) = self.level.lock() {
128 *level = Some(*event.metadata().level());
129 }
130 }
131 }
132
133 fn create_test_layer() -> (TestLayer, std::sync::Arc<Mutex<Option<Level>>>) {
134 let level = std::sync::Arc::new(Mutex::new(None));
135 (
136 TestLayer {
137 level: level.clone(),
138 },
139 level,
140 )
141 }
142
143 #[test]
144 fn test_default_log_level() {
145 let _lock = TEST_MUTEX.lock().expect("Test mutex poisoned");
146 unsafe {
147 env::remove_var("LOGLEVEL");
148 }
149
150 let (layer, level) = create_test_layer();
151 let subscriber = tracing_subscriber::registry().with(layer);
152
153 with_default(subscriber, || {
154 setup_logger();
155 info!("Test log");
156 });
157
158 assert_eq!(
159 *level.lock().expect("Level mutex poisoned"),
160 Some(Level::INFO)
161 );
162 }
163
164 #[test]
165 fn test_debug_log_level() {
166 let _lock = TEST_MUTEX.lock().expect("Test mutex poisoned");
167 unsafe {
168 env::set_var("LOGLEVEL", "DEBUG");
169 }
170
171 let (layer, level) = create_test_layer();
172 let subscriber = tracing_subscriber::registry().with(layer);
173
174 with_default(subscriber, || {
175 setup_logger();
176 tracing::debug!("Test log");
177 });
178
179 assert_eq!(
180 *level.lock().expect("Level mutex poisoned"),
181 Some(Level::DEBUG)
182 );
183
184 unsafe {
185 env::remove_var("LOGLEVEL");
186 }
187 }
188
189 #[test]
190 fn test_error_log_level() {
191 let _lock = TEST_MUTEX.lock().expect("Test mutex poisoned");
192 unsafe {
193 env::set_var("LOGLEVEL", "ERROR");
194 }
195
196 let (layer, level) = create_test_layer();
197 let subscriber = tracing_subscriber::registry().with(layer);
198
199 with_default(subscriber, || {
200 setup_logger();
201 tracing::error!("Test log");
202 });
203
204 assert_eq!(
205 *level.lock().expect("Level mutex poisoned"),
206 Some(Level::ERROR)
207 );
208 unsafe {
209 env::remove_var("LOGLEVEL");
210 }
211 }
212
213 #[test]
214 fn test_warn_log_level() {
215 let _lock = TEST_MUTEX.lock().expect("Test mutex poisoned");
216 unsafe {
217 env::set_var("LOGLEVEL", "WARN");
218 }
219
220 let (layer, level) = create_test_layer();
221 let subscriber = tracing_subscriber::registry().with(layer);
222
223 with_default(subscriber, || {
224 setup_logger();
225 tracing::warn!("Test log");
226 });
227
228 assert_eq!(
229 *level.lock().expect("Level mutex poisoned"),
230 Some(Level::WARN)
231 );
232 unsafe {
233 env::remove_var("LOGLEVEL");
234 }
235 }
236
237 #[test]
238 fn test_trace_log_level() {
239 let _lock = TEST_MUTEX.lock().expect("Test mutex poisoned");
240 unsafe {
241 env::set_var("LOGLEVEL", "TRACE");
242 }
243
244 let (layer, level) = create_test_layer();
245 let subscriber = tracing_subscriber::registry().with(layer);
246
247 with_default(subscriber, || {
248 setup_logger();
249 tracing::trace!("Test log");
250 });
251
252 assert_eq!(
253 *level.lock().expect("Level mutex poisoned"),
254 Some(Level::TRACE)
255 );
256 unsafe {
257 env::remove_var("LOGLEVEL");
258 }
259 }
260
261 #[test]
262 fn test_invalid_log_level() {
263 let _lock = TEST_MUTEX.lock().expect("Test mutex poisoned");
264 unsafe {
265 env::set_var("LOGLEVEL", "INVALID");
266 }
267
268 let (layer, level) = create_test_layer();
269 let subscriber = tracing_subscriber::registry().with(layer);
270
271 with_default(subscriber, || {
272 setup_logger();
273 info!("Test log");
274 });
275
276 assert_eq!(
277 *level.lock().expect("Level mutex poisoned"),
278 Some(Level::INFO)
279 );
280 unsafe {
281 env::remove_var("LOGLEVEL");
282 }
283 }
284}