Class: Logging::Logger

Inherits:
Object show all
Defined in:
lib/gems/logging-0.9.4/lib/logging/logger.rb

Overview

The Logger class is the primary interface to the Logging framework. It provides the logging methods that will be called from user methods, and it generates logging events that are sent to the appenders (the appenders take care of sending the log events to the logging destinations – files, sockets, etc).

Logger instances are obtained from the Repository and should not be directly created by users.

Example:

log = Logging::Logger['my logger']
log.add_appenders( Logging::Appender.stdout )   # append to STDOUT
log.level = :info                               # log 'info' and above

log.info 'starting foo operation'
...
log.info 'finishing foo operation'
...
log.fatal 'unknown exception', exception

Direct Known Subclasses

RootLogger

Instance Attribute Summary collapse

Class Method Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(name) ⇒ Logger

call-seq:

Logger.new( name )
Logger[name]

Returns the logger identified by name.

When name is a String or a Symbol it will be used “as is” to retrieve the logger. When name is a Class the class name will be used to retrieve the logger. When name is an object the name of the object’s class will be used to retrieve the logger.

Example:

obj = MyClass.new

log1 = Logger.new(obj)
log2 = Logger.new(MyClass)
log3 = Logger['MyClass']

log1.object_id == log2.object_id         # => true
log2.object_id == log3.object_id         # => true


138
139
140
141
142
143
144
145
146
# File 'lib/gems/logging-0.9.4/lib/logging/logger.rb', line 138

def initialize( name )
  case name
  when String
    raise(ArgumentError, "logger must have a name") if name.empty?
  else raise(ArgumentError, "logger name must be a String") end

  repo = ::Logging::Repository.instance
  _setup(name, :parent => repo.parent(name))
end

Instance Attribute Details

#additiveObject

class << self



114
115
116
# File 'lib/gems/logging-0.9.4/lib/logging/logger.rb', line 114

def additive
  @additive
end

#nameObject (readonly)

class << self



114
115
116
# File 'lib/gems/logging-0.9.4/lib/logging/logger.rb', line 114

def name
  @name
end

#parentObject

class << self



114
115
116
# File 'lib/gems/logging-0.9.4/lib/logging/logger.rb', line 114

def parent
  @parent
end

#traceObject

class << self



114
115
116
# File 'lib/gems/logging-0.9.4/lib/logging/logger.rb', line 114

def trace
  @trace
end

Class Method Details

.define_log_methods(logger) ⇒ Object

This is where the actual logging methods are defined. Two methods are created for each log level. The first is a query method used to determine if that perticular logging level is enabled. The second is the actual logging method that accepts a list of objects to be logged or a block. If a block is given, then the object returned from the block will be logged.

Example

log = Logging::Logger['my logger']
log.level = :warn

log.info?                               # => false
log.warn?                               # => true
log.warn 'this is your last warning'
log.fatal 'I die!', exception

log.debug do
  # expensive method to construct log message
  msg
end


85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
# File 'lib/gems/logging-0.9.4/lib/logging/logger.rb', line 85

