class DataObjects::Logger

Public DataObjects Logger API

Logger taken from Merb :)

To replace an existing logger with a new one:

DataObjects::Logger.set_log(log{String, IO},level{Symbol, String})

Available logging levels are

DataObjects::Logger::{ Fatal, Error, Warn, Info, Debug }

Logging via:

DataObjects.logger.fatal(message<String>)
DataObjects.logger.error(message<String>)
DataObjects.logger.warn(message<String>)
DataObjects.logger.info(message<String>)
DataObjects.logger.debug(message<String>)

Flush the buffer to

DataObjects.logger.flush

Remove the current log object

DataObjects.logger.close

Private DataObjects Logger API

To initialize the logger you create a new object, proxies to set_log.

DataObjects::Logger.new(log{String, IO},level{Symbol, String})

Logger will not create the file until something is actually logged This avoids file creation on DataObjects init when it creates the default logger.

Constants

LEVELS

Ruby (standard) logger levels:

off:   absolutely nothing
fatal: an unhandleable error that results in a program crash
error: a handleable error condition
warn:  a warning
info:  generic (useful) information about system operation
debug: low-level information for developers

DataObjects::Logger::LEVELS[:off, :fatal, :error, :warn, :info, :debug]

Message

Attributes

aio[RW]

Use asynchronous I/O?

buffer[R]

Direct access to the buffer

delimiter[RW]

delimiter to use between message sections

level[R]

a symbol representing the log level from {:off, :fatal, :error, :warn, :info, :debug}

log[R]

The name of the log file

Public Class Methods

new(*args) click to toggle source

To initialize the logger you create a new object, proxies to set_log.

DataObjects::Logger.new(log{String, IO},level{Symbol, String})

@param log<IO,String> either an IO object or a name of a logfile. @param log_level<String> the message string to be logged @param delimiter<String> delimiter to use between message sections @param log_creation<Boolean> log that the file is being created

# File lib/data_objects/logger.rb, line 167
def initialize(*args)
  set_log(*args)
end

Public Instance Methods

<<(string)
Alias for: push
close() click to toggle source

Close and remove the current log object.

DataObjects.logger.close
# File lib/data_objects/logger.rb, line 210
def close
  flush
  @log.close if @log.respond_to?(:close)
  @log = nil
end
flush() click to toggle source

Flush the entire buffer to the log object.

DataObjects.logger.flush
# File lib/data_objects/logger.rb, line 202
def flush
  return unless @buffer.size > 0
  @log.write_method(@buffer.slice!(0..-1).join)
end
level=(new_level) click to toggle source

Set the log level (use the level symbols as documented)

# File lib/data_objects/logger.rb, line 89
def level=(new_level)
  @level = LEVELS[new_level.to_sym]
  reset_methods(:close)
end
push(string) click to toggle source

Note that the string is discarded if the string's log level less than the logger's log level.

Note that if the logger is aio capable then the logger will use non-blocking asynchronous writes.

@param level<Fixnum> the logging level as an integer @param string<String> the message string to be logged

# File lib/data_objects/logger.rb, line 227
def push(string)
  internal_push(string)
end
Also aliased as: <<
set_log(log, log_level = :off, delimiter = " ~ ", log_creation = false) click to toggle source

To replace an existing logger with a new one:

DataObjects::Logger.set_log(log{String, IO},level{Symbol, String})

@param log<IO,String> either an IO object or a name of a logfile. @param log_level<Symbol> a symbol representing the log level from

{:off, :fatal, :error, :warn, :info, :debug}

@param delimiter<String> delimiter to use between message sections @param log_creation<Boolean> log that the file is being created

# File lib/data_objects/logger.rb, line 180
def set_log(log, log_level = :off, delimiter = " ~ ", log_creation = false)
  delimiter    ||= " ~ "

  if log_level && LEVELS[log_level.to_sym]
    self.level = log_level.to_sym
  else
    self.level = :debug
  end

  @buffer    = []
  @delimiter = delimiter

  initialize_log(log)

  DataObjects.logger = self

  self.info("Logfile created") if log_creation
end

Private Instance Methods

aio?() click to toggle source

Determine if asynchronous IO can be used

# File lib/data_objects/logger.rb, line 102
def aio?
  @aio = !RUBY_PLATFORM.match(/java|mswin/) &&
  !(@log == STDOUT) &&
  @log.respond_to?(:write_nonblock)
end
initialize_log(log) click to toggle source
# File lib/data_objects/logger.rb, line 118
def initialize_log(log)
  close if @log # be sure that we don't leave open files laying around.
  @log = log || "log/dm.log"
end
internal_push(string)
Alias for: push_closed
prep_msg(message, level) click to toggle source
# File lib/data_objects/logger.rb, line 154
def prep_msg(message, level)
  level << delimiter << message
end
push_closed(string) click to toggle source
# File lib/data_objects/logger.rb, line 140
def push_closed(string)
  unless @log.respond_to?(:write)
    log = Pathname(@log)
    log.dirname.mkpath
    @log = log.open('a')
    @log.sync = true
  end
  set_write_method
  reset_methods(:open)
  push(string)
end
Also aliased as: internal_push
push_opened(string) click to toggle source
# File lib/data_objects/logger.rb, line 131
def push_opened(string)
  message = Time.now.httpdate
  message << delimiter
  message << string
  message << "\n" unless message[-1] == ?\n
  @buffer << message
  flush # Force a flush for now until we figure out where we want to use the buffering.
end
reset_methods(o_or_c) click to toggle source
# File lib/data_objects/logger.rb, line 123
def reset_methods(o_or_c)
  if o_or_c == :open
    alias internal_push push_opened
  elsif o_or_c == :close
    alias internal_push push_closed
  end
end
set_write_method() click to toggle source

The idea here is that instead of performing an 'if' conditional check on each logging we do it once when the log object is setup

# File lib/data_objects/logger.rb, line 98
def set_write_method
  @log.instance_eval do

    # Determine if asynchronous IO can be used
    def aio?
      @aio = !RUBY_PLATFORM.match(/java|mswin/) &&
      !(@log == STDOUT) &&
      @log.respond_to?(:write_nonblock)
    end

    # Define the write method based on if aio an be used
    undef write_method if defined? write_method
    if aio?
      alias :write_method :write_nonblock
    else
      alias :write_method :write
    end
  end
end