# Ansi::Logger
# Copyright (c) 2009 Thomas Sawyer
# Copyright (c) 2005 George Moschovitis
require "logger"
require "time"
require "ansi/code"
# = ANSI::Logger
#
# Extended variation of Ruby's standard Logger library that supports
# color output.
#
# log = ANSI::Logger.new
#
# log.formatter do |severity, timestamp, progname, msg|
# ANSI::Logger::SIMPLE_FORMAT % [severity, msg]
# end
#
#--
# TODO: What's all this about then?
#
# When using debug level logger messages always append 'if $DBG'
# at the end. This hack is needed because Ruby does not support
# lazy evaluation (lisp macros).
#++
class ANSI::Logger < Logger
# Some available logging formats.
SIMPLE_FORMAT = "%5s: %s\n"
DETAILED_FORMAT = "%s %5s: %s\n"
# TODO: Not sure I like this approach.
class ::Logger #:nodoc:
class LogDevice #:nodoc:
attr_writer :ansicolor
def ansicolor?
@ansicolor.nil? ? true : @ansicolor
end
end
end
#
def ansicolor?
@logdev.ansicolor?
end
#
def ansicolor=(on)
@logdev.ansicolor = on
end
# Dictate the way in which this logger should format the
# messages it displays. This method requires a block. The
# block should return formatted strings given severity,
# timestamp, progname and msg.
#
# === Example
#
# logger = ANSI::Logger.new
#
# logger.formatter do |severity, timestamp, progname, msg|
# "#{progname}@#{timestamp} - #{severity}::#{msg}"
# end
#
def formatter(&block)
self.formatter = block if block
super
end
def styles(options=nil)
@styles ||= {
:info => [],
:warn => [:yellow],
:debug => [:cyan],
:error => [:red],
:fatal => [:bold, :red]
}
@styles.merge!(options) if options
@styles
end
#
def info(progname=nil, &block)
return unless info?
@logdev.ansicolor? ? info_with_color{ super } : super
end
#
def warn(progname=nil, &block)
return unless warn?
@logdev.ansicolor? ? warn_with_color{ super } : super
end
#
def debug(progname=nil, &block)
return unless debug?
@logdev.ansicolor? ? debug_with_color{ super } : super
end
#
def error(progname=nil, &block)
return unless error?
@logdev.ansicolor? ? error_with_color{ super } : super
end
#
def fatal(progname=nil, &block)
return unless error?
@logdev.ansicolor? ? fatal_with_color{ super } : super
end
private
def info_with_color #:yield:
styles[:info].each{ |s| self << ANSI::Code.send(s) }
yield
self << ANSI::Code.clear
end
def warn_with_color #:yield:
styles[:warn].each{ |s| self << ANSI::Code.send(s) }
yield
self << ANSI::Code.clear
end
def error_with_color #:yield:
styles[:error].each{ |s| self << ANSI::Code.send(s) }
yield
self << ANSI::Code.clear
end
def debug_with_color #:yield:
styles[:debug].each{ |s| self << ANSI::Code.send(s) }
yield
self << ANSI::Code.clear
end
def fatal_with_color #:yield:
styles[:fatal].each{ |s| self << ANSI::Code.send(s) }
yield
self << ANSI::Code.clear
end
end
# NOTE: trace is deprecated b/c binding of caller is no longer possible.
=begin
# 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
raise "FACETS: binding/or_caller is no longer possible"
require "facets/core/binding/self/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
)
=end