1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211
|
# 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 <tt>:p</tt>.
#
# CREDITS:
#
# This code comes straight from the dev-utils Gem.
# Author: Gavin Sinclair <gsinclair@soyabean.com.au>
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
|