Skip to content

Commit 6c11cd8

Browse files
authored
add trace! macro (#80)
1 parent 7d895fc commit 6c11cd8

File tree

1 file changed

+259
-0
lines changed

1 file changed

+259
-0
lines changed

src/macros/mod.rs

Lines changed: 259 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -152,6 +152,19 @@ macro_rules! debug {
152152
};
153153
}
154154

155+
/// Emit a log at the TRACE level.
156+
///
157+
/// See the [`log!`][macro@crate::log] macro for more details.
158+
#[macro_export]
159+
macro_rules! trace {
160+
(parent: $parent:expr, $format:expr $(, $($path:ident).+ $(= $value:expr)?)* $(,)?) => {
161+
$crate::log!(parent: $parent, tracing::Level::TRACE, $format, $($($path).+ $(= $value)?),*)
162+
};
163+
($format:expr $(, $($path:ident).+ $(= $value:expr)?)* $(,)?) => {
164+
$crate::log!(tracing::Level::TRACE, $format, $($($path).+ $(= $value)?),*)
165+
};
166+
}
167+
155168
/// Export a log message at the specified level.
156169
///
157170
/// # Syntax
@@ -255,3 +268,249 @@ macro_rules! log {
255268
$crate::__macros_impl::log!(parent: tracing::Span::current(), $level, $format, $($($path).+ $(= $value)?),*)
256269
};
257270
}
271+
272+
#[cfg(test)]
273+
mod tests {
274+
use crate::config::{ConsoleOptions, Target};
275+
use std::sync::{Arc, Mutex};
276+
use tracing::Level;
277+
278+
#[test]
279+
fn test_error_macro() {
280+
let output = Arc::new(Mutex::new(Vec::new()));
281+
let console_options = ConsoleOptions {
282+
target: Target::Pipe(output.clone()),
283+
..ConsoleOptions::default().with_min_log_level(Level::ERROR)
284+
};
285+
286+
let handler = crate::configure()
287+
.local()
288+
.send_to_logfire(false)
289+
.with_console(Some(console_options))
290+
.install_panic_handler()
291+
.with_default_level_filter(tracing::level_filters::LevelFilter::TRACE)
292+
.finish()
293+
.unwrap();
294+
295+
let guard = crate::set_local_logfire(handler);
296+
297+
tracing::subscriber::with_default(guard.subscriber().clone(), || {
298+
crate::error!("Test error message");
299+
crate::error!("Test error with value", field = 42);
300+
});
301+
302+
guard.shutdown_handler.shutdown().unwrap();
303+
304+
let output = output.lock().unwrap();
305+
let output = std::str::from_utf8(&output).unwrap();
306+
307+
assert!(output.contains("Test error message"));
308+
assert!(output.contains("Test error with value"));
309+
assert!(output.contains("field") && output.contains("42"));
310+
}
311+
312+
#[test]
313+
fn test_warn_macro() {
314+
let output = Arc::new(Mutex::new(Vec::new()));
315+
let console_options = ConsoleOptions {
316+
target: Target::Pipe(output.clone()),
317+
..ConsoleOptions::default().with_min_log_level(Level::WARN)
318+
};
319+
320+
let handler = crate::configure()
321+
.local()
322+
.send_to_logfire(false)
323+
.with_console(Some(console_options))
324+
.install_panic_handler()
325+
.with_default_level_filter(tracing::level_filters::LevelFilter::TRACE)
326+
.finish()
327+
.unwrap();
328+
329+
let guard = crate::set_local_logfire(handler);
330+
331+
tracing::subscriber::with_default(guard.subscriber().clone(), || {
332+
crate::warn!("Test warn message");
333+
crate::warn!("Test warn with value", field = "test");
334+
});
335+
336+
guard.shutdown_handler.shutdown().unwrap();
337+
338+
let output = output.lock().unwrap();
339+
let output = std::str::from_utf8(&output).unwrap();
340+
341+
assert!(output.contains("Test warn message"));
342+
assert!(output.contains("Test warn with value"));
343+
assert!(output.contains("field") && output.contains("test"));
344+
}
345+
346+
#[test]
347+
fn test_info_macro() {
348+
let output = Arc::new(Mutex::new(Vec::new()));
349+
let console_options = ConsoleOptions {
350+
target: Target::Pipe(output.clone()),
351+
..ConsoleOptions::default().with_min_log_level(Level::INFO)
352+
};
353+
354+
let handler = crate::configure()
355+
.local()
356+
.send_to_logfire(false)
357+
.with_console(Some(console_options))
358+
.install_panic_handler()
359+
.with_default_level_filter(tracing::level_filters::LevelFilter::TRACE)
360+
.finish()
361+
.unwrap();
362+
363+
let guard = crate::set_local_logfire(handler);
364+
365+
tracing::subscriber::with_default(guard.subscriber().clone(), || {
366+
crate::info!("Test info message");
367+
crate::info!("Test info with value", field = true);
368+
});
369+
370+
guard.shutdown_handler.shutdown().unwrap();
371+
372+
let output = output.lock().unwrap();
373+
let output = std::str::from_utf8(&output).unwrap();
374+
375+
assert!(output.contains("Test info message"));
376+
assert!(output.contains("Test info with value"));
377+
assert!(output.contains("field") && output.contains("true"));
378+
}
379+
380+
#[test]
381+
fn test_debug_macro() {
382+
let output = Arc::new(Mutex::new(Vec::new()));
383+
let console_options = ConsoleOptions {
384+
target: Target::Pipe(output.clone()),
385+
..ConsoleOptions::default().with_min_log_level(Level::TRACE)
386+
};
387+
388+
let handler = crate::configure()
389+
.local()
390+
.send_to_logfire(false)
391+
.with_console(Some(console_options))
392+
.install_panic_handler()
393+
.with_default_level_filter(tracing::level_filters::LevelFilter::TRACE)
394+
.finish()
395+
.unwrap();
396+
397+
let guard = crate::set_local_logfire(handler);
398+
399+
tracing::subscriber::with_default(guard.subscriber().clone(), || {
400+
crate::debug!("Test debug message");
401+
crate::debug!("Test debug with value", field = 3.14);
402+
});
403+
404+
guard.shutdown_handler.shutdown().unwrap();
405+
406+
let output = output.lock().unwrap();
407+
let output = std::str::from_utf8(&output).unwrap();
408+
409+
assert!(output.contains("Test debug message"));
410+
assert!(output.contains("Test debug with value"));
411+
assert!(output.contains("field") && output.contains("3.14"));
412+
}
413+
414+
#[test]
415+
fn test_trace_macro() {
416+
let output = Arc::new(Mutex::new(Vec::new()));
417+
let console_options = ConsoleOptions {
418+
target: Target::Pipe(output.clone()),
419+
..ConsoleOptions::default().with_min_log_level(Level::TRACE)
420+
};
421+
422+
let handler = crate::configure()
423+
.local()
424+
.send_to_logfire(false)
425+
.with_console(Some(console_options))
426+
.install_panic_handler()
427+
.with_default_level_filter(tracing::level_filters::LevelFilter::TRACE)
428+
.finish()
429+
.unwrap();
430+
431+
let guard = crate::set_local_logfire(handler);
432+
433+
tracing::subscriber::with_default(guard.subscriber().clone(), || {
434+
crate::trace!("Test trace message");
435+
crate::trace!("Test trace with value", field = "debug_info");
436+
});
437+
438+
guard.shutdown_handler.shutdown().unwrap();
439+
440+
let output = output.lock().unwrap();
441+
let output = std::str::from_utf8(&output).unwrap();
442+
443+
assert!(output.contains("Test trace message"));
444+
assert!(output.contains("Test trace with value"));
445+
assert!(output.contains("field") && output.contains("debug_info"));
446+
}
447+
448+
#[test]
449+
fn test_log_macro_with_explicit_level() {
450+
let output = Arc::new(Mutex::new(Vec::new()));
451+
let console_options = ConsoleOptions {
452+
target: Target::Pipe(output.clone()),
453+
..ConsoleOptions::default().with_min_log_level(Level::INFO)
454+
};
455+
456+
let handler = crate::configure()
457+
.local()
458+
.send_to_logfire(false)
459+
.with_console(Some(console_options))
460+
.install_panic_handler()
461+
.with_default_level_filter(tracing::level_filters::LevelFilter::TRACE)
462+
.finish()
463+
.unwrap();
464+
465+
let guard = crate::set_local_logfire(handler);
466+
467+
tracing::subscriber::with_default(guard.subscriber().clone(), || {
468+
crate::log!(Level::INFO, "Test log message");
469+
crate::log!(Level::INFO, "Test log with value", field = "explicit");
470+
});
471+
472+
guard.shutdown_handler.shutdown().unwrap();
473+
474+
let output = output.lock().unwrap();
475+
let output = std::str::from_utf8(&output).unwrap();
476+
477+
assert!(output.contains("Test log message"));
478+
assert!(output.contains("Test log with value"));
479+
assert!(output.contains("field") && output.contains("explicit"));
480+
}
481+
482+
#[test]
483+
fn test_macros_with_parent_span() {
484+
let output = Arc::new(Mutex::new(Vec::new()));
485+
let console_options = ConsoleOptions {
486+
target: Target::Pipe(output.clone()),
487+
..ConsoleOptions::default().with_min_log_level(Level::INFO)
488+
};
489+
490+
let handler = crate::configure()
491+
.local()
492+
.send_to_logfire(false)
493+
.with_console(Some(console_options))
494+
.install_panic_handler()
495+
.with_default_level_filter(tracing::level_filters::LevelFilter::TRACE)
496+
.finish()
497+
.unwrap();
498+
499+
let guard = crate::set_local_logfire(handler);
500+
501+
tracing::subscriber::with_default(guard.subscriber().clone(), || {
502+
let parent_span = crate::span!("parent span");
503+
crate::info!(parent: &parent_span, "Test info with parent");
504+
crate::error!(parent: &parent_span, "Test error with parent", field = "parent_test");
505+
});
506+
507+
guard.shutdown_handler.shutdown().unwrap();
508+
509+
let output = output.lock().unwrap();
510+
let output = std::str::from_utf8(&output).unwrap();
511+
512+
assert!(output.contains("Test info with parent"));
513+
assert!(output.contains("Test error with parent"));
514+
assert!(output.contains("field") && output.contains("parent_test"));
515+
}
516+
}

0 commit comments

Comments
 (0)