lightstreamer_rs/utils/
logger.rs1use std::sync::Once;
66
67use tracing_subscriber::FmtSubscriber;
68
69use {std::env, tracing::Level};
70
71static INIT: Once = Once::new();
72
73pub fn setup_logger() {
89 INIT.call_once(|| {
90 let log_level = env::var("LOGLEVEL")
91 .unwrap_or_else(|_| "INFO".to_string())
92 .to_uppercase();
93
94 let level = match log_level.as_str() {
95 "DEBUG" => Level::DEBUG,
96 "ERROR" => Level::ERROR,
97 "WARN" => Level::WARN,
98 "TRACE" => Level::TRACE,
99 _ => Level::INFO,
100 };
101
102 let subscriber = FmtSubscriber::builder().with_max_level(level).finish();
103
104 tracing::subscriber::set_global_default(subscriber)
105 .expect("Error setting default subscriber");
106
107 tracing::debug!("Log level set to: {}", level);
108 });
109}
110
111#[allow(unused_variables)]
122pub fn setup_logger_with_level(log_level: &str) {
123 INIT.call_once(|| {
124 let log_level = log_level.to_uppercase();
125
126 let level = match log_level.as_str() {
127 "DEBUG" => Level::DEBUG,
128 "ERROR" => Level::ERROR,
129 "WARN" => Level::WARN,
130 "TRACE" => Level::TRACE,
131 _ => Level::INFO,
132 };
133
134 let subscriber = FmtSubscriber::builder().with_max_level(level).finish();
135
136 tracing::subscriber::set_global_default(subscriber)
137 .expect("Error setting default subscriber");
138
139 tracing::debug!("Log level set to: {}", level);
140 });
141}
142
143#[cfg(test)]
144mod tests_setup_logger {
145 use super::setup_logger;
146 use std::env;
147 use tracing::subscriber::set_global_default;
148 use tracing_subscriber::FmtSubscriber;
149
150 #[test]
151 fn test_logger_initialization_info() {
152 unsafe {
153 env::set_var("LOGLEVEL", "INFO");
154 }
155 setup_logger();
156
157 assert!(
158 set_global_default(FmtSubscriber::builder().finish()).is_err(),
159 "Logger should already be set"
160 );
161 }
162
163 #[test]
164 fn test_logger_initialization_debug() {
165 unsafe {
166 env::set_var("LOGLEVEL", "DEBUG");
167 }
168 setup_logger();
169
170 assert!(
171 set_global_default(FmtSubscriber::builder().finish()).is_err(),
172 "Logger should already be set"
173 );
174 }
175
176 #[test]
177 fn test_logger_initialization_default() {
178 unsafe {
179 env::remove_var("LOGLEVEL");
180 }
181 setup_logger();
182
183 assert!(
184 set_global_default(FmtSubscriber::builder().finish()).is_err(),
185 "Logger should already be set"
186 );
187 }
188
189 #[test]
190 fn test_logger_called_once() {
191 unsafe {
192 env::set_var("LOGLEVEL", "INFO");
193 }
194
195 setup_logger(); setup_logger(); assert!(
199 set_global_default(FmtSubscriber::builder().finish()).is_err(),
200 "Logger should already be set and should not be reset"
201 );
202 }
203}
204
205#[cfg(test)]
206mod tests_setup_logger_bis {
207 use super::*;
208 use std::sync::Mutex;
209 use tracing::subscriber::with_default;
210 use tracing_subscriber::Layer;
211 use tracing_subscriber::layer::{Context, SubscriberExt};
212 use tracing_subscriber::registry;
213
214 static TEST_MUTEX: Mutex<()> = Mutex::new(());
215
216 #[derive(Clone)]
217 struct TestLayer {
218 level: std::sync::Arc<Mutex<Option<Level>>>,
219 }
220
221 impl<S> Layer<S> for TestLayer
222 where
223 S: tracing::Subscriber,
224 {
225 fn on_event(&self, event: &tracing::Event<'_>, _ctx: Context<'_, S>) {
226 let mut level = self.level.lock().unwrap();
227 *level = Some(*event.metadata().level());
228 }
229 }
230
231 fn create_test_layer() -> (TestLayer, std::sync::Arc<Mutex<Option<Level>>>) {
232 let level = std::sync::Arc::new(Mutex::new(None));
233 (
234 TestLayer {
235 level: level.clone(),
236 },
237 level,
238 )
239 }
240
241 #[test]
242 fn test_default_log_level() {
243 let _lock = TEST_MUTEX.lock().unwrap();
244 unsafe {
245 env::remove_var("LOGLEVEL");
246 }
247
248 let (layer, level) = create_test_layer();
249 let subscriber = registry().with(layer);
250
251 with_default(subscriber, || {
252 setup_logger();
253 tracing::info!("Test log");
254 });
255
256 assert_eq!(*level.lock().unwrap(), Some(Level::INFO));
257 }
258
259 #[test]
260 fn test_debug_log_level() {
261 let _lock = TEST_MUTEX.lock().unwrap();
262 unsafe {
263 env::set_var("LOGLEVEL", "DEBUG");
264 }
265
266 let (layer, level) = create_test_layer();
267 let subscriber = registry().with(layer);
268
269 with_default(subscriber, || {
270 setup_logger();
271 tracing::debug!("Test log");
272 });
273
274 assert_eq!(*level.lock().unwrap(), Some(Level::DEBUG));
275 unsafe {
276 env::remove_var("LOGLEVEL");
277 }
278 }
279
280 #[test]
281 fn test_error_log_level() {
282 let _lock = TEST_MUTEX.lock().unwrap();
283 unsafe {
284 env::set_var("LOGLEVEL", "ERROR");
285 }
286
287 let (layer, level) = create_test_layer();
288 let subscriber = registry().with(layer);
289
290 with_default(subscriber, || {
291 setup_logger();
292 tracing::error!("Test log");
293 });
294
295 assert_eq!(*level.lock().unwrap(), Some(Level::ERROR));
296 unsafe {
297 env::remove_var("LOGLEVEL");
298 }
299 }
300
301 #[test]
302 fn test_warn_log_level() {
303 let _lock = TEST_MUTEX.lock().unwrap();
304 unsafe {
305 env::set_var("LOGLEVEL", "WARN");
306 }
307 let (layer, level) = create_test_layer();
308 let subscriber = registry().with(layer);
309
310 with_default(subscriber, || {
311 setup_logger();
312 tracing::warn!("Test log");
313 });
314
315 assert_eq!(*level.lock().unwrap(), Some(Level::WARN));
316 unsafe {
317 env::remove_var("LOGLEVEL");
318 }
319 }
320
321 #[test]
322 fn test_trace_log_level() {
323 let _lock = TEST_MUTEX.lock().unwrap();
324 unsafe {
325 env::set_var("LOGLEVEL", "TRACE");
326 }
327
328 let (layer, level) = create_test_layer();
329 let subscriber = registry().with(layer);
330
331 with_default(subscriber, || {
332 setup_logger();
333 tracing::trace!("Test log");
334 });
335
336 assert_eq!(*level.lock().unwrap(), Some(Level::TRACE));
337
338 unsafe {
339 env::remove_var("LOGLEVEL");
340 }
341 }
342
343 #[test]
344 fn test_invalid_log_level() {
345 let _lock = TEST_MUTEX.lock().unwrap();
346 unsafe {
347 env::set_var("LOGLEVEL", "INVALID");
348 }
349
350 let (layer, level) = create_test_layer();
351 let subscriber = registry().with(layer);
352
353 with_default(subscriber, || {
354 setup_logger();
355 tracing::info!("Test log");
356 });
357
358 assert_eq!(*level.lock().unwrap(), Some(Level::INFO));
359 unsafe {
360 env::remove_var("LOGLEVEL");
361 }
362 }
363}