@@ -418,6 +418,31 @@ def with_level(severity)
418418 end
419419 end
420420
421+ def with_context ( context )
422+ begin
423+ prev_context = @current_context [ Fiber . current ]
424+ @current_context [ Fiber . current ] = if prev_context . nil?
425+ context
426+ else
427+ case context
428+ when Hash
429+ prev_context . merge ( context )
430+ when Array
431+ prev_context + context
432+ # else throw error
433+ end
434+ end
435+
436+ yield
437+ ensure
438+ if prev_context . nil?
439+ @context_store . delete ( Fiber . current )
440+ else
441+ @context_store [ Fiber . current ] = prev_context
442+ end
443+ end
444+ end
445+
421446 # Program name to include in log messages.
422447 attr_accessor :progname
423448
@@ -607,6 +632,7 @@ def initialize(logdev, shift_age = 0, shift_size = 1048576, level: DEBUG,
607632 self . formatter = formatter
608633 @logdev = nil
609634 @level_override = { }
635+ @context_store = { } . compare_by_identity
610636 return unless logdev
611637 case logdev
612638 when File ::NULL
@@ -796,7 +822,23 @@ def level_key
796822 Fiber . current
797823 end
798824
799- def format_message ( severity , datetime , progname , msg , **kwargs )
800- ( @formatter || @default_formatter ) . call ( severity , datetime , progname , msg , **kwargs )
825+ def format_message ( severity , datetime , progname , msg , context : nil )
826+ current_context = @context_store [ Fiber . current ]
827+ formatter = @formatter || @default_formatter
828+
829+ case context
830+ when nil
831+ context ||= current_context
832+ when Hash
833+ context = context . merge ( current_context ) if current_context
834+ when Array
835+ context += current_context if current_context
836+ end
837+
838+ if context . nil?
839+ formatter . call ( severity , datetime , progname , msg )
840+ else
841+ formatter . call ( severity , datetime , progname , msg , context : context )
842+ end
801843 end
802844end
0 commit comments