class Logging::Logger

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.appenders.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

Attributes

additive[R]
caller_tracing[R]
name[R]
parent[R]

Public Class Methods

[]( name ) click to toggle source

Returns a logger instance for the given name.

# File lib/logging/logger.rb, line 45
def self.[]( name )
  repo = ::Logging::Repository.instance
  name = repo.to_key(name)
  logger = repo[name]
  return logger unless logger.nil?

  @mutex.synchronize do
    logger = repo[name]
    return logger unless logger.nil? # thread-safe double checking

    logger = instantiate(name)
    repo[name] = logger
    repo.children(name).each { |child| child.__send__(:parent=, logger) }
    logger
  end
end
define_log_methods( logger ) click to toggle source

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
# File lib/logging/logger.rb, line 84
def self.define_log_methods( logger )
  code = log_methods_for_level(logger.level)
  logger._meta_eval(code, __FILE__, __LINE__)
  logger
end
instantiate( *args )
Alias for: new
log_methods_for_level( level ) click to toggle source

This generator is used to define the log methods for the given `level`. This code is evaluated in the context of a Logger instance.

Returns log methods as a String

# File lib/logging/logger.rb, line 94
    def self.log_methods_for_level( level )
      code = []
      ::Logging::LEVELS.each do |name,num|
        code << <<-CODE
            undef :#{name}  if method_defined? :#{name}
            undef :#{name}? if method_defined? :#{name}?
        CODE

        if 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, @caller_tracing))
              true
            end
          CODE
        end
      end
      code.join("\n")
    end
new( *args ) click to toggle source

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

Calls superclass method
# File lib/logging/logger.rb, line 40
def self.new( *args )
  args.empty? ? super : self[args.shift]
end
Also aliased as: instantiate
new( name ) click to toggle source
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
# File lib/logging/logger.rb, line 145
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
root() click to toggle source

Returns the root logger.

# File lib/logging/logger.rb, line 30
def self.root
  ::Logging::Repository.instance[:root]
end

Public Instance Methods

log << "message" click to toggle source

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.

# File lib/logging/logger.rb, line 176
def <<( msg )
  @appenders.each {|a| a << msg}
  @parent << msg if @additive
end
Also aliased as: write
log <→ other click to toggle source

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

# File lib/logging/logger.rb, line 161
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
add( severity, message = nil ) {block} click to toggle source

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.

# File lib/logging/logger.rb, line 206
def add( lvl, data = nil, progname = nil )
  lvl = Integer(lvl)
  return false if lvl < level

  if data.nil?
    if block_given?
      data = yield
    else
      data = progname
    end
  end

  log_event(::Logging::LogEvent.new(@name, lvl, data, @caller_tracing))
  true
end
add_appenders( appenders ) click to toggle source

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

# File lib/logging/logger.rb, line 340
def add_appenders( *args )
  args.flatten.each do |arg|
    o = arg.kind_of?(::Logging::Appender) ? arg : ::Logging::Appenders[arg.to_s]
    raise ArgumentError, "unknown appender #{arg.inspect}" if o.nil?
    @appenders << o unless @appenders.include?(o)
  end
  self
end
additive = true click to toggle source

Sets the additivity of the logger. Acceptable values are true, 'true', false, 'false', or nil. In this case nil does not change the additivity

# File lib/logging/logger.rb, line 229
def additive=( val )
  @additive = case val
              when true, 'true'; true
              when false, 'false'; false
              when nil; @additive
              else raise ArgumentError, 'expecting a boolean' end
end
appenders() click to toggle source

Returns the list of appenders.

# File lib/logging/logger.rb, line 319
def appenders
  @appenders.dup
end
appenders = app click to toggle source

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

# File lib/logging/logger.rb, line 329
def appenders=( args )
  @appenders.clear
  add_appenders(*args) unless args.nil?
end
caller_tracing = true click to toggle source

Sets the caller tracing of the logger. Acceptable values are true, 'true', false, 'false', or nil. In this case nil does not change the tracing.

# File lib/logging/logger.rb, line 244
def caller_tracing=( val )
  @caller_tracing =
      case val
      when true, 'true'; true
      when false, 'false'; false
      when nil; @caller_tracing
      else raise ArgumentError, 'expecting a boolean' end
end
clear_appenders click to toggle source

Remove all appenders from this logger.

# File lib/logging/logger.rb, line 376
def clear_appenders( ) @appenders.clear end
has_own_level?() click to toggle source

Returns `true` if the logger has its own level defined.

# File lib/logging/logger.rb, line 313
def has_own_level?
  !@level.nil?
end
level → integer click to toggle source

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

# File lib/logging/logger.rb, line 258
def level
  return @level unless @level.nil?
  @parent.level
end
level = :all click to toggle source

Set the level for this logger. The level can be either a String, a Symbol, or an Integer. 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 produce an ArgumentError

log.level = Object
log.level = -1
log.level = 1_000_000_000_000
# File lib/logging/logger.rb, line 291
def level=( level )
  @level =
    if level.nil? then level
    else
      lvl = case level
            when String, Symbol; ::Logging::level_num(level)
            when Integer; 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( appenders ) click to toggle source

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.

# File lib/logging/logger.rb, line 357
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
write( msg )
Alias for: <<

Protected Instance Methods

define_log_methods( force = false ) click to toggle source

Define the logging methods for this logger based on the configured log level. If the level is nil, then we will ask our parent for it's level and define log levels accordingly. The force flag will skip this check.

Recursively call this method on all our children loggers.

# File lib/logging/logger.rb, line 411
def define_log_methods( force = false, code = nil )
  return if has_own_level? and !force

  ::Logging::Logger._reentrant_mutex.synchronize do
    ::Logging::Logger.define_log_methods(self)
    ::Logging::Repository.instance.children(name).each do |child|
      child.define_log_methods
    end
  end
  self
end
log_event( event ) click to toggle source

Send the given event to the appenders for logging, and pass the event up to the parent if additive mode is enabled. The log level has already been checked before this method is called.

# File lib/logging/logger.rb, line 396
def log_event( event )
  @appenders.each {|a| a.append(event)}
  @parent.log_event(event) if @additive
end
parent = ParentLogger click to toggle source

Set the parent logger for this logger. This method will be invoked by the Repository class when a parent or child is added to the hierarchy.

# File lib/logging/logger.rb, line 387
def parent=( parent ) @parent = parent end