@@ -457,18 +457,73 @@ def decorate(event, context, *args, **kwargs):
457
457
458
458
return decorate
459
459
460
- def _add_log_line_to_buffer (self , log_record : dict [str , Any ]):
461
- # Initial implementation, will always cache
462
- # Add logic for "empty"
460
+ def _create_and_flush_log_record (self , log_line : dict ) -> None :
461
+ """
462
+ Create and immediately flush a log record to the configured logger.
463
+
464
+ Parameters
465
+ ----------
466
+ log_line : dict[str, Any]
467
+ Dictionary containing log record details with keys:
468
+ - 'level': Logging level
469
+ - 'filename': Source filename
470
+ - 'line': Line number
471
+ - 'msg': Log message
472
+ - 'function': Source function name
473
+ - 'extra': Additional context
474
+ - 'timestamp': Original log creation time
475
+
476
+ Notes
477
+ -----
478
+ Bypasses standard logging flow by directly creating and handling a log record.
479
+ Preserves original timestamp and source information.
480
+ """
481
+ record = self ._logger .makeRecord (
482
+ name = self .name ,
483
+ level = log_line ["level" ],
484
+ fn = log_line ["filename" ],
485
+ lno = log_line ["line" ],
486
+ msg = log_line ["msg" ],
487
+ args = (),
488
+ exc_info = None ,
489
+ func = log_line ["function" ],
490
+ extra = log_line ["extra" ],
491
+ )
492
+ record .created = log_line ["timestamp" ]
493
+ self ._logger .handle (record )
494
+
495
+ def _add_log_record_to_buffer (
496
+ self ,
497
+ level : int ,
498
+ msg : object ,
499
+ args : object ,
500
+ exc_info : logging ._ExcInfoType ,
501
+ stack_info : bool ,
502
+ extra : Mapping [str , object ],
503
+ ):
463
504
tracer_id = os .getenv (constants .XRAY_TRACE_ID_ENV , None )
464
505
if tracer_id :
506
+ log_record : dict [str , Any ] = _create_buffer_record (level = level , msg = msg , args = args , extra = extra )
465
507
self ._buffer_cache .add (tracer_id , log_record )
466
508
467
509
def flush_buffer (self ):
468
- # Initial logic
510
+ """
511
+ Flush all buffered log records associated with current trace ID.
512
+
513
+ Notes
514
+ -----
515
+ Retrieves log records for current trace from buffer
516
+ Immediately processes and logs each record
517
+ Clears buffer after complete processing
518
+
519
+ Raises
520
+ ------
521
+ Any exceptions from underlying logging or buffer mechanisms
522
+ will be propagated to caller
523
+ """
469
524
tracer_id = os .getenv (constants .XRAY_TRACE_ID_ENV , None )
470
- for item in self ._buffer_cache .get (tracer_id ):
471
- self ._logger . debug ( item [ "msg" ] )
525
+ for log_line in self ._buffer_cache .get (tracer_id ):
526
+ self ._create_and_flush_log_record ( log_line )
472
527
473
528
self ._buffer_cache .clear ()
474
529
@@ -485,7 +540,16 @@ def debug(
485
540
extra = extra or {}
486
541
extra = {** extra , ** kwargs }
487
542
488
- # Buffer is not active, flushing
543
+ # Logging workflow for logging.debug:
544
+ # 1. Buffer is completely disabled - log right away
545
+ # 2. DEBUG is the maximum level of buffer, so, can't bypass if enabled
546
+ # 3. Store in buffer for potential later processing
547
+
548
+ # MAINTAINABILITY_DECISION:
549
+ # Keeping this implementation to avoid complex code handling.
550
+ # Also for clarity over complexity
551
+
552
+ # Buffer is not active and we need to log immediately
489
553
if not self ._logger_buffer :
490
554
return self ._logger .debug (
491
555
msg ,
@@ -496,9 +560,15 @@ def debug(
496
560
extra = extra ,
497
561
)
498
562
499
- log_record = _create_buffer_record (level = "DEBUG" , msg = msg , args = args , ** kwargs )
500
-
501
- self ._add_log_line_to_buffer (log_record )
563
+ # Store record in the buffer
564
+ self ._add_log_record_to_buffer (
565
+ level = logging .DEBUG ,
566
+ msg = msg ,
567
+ args = args ,
568
+ exc_info = exc_info ,
569
+ stack_info = stack_info ,
570
+ extra = extra ,
571
+ )
502
572
503
573
def info (
504
574
self ,
@@ -513,7 +583,16 @@ def info(
513
583
extra = extra or {}
514
584
extra = {** extra , ** kwargs }
515
585
516
- # Buffer is not active and we need to flush
586
+ # Logging workflow for logging.info:
587
+ # 1. Buffer is completely disabled - log right away
588
+ # 2. Log severity exceeds buffer's minimum threshold - bypass buffering
589
+ # 3. If neither condition met, store in buffer for potential later processing
590
+
591
+ # MAINTAINABILITY_DECISION:
592
+ # Keeping this implementation to avoid complex code handling.
593
+ # Also for clarity over complexity
594
+
595
+ # Buffer is not active and we need to log immediately
517
596
if not self ._logger_buffer :
518
597
return self ._logger .info (
519
598
msg ,
@@ -524,7 +603,7 @@ def info(
524
603
extra = extra ,
525
604
)
526
605
527
- # Buffer log level is higher than this log level and we need to flush
606
+ # Bypass buffer when log severity meets or exceeds configured minimum
528
607
if _check_minimum_buffer_log_level (self ._logger_buffer .minimum_log_level , "INFO" ):
529
608
return self ._logger .info (
530
609
msg ,
@@ -535,9 +614,15 @@ def info(
535
614
extra = extra ,
536
615
)
537
616
538
- log_record : dict [str , Any ] = _create_buffer_record (level = "INFO" , msg = msg , args = args , ** kwargs )
539
-
540
- self ._add_log_line_to_buffer (log_record )
617
+ # Store record in the buffer
618
+ self ._add_log_record_to_buffer (
619
+ level = logging .INFO ,
620
+ msg = msg ,
621
+ args = args ,
622
+ exc_info = exc_info ,
623
+ stack_info = stack_info ,
624
+ extra = extra ,
625
+ )
541
626
542
627
def warning (
543
628
self ,
@@ -552,7 +637,16 @@ def warning(
552
637
extra = extra or {}
553
638
extra = {** extra , ** kwargs }
554
639
555
- # Buffer is not active and we need to flush
640
+ # Logging workflow for logging.warning:
641
+ # 1. Buffer is completely disabled - log right away
642
+ # 2. Log severity exceeds buffer's minimum threshold - bypass buffering
643
+ # 3. If neither condition met, store in buffer for potential later processing
644
+
645
+ # MAINTAINABILITY_DECISION:
646
+ # Keeping this implementation to avoid complex code handling.
647
+ # Also for clarity over complexity
648
+
649
+ # Buffer is not active and we need to log immediately
556
650
if not self ._logger_buffer :
557
651
return self ._logger .warning (
558
652
msg ,
@@ -563,7 +657,7 @@ def warning(
563
657
extra = extra ,
564
658
)
565
659
566
- # Buffer log level is higher than this log level and we need to flush
660
+ # Bypass buffer when log severity meets or exceeds configured minimum
567
661
if _check_minimum_buffer_log_level (self ._logger_buffer .minimum_log_level , "WARNING" ):
568
662
return self ._logger .warning (
569
663
msg ,
@@ -574,9 +668,15 @@ def warning(
574
668
extra = extra ,
575
669
)
576
670
577
- log_record = _create_buffer_record (level = "WARNING" , msg = msg , args = args , ** kwargs )
578
-
579
- self ._add_log_line_to_buffer (log_record )
671
+ # Store record in the buffer
672
+ self ._add_log_record_to_buffer (
673
+ level = logging .WARNING ,
674
+ msg = msg ,
675
+ args = args ,
676
+ exc_info = exc_info ,
677
+ stack_info = stack_info ,
678
+ extra = extra ,
679
+ )
580
680
581
681
def error (
582
682
self ,
@@ -591,9 +691,11 @@ def error(
591
691
extra = extra or {}
592
692
extra = {** extra , ** kwargs }
593
693
594
- # Buffer is active and an error happened
595
- # LoggerBufferConfig flush_on_error is True
596
- # So, we need to flush the buffer
694
+ # Workflow: Error Logging with automatic buffer flushing
695
+ # 1. Buffer configuration checked for immediate flush
696
+ # 2. If auto-flush enabled, trigger complete buffer processing
697
+ # 3. Error log is not "bufferable", so ensure error log is immediately available
698
+
597
699
if self ._logger_buffer and self ._logger_buffer .flush_on_error :
598
700
self .flush_buffer ()
599
701
@@ -619,9 +721,10 @@ def critical(
619
721
extra = extra or {}
620
722
extra = {** extra , ** kwargs }
621
723
622
- # Buffer is active and an error happened
623
- # LoggerBufferConfig flush_on_error is True
624
- # So, we need to flush the buffer
724
+ # Workflow: Error Logging with automatic buffer flushing
725
+ # 1. Buffer configuration checked for immediate flush
726
+ # 2. If auto-flush enabled, trigger complete buffer processing
727
+ # 3. Critical log is not "bufferable", so ensure error log is immediately available
625
728
if self ._logger_buffer and self ._logger_buffer .flush_on_error :
626
729
self .flush_buffer ()
627
730
@@ -647,9 +750,10 @@ def exception(
647
750
extra = extra or {}
648
751
extra = {** extra , ** kwargs }
649
752
650
- # Buffer is active and an error happened
651
- # LoggerBufferConfig flush_on_error is True
652
- # So, we need to flush the buffer
753
+ # Workflow: Error Logging with automatic buffer flushing
754
+ # 1. Buffer configuration checked for immediate flush
755
+ # 2. If auto-flush enabled, trigger complete buffer processing
756
+ # 3. Exception log is not "bufferable", so ensure error log is immediately available
653
757
if self ._logger_buffer and self ._logger_buffer .flush_on_error :
654
758
self .flush_buffer ()
655
759
0 commit comments