Module: InjectedLogger

Defined in:
lib/injectedlogger.rb,
lib/injectedlogger/errors.rb,
lib/injectedlogger/logger.rb,
lib/injectedlogger/version.rb,
lib/injectedlogger/delegator.rb

Defined Under Namespace

Modules: Delegator Classes: Logger

Constant Summary collapse

Error =
Class.new StandardError
InUse =
Class.new Error
DefaultInjectionBlockMissing =
Class.new Error
UnsupportedLevels =
Class.new Error do
  def initalize(levels)
    super("logger does not support required levels #{levels.join ', '}")
  end
end
VERSION =
'0.0.8'

Class Method Summary collapse

Class Method Details

.after_injection(&blk) ⇒ Object



23
24
25
26
# File 'lib/injectedlogger/logger.rb', line 23

def self.after_injection(&blk)
  on = blk.binding.eval 'self'
  logger[on].after_hook = blk
end

.default_loggerObject



69
70
71
72
# File 'lib/injectedlogger.rb', line 69

def self.default_logger
  require 'logger'
  { logger: ::Logger.new(STDERR) }
end

.inject(*args, on:, **options) ⇒ Object



15
16
17
# File 'lib/injectedlogger/logger.rb', line 15

def self.inject(*args, on:, **options)
  logger[on].inject(*args, **options)
end

.inject!(*args, on:, **options) ⇒ Object



19
20
21
# File 'lib/injectedlogger/logger.rb', line 19

def self.inject!(*args, on:, **options)
  logger[on].inject!(*args, **options)
end

.inject_logger(args, required, on:) ⇒ Object



74
75
76
77
78
79
80
81
82
83
84
85
# File 'lib/injectedlogger.rb', line 74

def self.inject_logger(args, required, on:)
  args ||= {}
  args = default_logger.merge(args) unless args.has_key? :logger
  logger = args.delete :logger
  unless required.empty?
    args[:levels] ||= []
    args[:levels].push(required).flatten!
    args[:levels].uniq!
  end
  args[:on] = on
  InjectedLogger.inject(logger, **args)
end

.injected?(on:) ⇒ Boolean

Returns:

  • (Boolean)


11
12
13
# File 'lib/injectedlogger/logger.rb', line 11

def self.injected?(on:)
  logger[on].injected?
end

.use(*required, on: nil, method_name: :logger, &blk) ⇒ Object

inject a default logger in case no one has set one for you:

module MyLogger

InjectedLogger.use :info, :debug, :invented do
  require 'logger'
  # parameters are inject() params, none is required, but if
  # logger is not present, a default one will be used.
  { logger: Logger.new(STDERR), prefix: '[mylogger]', ... }
end

end

class WantsLogging

include MyLogger

def some_method_needing_logging
  logger.info 'some info'
end

def some_method_with_invented_level_logging
  logger.invented do
    'some invented logging'
  end
end

end

This will only run the block passed to inject IFF there was no logger set up to be used by InjectedLogger, and it will only happen the first time the logger method is called, so that it does not ‘require’ anything if it is not needed. :)



36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/injectedlogger.rb', line 36

def self.use(*required, on: nil, method_name: :logger, &blk)
  if on.nil?
    raise InjectedLogger::DefaultInjectionBlockMissing if blk.nil?
    on = blk.binding.eval 'self'
  else
    on = on.singleton_class unless on.is_a? Module
  end
  on.send :define_method, method_name do
    # avoid recursion if someone calls logger in the block
    on.send :remove_method, method_name
    unless InjectedLogger.injected? on: on
      args = blk ? blk.call : nil
      InjectedLogger.inject_logger args, required, on: on
    end
    thislogger = InjectedLogger.send(:logger).[](on)
    required.uniq!
    required -= thislogger.level_info[:supported]
    unless required.empty?
      thislogger.add_levels(*required)
      required -= thislogger.level_info[:supported]
      raise InjectedLogger::UnsupportedLevels.new(required) unless required.empty?
    end
    on.send :define_method, method_name do
      thislogger
    end
    thislogger.after_hook.call(thislogger) if thislogger.after_hook
    thislogger.send :ready
    thislogger
  end
end