Class: RooOnRails::Logger

Inherits:
SimpleDelegator
  • Object
show all
Defined in:
lib/roo_on_rails/logger.rb

Overview

A compatible replacement for the standard Logger to provide context, similar to ‘ActiveSupport::TaggedLogging` but with key/value pairs in logfmt format.

logger = RooOnRails::Logger.new(STDOUT)
logger.with(a: 1, b: 2) { logger.info 'Stuff' }
# Logs "at=INFO msg=Stuff a=1 b=2"

logger.with(a: 1) { logger.with(b: 2) { logger.info('Stuff') } }
# Logs "at=INFO msg=Stuff a=1 b=2"

The above methods persist the context in thread local storage so it will be attached to any logs made within the scope of the block, even in called methods. However, if your context only applies to the current log then you can chain off the ‘with` method.

logger.with(a: 1, b: 2).info('Stuff')
# Logs "at=INFO msg=Stuff a=1 b=2"

logger.with(a: 1) { logger.with(b: 2).info('Stuff')  }
# Logs "at=INFO msg=Stuff a=1 b=2"

Hashes, arrays and any complex object that supports ‘#to_json` will be output in escaped JSON format so that it can be parsed out of the attribute values.

Instance Method Summary collapse

Constructor Details

#initialize(io = STDOUT) ⇒ Logger

Returns a new instance of Logger.



32
33
34
35
36
37
38
# File 'lib/roo_on_rails/logger.rb', line 32

def initialize(io = STDOUT)
  @show_timestamp = io.tty?
  logger = ActiveSupport::Logger.new(io).tap do |l|
    l.formatter = method(:_formatter)
  end
  super(logger)
end

Instance Method Details

#set_log_level(default: :DEBUG) ⇒ Object



57
58
59
60
61
62
63
# File 'lib/roo_on_rails/logger.rb', line 57

def set_log_level(default: :DEBUG)
  selected_level = ::Logger::Severity.constants.detect do |log_level|
    log_level == log_level_setting.upcase.to_sym
  end

  self.level = ::Logger::Severity.const_get(selected_level || default.upcase)
end

#with(context = {}) ⇒ Object



40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/roo_on_rails/logger.rb', line 40

def with(context = {})
  return Proxy.new(self, context) unless block_given?

  new_context = (_context_stack.last || {}).merge(context)
  Thread.handle_interrupt(Exception => :never) do
    begin
      _context_stack.push(new_context)
      Thread.handle_interrupt(Exception => :immediate) do
        yield self
      end
    ensure
      _context_stack.pop
    end
  end
  nil
end