def define_log_methods( logger )
  ::Logging::LEVELS.each do |name,num|
    code =  "undef :#{name}  if method_defined? :#{name}\n"
    code << "undef :#{name}? if method_defined? :#{name}?\n"

    if logger.level > num
      code << <<-CODE
        def #{name}?( ) false end
        def #{name}( data = nil ) false end
      CODE
    else
      code << <<-CODE
        def #{name}?( ) true end
        def #{name}( data = nil )
          data = yield if block_given?
          log_event(::Logging::LogEvent.new(@name, #{num}, data, @trace))
          true
        end
      CODE
    end

    logger._meta_eval(code, __FILE__, __LINE__)
  end
  logger
end

.new(*args) ⇒ Object Also known as: []

Overrides the new method such that only one Logger will be created for any given logger name.



45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
# File 'lib/gems/logging-0.9.4/lib/logging/logger.rb', line 45

def new( *args )
  return super if args.empty?

  repo = ::Logging::Repository.instance
  name = repo.to_key(args.shift)

  @mutex.synchronize do
    logger = repo[name]
    if logger.nil?
      logger = super(name, *args)
      repo[name] = logger
      repo.children(name).each {|c| c.__send__(:parent=, logger)}
    end
    logger
  end
end

.rootObject

call-seq:

Logger.root

Returns the root logger.



36
37
38
# File 'lib/gems/logging-0.9.4/lib/logging/logger.rb', line 36

def root
  ::Logging::Repository.instance[:root]
end

Instance Method Details

#<<(msg) ⇒ Object

call-seq:

log << "message"

Log the given message without any formatting and without performing any level checks. The message is logged to all appenders. The message is passed up the logger tree if this logger’s additivity is true.



169
170
171
172
# File 'lib/gems/logging-0.9.4/lib/logging/logger.rb', line 169

def <<( msg )
  @appenders.each {|a| a << msg}
  @parent << msg if @additive
end

#<=>(other) ⇒ Object

call-seq:

log <=> other

Compares this logger by name to another logger. The normal return codes for String objects apply.



154
155
156
157
158
159
160
# File 'lib/gems/logging-0.9.4/lib/logging/logger.rb', line 154

def <=>( other )
  case other
  when self; 0
  when ::Logging::RootLogger; 1
  when ::Logging::Logger; @name <=> other.name
  else raise ArgumentError, 'expecting a Logger instance' end
end

#_dump_configuration(io = STDOUT, indent = 0) ⇒ Object

call-seq:

_dump_configuration( io = STDOUT, indent = 0 )

An internal method that is used to dump this logger’s configuration to the given io stream. The configuration includes the logger’s name, level, additivity, and trace settings. The configured appenders are also printed to the io stream.



442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
460
461
462
463
464
465
466
467
468
469
470
471
472
473
474
475
476
477
478
479
480
481
482
483
484
# File 'lib/gems/logging-0.9.4/lib/logging/logger.rb', line 442

def _dump_configuration( io = STDOUT, indent = 0 )
  str, spacer, base = '', '  ', 50
  indent_str = indent == 0 ? '' : ' ' * indent

  str << indent_str
  str << self.name.reduce(base - indent)
  if (str.length + spacer.length) < base
    str << spacer
    str << '.' * (base - str.length)
  end
  io.print(str.ljust(base))
  io.print(spacer)

  level_str  = @level.nil? ? '' : '*'
  level_str << if level < ::Logging::LEVELS.length
    ::Logging.levelify(::Logging::LNAMES[level])
  else
    'off'
  end
  level_len = ::Logging::MAX_LEVEL_LENGTH + 1

  io.print("%#{level_len}s" % level_str)
  io.print(spacer)

  if self.respond_to?(:additive)
    io.print(additive ? '+A' : '-A')
  else
    io.print('  ')
  end

  io.print(spacer)
  io.print(trace ? '+T' : '-T')
  io.print("\n")

  @appenders.each do |appender|
    io.print(indent_str)
    io.print('- ')
    io.print(appender.inspect)
    io.print("\n")
  end

  return io
end

#_meta_eval(code, file = nil, line = nil) ⇒ Object

call-seq:

_meta_eval( code )

Evaluates the given string of code if the singleton class of this Logger object.



413
414
415
416
# File 'lib/gems/logging-0.9.4/lib/logging/logger.rb', line 413

def _meta_eval( code, file = nil, line = nil )
  meta = class << self; self end
  meta.class_eval code, file, line
end

#_setup(name, opts = {}) ⇒ Object

call-seq:

_setup( name, opts = {} )

Configures internal variables for the logger. This method can be used to avoid storing the logger in the repository.



424
425
426
427
428
429
430
431
432
# File 'lib/gems/logging-0.9.4/lib/logging/logger.rb', line 424

def _setup( name, opts = {} )
  @name      = name
  @parent    = opts.getopt(:parent)
  @appenders = opts.getopt(:appenders, [])
  @additive  = opts.getopt(:additive, true)
  @trace     = opts.getopt(:trace, false)
  @level     = opts.getopt(:level)
  ::Logging::Logger.define_log_methods(self)
end

#add(lvl, data = nil) ⇒ Object

call-seq:

add( severity, message = nil ) {block}

Log a message if the given severity is high enough. This is the generic logging method. Users will be more inclined to use #debug, #info, #warn, #error, and #fatal.

Message format: message can be any object, but it has to be converted to a String in order to log it. The Logging::format_as method is used to determine how objects chould be converted to strings. Generally, inspect is used.

A special case is an Exception object, which will be printed in detail, including message, class, and backtrace.

If a message is not given, then the return value from the block is used as the message to log. This is useful when creating the actual message is an expensive operation. This allows the logger to check the severity against the configured level before actually constructing the message.

This method returns true if the message was logged, and false is returned if the message was not logged.



198
199
200
201
202
203
204
205
# File 'lib/gems/logging-0.9.4/lib/logging/logger.rb', line 198

def add( lvl, data = nil )
  lvl = Integer(lvl)
  return false if lvl < level

  data = yield if block_given?
  log_event(::Logging::LogEvent.new(@name, lvl, data, @trace))
  true
end

#add_appenders(*args) ⇒ Object

call-seq:

add_appenders( appenders )

Add the given appenders to the list of appenders, where appenders can be either a single appender or an array of appenders.



313
314
315
316
317
318
319
320
# File 'lib/gems/logging-0.9.4/lib/logging/logger.rb', line 313

def add_appenders( *args )
  args.flatten.each do |arg|
    o = arg.kind_of?(::Logging::Appender) ? arg : ::Logging::Appender[arg]
    raise ArgumentError, "unknown appender '#{arg}'" if o.nil?
    @appenders << o unless @appenders.include?(o)
  end
  self
end

#appenders=(args) ⇒ Object

call-seq:

appenders = app

Clears the current list of appenders and replaces them with app, where app can be either a single appender or an array of appenders.



302
303
304
305
# File 'lib/gems/logging-0.9.4/lib/logging/logger.rb', line 302

def appenders=( args )
  @appenders.clear
  add_appenders(*args) unless args.nil?
end

#clear_appendersObject

call-seq:

clear_appenders

Remove all appenders from this logger.



349
# File 'lib/gems/logging-0.9.4/lib/logging/logger.rb', line 349

def clear_appenders( ) @appenders.clear end

#inspectObject

call-seq:

inspect    => string

Returns a string representation of the logger.



356
357
358
# File 'lib/gems/logging-0.9.4/lib/logging/logger.rb', line 356

def inspect
  "<%s:0x%x name=\"%s\">" % [self.class.name, self.object_id, self.name]
end

#levelObject

call-seq:

level    => integer

Returns an integer which is the defined log level for this logger.



242
243
244
245
# File 'lib/gems/logging-0.9.4/lib/logging/logger.rb', line 242

def level
  return @level unless @level.nil?
  @parent.level
end

#level=(level) ⇒ Object

call-seq:

level = :all

Set the level for this logger. The level can be either a String, a Symbol, or a Fixnum. An ArgumentError is raised if this is not the case.

There are two special levels – “all” and “off”. The former will enable log messages from this logger. The latter will disable all log messages from this logger.

Setting the logger level to nil will cause the parent’s logger level to be used.

Example:

log.level = :debug
log.level = "INFO"
log.level = 4
log.level = 'off'
log.level = :all

These prodcue an ArgumentError

log.level = Object
log.level = -1
log.level = 1_000_000_000_000


275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
# File 'lib/gems/logging-0.9.4/lib/logging/logger.rb', line 275

def level=( level )
  @level =
    if level.nil? then level
    else
      lvl = case level
            when String, Symbol; ::Logging::level_num(level)
            when Fixnum; level
            else
              raise ArgumentError,
                    "level must be a String, Symbol, or Integer"
            end
      if lvl.nil? or lvl < 0 or lvl > ::Logging::LEVELS.length
        raise ArgumentError, "unknown level was given '#{level}'"
      end
      lvl
    end

  define_log_methods(true)
  self.level
end

#remove_appenders(*args) ⇒ Object

call-seq:

remove_appenders( appenders )

Remove the given appenders from the list of appenders. The appenders to remove can be identified either by name using a String or by passing the appender instance. appenders can be a single appender or an array of appenders.



330
331
332
333
334
335
336
337
338
339
340
341
342
# File 'lib/gems/logging-0.9.4/lib/logging/logger.rb', line 330

def remove_appenders( *args )
  args.flatten.each do |arg|
    @appenders.delete_if do |a|
      case arg
      when String; arg == a.name
      when ::Logging::Appender; arg.object_id == a.object_id
      else
        raise ArgumentError, "#{arg.inspect} is not a 'Logging::Appender'"
      end
    end
  end
  self
end