@@ -152,6 +152,19 @@ macro_rules! debug {
152
152
} ;
153
153
}
154
154
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
+
155
168
/// Export a log message at the specified level.
156
169
///
157
170
/// # Syntax
@@ -255,3 +268,249 @@ macro_rules! log {
255
268
$crate:: __macros_impl:: log!( parent: tracing:: Span :: current( ) , $level, $format, $( $( $path) .+ $( = $value) ?) ,* )
256
269
} ;
257
270
}
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