Class: ContextualLogger::LoggerWithContext

Inherits:
Object
  • Object
show all
Includes:
LoggerMixin
Defined in:
lib/contextual_logger/logger_with_context.rb

Overview

A logger that deep_merges additional context and then delegates to the given logger. Keeps it own log level (called override_level) that may be set independently of the logger it delegates to. If override_level is non-nil, it takes precedence; if it is nil (the default), then it delegates to the logger.

Context Precedence:

  1. inline **context passed to the logger method

  2. ‘with_context` overrides on this LoggerWithContext object

  3. context passed to this LoggerWithContext constructor

  4. ‘with_context` overrides on the logger passed to this constructor

  5. ‘global_context` set on the logger passed to this constructor

Constant Summary

Constants included from Context

Context::EMPTY_CONTEXT

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Methods included from LoggerMixin

#add, #current_context, #global_context=, #log_level_enabled?, #with_context

Methods included from Context

#current_context_override, #current_context_override=, #thread_context_key_for_logger_instance

Constructor Details

#initialize(logger, context, level: nil) ⇒ LoggerWithContext

Returns a new instance of LoggerWithContext.



21
22
23
24
25
26
# File 'lib/contextual_logger/logger_with_context.rb', line 21

def initialize(logger, context, level: nil)
  logger.is_a?(LoggerMixin) or raise ArgumentError, "logger must include ContextualLogger::LoggerMixin (got #{logger.inspect})"
  @logger = logger
  self.level = level
  @context = normalize_context(context)
end

Instance Attribute Details

#contextObject (readonly)

Returns the value of attribute context.



19
20
21
# File 'lib/contextual_logger/logger_with_context.rb', line 19

def context
  @context
end

#loggerObject (readonly)

Returns the value of attribute logger.



19
20
21
# File 'lib/contextual_logger/logger_with_context.rb', line 19

def logger
  @logger
end

#override_levelObject (readonly)

Returns the value of attribute override_level.



19
20
21
# File 'lib/contextual_logger/logger_with_context.rb', line 19

def override_level
  @override_level
end

Class Method Details

.for_log_source(logger, log_source, level: nil) ⇒ Object



81
82
83
# File 'lib/contextual_logger/logger_with_context.rb', line 81

def for_log_source(logger, log_source, level: nil)
  new(logger, { log_source: log_source }, level: level)
end

Instance Method Details

#global_contextObject

TODO: It’s a (small) bug that the global_context is memoized at this point. There’s a chance that the @logger.current_context changes after this because of an enclosing @logger.with_context block. If that happens, we’ll miss that extra context. The tradeoff is that we don’t want to keep calling deep_merge.



31
32
33
# File 'lib/contextual_logger/logger_with_context.rb', line 31

def global_context
  @global_context ||= @logger.current_context.deep_merge(@context) # this will include any with_context overrides on the `logger`
end

#levelObject



35
36
37
# File 'lib/contextual_logger/logger_with_context.rb', line 35

def level
  @override_level || @logger.level
end

#level=(override_level) ⇒ Object



39
40
41
# File 'lib/contextual_logger/logger_with_context.rb', line 39

def level=(override_level)
  @override_level = (ContextualLogger.normalize_log_level(override_level) if override_level)
end

#write_entry_to_log(severity, timestamp, progname, message, context:) ⇒ Object



49
50
51
52
53
54
55
56
57
58
# File 'lib/contextual_logger/logger_with_context.rb', line 49

def write_entry_to_log(severity, timestamp, progname, message, context:)
  merged_context =
    if context.any?
      current_context.deep_merge(context)
    else
      current_context
    end

  @logger.write_entry_to_log(severity, timestamp, progname, message, context: merged_context)
end