Parent

Files

Needle::LogFactory

A factory class that returns Logger instances. Since each registry has its own logger factory, the logger factory must be separately instantiable.

Constants

DEFAULT_LOG_FILENAME

The default name of the log file to write to.

DEFAULT_MESSAGE_FORMAT

The default format of the log messages (see Logger for more info)

LEVEL_TRANSLATOR

Translate names of levels to their actual values.

VALID_LEVEL_OPTIONS
VALID_OPTIONS

Attributes

default_date_format[R]

The default date format string to use when logging.

default_level[R]

The default log level to use for logs that are created.

default_message_format[R]

The default message format string to use when logging.

device[R]

The device that logs will write to.

Public Class Methods

new( opts={} ) click to toggle source

Create a new LogFactory using the given initialization parameters. The valid options are:

  • :device: the device (pseudo-IO object) to write log messages to. Either this, or :filename must be specified.

  • :filename: the filename of the log to write to.

  • :roll_age: the number of days before the log should be rolled.

  • :roll_frequency: either 'daily', 'weekly', or 'monthly'.

  • :roll_size: the maximum size of a log file.

  • :default_date_format: the default date format string for the log.

  • :default_message_format: the default message format string for the log.

  • :default_level: the default log level for the log.

  • :levels: a hash of patterns that map to a hash of 'level' 'date_format', and 'message_format' keys, specifying the log level, date format, and message format for any log whose name matches the key.

# File lib/needle/log-factory.rb, line 80
def initialize( opts={} )
  opts = convert_keys_to_symbols( opts )
  bad = opts.keys - VALID_OPTIONS
  raise ArgumentError,
    "invalid option(s) to LogFactory (#{bad.inspect})" unless bad.empty?

  if opts[:device]
    @device = opts[:device]
  else
    filename = opts[:filename] || DEFAULT_LOG_FILENAME
    roll_age = opts[:roll_age ] || opts[:roll_frequency] || 0
    roll_size = opts[:roll_size] || 0
    @device = Logger::LogDevice.new( filename,
      :shift_age=>roll_age, :shift_size=>roll_size )
  end

  @default_date_format = opts[:default_date_format]
  @default_message_format = opts[:default_message_format] ||
    DEFAULT_MESSAGE_FORMAT
  @default_level = opts[:default_level]

  if @default_level.is_a?( String ) || @default_level.is_a?( Symbol )
    @default_level = LEVEL_TRANSLATOR[@default_level.to_s.upcase]
    if @default_level.nil?
      raise ArgumentError,
        "invalid logging level (#{@default_level.inspect})"
    end
  end

  @levels = Hash.new :level => nil, :date_format => nil,
    :message_format => nil

  ( opts[:levels] || {} ).each_pair do |key, value|
    key = Regexp.new( "^" + key.gsub( /\./, "\\." ).gsub( /\*/, ".*" ) )

    if value.is_a?( String ) || value.is_a?( Symbol )
      value = { :level => value.to_s }
    else
      value = convert_keys_to_symbols( value )
    end

    bad = value.keys - VALID_LEVEL_OPTIONS
    raise ArgumentError, 
      "invalid log level option(s) #{bad.inspect}" unless bad.empty?

    value[ :level ] = LEVEL_TRANSLATOR[ value[:level].to_s.upcase ]
    if value[:level].nil?
      raise ArgumentError,
        "invalid logging level (#{value[:level].inspect})"
    end

    @levels[ key ] = value
  end

  @loggers = Hash.new
  @mutex = Mutex.new
  @closed = false
end

Public Instance Methods

close() click to toggle source

Closes the logging device and makes this factory invalid for future accesses.

# File lib/needle/log-factory.rb, line 218
def close
  @mutex.synchronize do
    return if @closed

    if @device
      @device.close unless [ $stdout, $stderr ].include?( @device )
    end

    @loggers = nil
    @closed = true
  end
end
closed?() click to toggle source

Returns true if the factory has been closed.

# File lib/needle/log-factory.rb, line 232
def closed?
  @closed
end
get( name ) click to toggle source

Retrieves the logger with the given name. If no such log has been created, the log will be created and initialized. Otherwise, the log with the given name is returned.

If name responds to either fullname or name, then the result of invoking that message on name will be used as the name.

# File lib/needle/log-factory.rb, line 184
def get( name )
  name = name.fullname if name.respond_to?( :fullname )
  name = name.name if name.respond_to?( :name )
  name = name.to_s

  # the common case first, outside the synchronize, for speed
  return @loggers[ name ] if @loggers[ name ]

  @mutex.synchronize do
    # check again, inside the synchronize, to avoid race conditions
    return @loggers[ name ] if @loggers[ name ]

    definition = find_definition( name )

    level = definition[ :level ] || @default_level
    date_format = definition[ :date_format ] || @default_date_format
    message_format = definition[ :message_format ] ||
      @default_message_format

    level = LEVEL_TRANSLATOR[ level.to_s.upcase ] || level

    logger = Needle::Logger.new( @device )
    logger.level = level if level
    logger.progname = name
    logger.datetime_format = date_format if date_format
    logger.message_format = message_format if message_format

    @loggers[ name ] = logger
    return logger
  end
end
write_to( device, shift_age = 0, shift_size = 1048576 ) click to toggle source

Changes the device that the loggers write to. Every log that was created by this log factory will be changed to use the given device.

# File lib/needle/log-factory.rb, line 141
def write_to( device, shift_age = 0, shift_size = 1048576 )
  saved_critical = Thread.critical
  Thread.critical = true

  @device.close if @device unless [ $stdout, $stderr ].include?( @device )
  if device.respond_to?( :write ) && device.respond_to?( :close )
    @device = device
  else
    @device = Logger::LogDevice.new( device.to_str,
      :shift_age => shift_age, 
      :shift_size => shift_size )
  end

  @loggers.each_value { |logger| logger.write_to( @device ) }
  device

ensure
  Thread.critical = saved_critical
end

[Validate]

Generated with the Darkfish Rdoc Generator 2.