require 'logger'
# A simple wrapper arround the Ruby logger. Mainly for
# compatibility purposes.
#
#--
# TODO: implement as mixin that can be added to Log4R.
#++
class Logger
alias_method :devel, :debug
alias_method :fine, :debug
# Prints a trace message to DEBUGLOG (at debug level).
# Useful for emitting the value of variables, etc. Use
# like this:
#
# x = y = 5
# trace 'x' # -> 'x = 5'
# trace 'x ** y' # -> 'x ** y = 3125'
#
# If you have a more complicated value, like an array of
# hashes, then you'll probably want to use an alternative
# output format. For instance:
#
# trace 'value', :yaml
#
# Valid output format values (the _style_ parameter) are:
#
# :p :inspect
# :pp (pretty-print, using 'pp' library)
# :s :to_s
# :y :yaml :to_yaml (using the 'yaml' library')
#
# The default is :p.
#
# CREDITS:
#
# This code comes straight from the dev-utils Gem.
# Author: Gavin Sinclair
def trace(expr, style=:p)
unless expr.respond_to? :to_str
warn "trace: Can't evaluate the given value: #{caller.first}"
else
require 'facet/binding-of-caller'
Binding.of_caller do |b|
value = b.eval(expr.to_str)
formatter = TRACE_STYLES[style] || :inspect
case formatter
when :pp then require 'pp'
when :y, :yaml, :to_yaml then require 'yaml'
end
value_s = value.send(formatter)
message = "#{expr} = #{value_s}"
lines = message.split(/\n/)
indent = " "
debug(lines.shift)
lines.each do |line|
debug(indent + line)
end
end
end
end
TRACE_STYLES = {} # :nodoc:
TRACE_STYLES.update(
:pp => :pp_s, :s => :to_s, :p => :inspect,
:y => :to_yaml, :yaml => :to_yaml,
:inspect => :inspect, :to_yaml => :to_yaml
)
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Global logger interface.
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
# Override the logger with your custom version.
@@global_logger = Logger.new(STDERR)
# Set the global Logger.
def self.set(logger)
if logger.is_a?(String)
@@global_logger = Logger.new(logger)
elsif logger.is_a?(Logger)
@@global_logger = logger
else
raise ArgumentError.new
end
end
def self.get
@@global_logger
end
def self.warn(str)
@@global_logger.warn(str)
end
def self.info(str)
@@global_logger.info(str)
end
def self.debug(str)
@@global_logger.debug(str)
end
def self.error(str)
@@global_logger.error(str)
end
#--
# Saddly have to duplicate the code to make
# Binding.of_caller work.
#++
def self.trace(expr, style=:p)
unless expr.respond_to? :to_str
warn "trace: Can't evaluate the given value: #{caller.first}"
else
require 'facet/binding-of-caller'
Binding.of_caller do |b|
value = eval(expr.to_str, b)
formatter = TRACE_STYLES[style] || :inspect
case formatter
when :pp then require 'pp'
when :y, :yaml, :to_yaml then require 'yaml'
end
value_s = value.send(formatter)
message = "#{expr} = #{value_s}"
lines = message.split(/\n/)
indent = " "
debug(lines.shift)
lines.each do |line|
debug(indent + line)
end
end
end
end
# - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - -
private
# the default Ruby logger has a hardwired silly format.
# we use some Ruby magic to fix it!
remove_const "Format"
Format = "%5s: %s\n"
def format_message(severity, timestamp, msg, progname)
Format % [severity, msg]
end
end
module Glue
# Add logging capabilities to the including class.
# When using the log/logger variables always check
# for nil:
#
# log.info "your #{expensive_calculation} comes here" if @log
#
# This way the expensive calculation is avoided if the
# logger is dissabled (@log == nil).
module Logging
attr_accessor :logger
alias_method :log, :logger
end
end
# * George Moschovitis