Class: RMTools::RMLogger
Overview
Lazy logger with timer, coloring and caller hints Usage: > $log <= “Starting process…” 13:43:01.632 DEBUG [(irb):1 :irb_binding]: Starting process… > $log << [“Got response:”, 200, body: “Hello”] 13:43:20.524 INFO [(irb):2 :irb_binding]: [“Got response:”, :body=>“Hello”] $log < “Oops, something went wrong!” 13:43:32.030 WARN [(irb):3 :irb_binding]: Oops, something went wrong!
which is aliases of #debug, #info and #warn, consequently
If you want to wrap logger call into another method: > class Exception > def warn! > $log.warn “#selfself.class – #message”, caller: 2 > end > end but still see in log string a reference to that method calling Exeption#warn! just pass stack frames quantity as :caller param
If you want to log an info that need a calculations (remember, #inspect is a calculations as well) to be logged, but don’t want a production server to calculate this, you may pass that calculations in a block: > $log.debug a_large_object and it won’t run if #debug should not run at this moment
Log level might be set for one server or console session using ENV variables: LOGLEVEL=| INFO | WARN | ERROR or DEBUG=1 | WARN=1 | SILENT=1 Default log level is INFO
Constant Summary collapse
- Modes =
[:debug, :log, :info, :warn, :error]
- NOPRINT =
8
- NOLOG =
4
- PREV_CALLER =
2
- INLINE =
1
Instance Attribute Summary collapse
-
#default_format ⇒ Object
readonly
Returns the value of attribute default_format.
-
#log_level ⇒ Object
Returns the value of attribute log_level.
-
#mute_debug ⇒ Object
Returns the value of attribute mute_debug.
-
#mute_error ⇒ Object
Returns the value of attribute mute_error.
-
#mute_info ⇒ Object
Returns the value of attribute mute_info.
-
#mute_log ⇒ Object
Returns the value of attribute mute_log.
-
#mute_warn ⇒ Object
Returns the value of attribute mute_warn.
Instance Method Summary collapse
-
#_print(mode, text, opts, caler, bind, cfg) ⇒ Object
TODO: добавить фильтров, например, для обработки текста, который будет логирован.
- #_set_format(file, format) ⇒ Object
- #debug(*args) ⇒ Object (also: #<=)
- #defaults ⇒ Object (also: #usage)
-
#error(*args) ⇒ Object
(also: #fatal)
controls: - @mute_warn, @mute_info, @mute_log, @mute_debug: do not print this messages regardless of any globals - @out_all: write to file info and debug messages - @out: write to file - @print: write to stdout.
- #get_config(file = nil) ⇒ Object
- #get_config! ⇒ Object
- #get_format(file = nil) ⇒ Object
- #info(*args) ⇒ Object (also: #<<, #puts)
-
#initialize(format = {}) ⇒ RMLogger
constructor
A new instance of RMLogger.
- #inspect ⇒ Object
- #log(*args) ⇒ Object
- #print(text) ⇒ Object
-
#set_format(*args) ⇒ Object
set any needed params, the rest will be set by default.
- #warn(*args) ⇒ Object (also: #<)
Constructor Details
#initialize(format = {}) ⇒ RMLogger
Returns a new instance of RMLogger.
53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 |
# File 'lib/rmtools/dev/logging.rb', line 53 def initialize format={} @c = Painter @highlight = { :error => @c.red_bold("ERROR"), :warn => @c.red_bold("WARN"), :log => @c.cyan("INFO"), :info => @c.cyan_bold("INFO"), :debug => @c.gray_bold("DEBUG") } @file_formats = Hash.new(@default_format = {}) set_format :global, format if ENV['LOGLEVEL'] self.log_level = ENV['LOGLEVEL'] elsif ENV['DEBUG'] || ENV['VERBOSE'] self.log_level = 'DEBUG' elsif ENV['WARN'] || ENV['QUIET'] self.log_level = 'WARN' elsif ENV['SILENT'] self.log_level = 'ERROR' else self.log_level = 'INFO' end end |
Instance Attribute Details
#default_format ⇒ Object (readonly)
Returns the value of attribute default_format.
45 46 47 |
# File 'lib/rmtools/dev/logging.rb', line 45 def default_format @default_format end |
#log_level ⇒ Object
Returns the value of attribute log_level.
45 46 47 |
# File 'lib/rmtools/dev/logging.rb', line 45 def log_level @log_level end |
#mute_debug ⇒ Object
Returns the value of attribute mute_debug.
44 45 46 |
# File 'lib/rmtools/dev/logging.rb', line 44 def mute_debug @mute_debug end |
#mute_error ⇒ Object
Returns the value of attribute mute_error.
44 45 46 |
# File 'lib/rmtools/dev/logging.rb', line 44 def mute_error @mute_error end |
#mute_info ⇒ Object
Returns the value of attribute mute_info.
44 45 46 |
# File 'lib/rmtools/dev/logging.rb', line 44 def mute_info @mute_info end |
#mute_log ⇒ Object
Returns the value of attribute mute_log.
44 45 46 |
# File 'lib/rmtools/dev/logging.rb', line 44 def mute_log @mute_log end |
#mute_warn ⇒ Object
Returns the value of attribute mute_warn.
44 45 46 |
# File 'lib/rmtools/dev/logging.rb', line 44 def mute_warn @mute_warn end |
Instance Method Details
#_print(mode, text, opts, caler, bind, cfg) ⇒ Object
TODO: добавить фильтров, например, для обработки текста, который будет логирован
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 |
# File 'lib/rmtools/dev/logging.rb', line 147 def _print mode, text, opts, caler, bind, cfg log_ = opts&NOLOG==0 print_ = opts&NOPRINT==0 str = cfg.fmt.dup str.gsub! "%mode", @highlight[mode] if bind text = bind.report text elsif !text.is String text = text.inspect elsif cfg.detect_comments and text =~ /\A[ \t]*#[ \t]+\S/ text = "\n" + @c.green(text.gsub(/^([ \t]*#[ \t])?/, cfg.precede_comments).chop) end out = cfg.out if cfg._time or cfg.path_format now = Time.now if cfg._time time = now.strftime cfg.tf[0] time << ".#{cfg.tf[1]%[now.usec/1000]}" if cfg.tf[1] str.gsub! "%time", time end out = now.strftime cfg.out if cfg.path_format end if caler caler.sub!(/block (?:\((\d+) levels\) )?in/) {"{#{$1||1}}"} str.gsub! "%caller", caler.sub(String::SIMPLE_CALLER_RE, cfg.cf) end str.gsub! "%text", text str << "\n" if opts&INLINE==0 log_str = cfg.color_out ? str : @c.clean(str) RMTools.write out, log_str if log_ Kernel::print str if print_ end |
#_set_format(file, format) ⇒ Object
78 79 80 81 82 83 84 85 86 87 88 89 90 91 |
# File 'lib/rmtools/dev/logging.rb', line 78 def _set_format file, format file.print = !format.q file.out = format.out || format.log_file file.color_out = format.color_out || format.color_log file.detect_comments = !!format.detect_comments file.precede_comments = format.precede_comments || "# " file.path_format = '%'.in file.out if file.out file.tf = format.time.to_a file.cf0 = format.caller file.cf = file.cf0.sub('%p') {'\1'}.sub('%f') {'\2'}.sub('%l') {'\3'}.sub('%m') {'\4'} file.fmt = format.format file._time, file._caller = '%time'.in(file.fmt), '%caller'.in(file.fmt) end |
#debug(*args) ⇒ Object Also known as: <=
239 240 241 242 243 244 245 246 247 248 |
# File 'lib/rmtools/dev/logging.rb', line 239 def debug *args cfg = get_config! if (cfg.print or cfg.out && cfg.out_all) && !@mute_debug text, bind, opts = args.get_opts [!block_given? && args[0].kinda(Hash) ? args[0] : "\b\b ", nil], :mute => 0 opts[:mute] |= NOLOG if !(cfg.out && cfg.out_all) opts[:mute] |= NOPRINT if !cfg.print return if block_given? && (text = yield).nil? _print(:debug, text, opts[:mute], cfg._caller && (@current_caller || caller)[(opts[:caller] || opts[:caller_offset]).to_i], bind, cfg) end end |
#defaults ⇒ Object Also known as: usage
93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 |
# File 'lib/rmtools/dev/logging.rb', line 93 def defaults Kernel::puts %{ # #{@c.y 'common options:'} :q => false, # not print :out => false, # output to file, may contain strftime's %H%M%Y etc for filename :time => ["%H:%M:%S", "%03d"], # strftime, [msecs] :type => :console, # or :html # #{@c.y 'console values:'} :caller => "#{@c.gray('%f:%l')} #{@c.red_bold(':%m')}", # "file:line :method", %p is for fullpath :format => "%time %mode [%caller]: %text" # format of entire log string, %mode is {#{%w(debug log info warn).map {|i| @highlight[i.to_sym]}*', '}} :color_out => false, # do not clean control characters that make output to file colorful; set to true makes more readable output of `tail' but hardly readable by gui file output :detect_comments => false, # highlight and strip comments blocks :precede_comments => "# ", # :detect_comments with default :precede_comments allows comment blocks looking like: $log<<<<-'#' # ... comment string one ... # ... comment string two ... # be logged like #{@c.green "\n# ... comment string one ...\n# ... comment string two ..."} # #{@c.y 'html options:'} :caller => "<a class='l'>%f:%l</a> <a class='m'>:%m</a>", :format => "<div class='line'><a class='t'>%time</a> <a class='%mode'>%mode</m> [%caller]: <p>%text</p>%att</div>", # %att is for array of objects that should be formatted by the next option :att =>"<div class='att'><div class='hide'>+</div><pre>%s</pre></div>", # .hide should be scripted to work like a spoiler :serializer => RMTools::RMLogger::HTML # should respond to :render(obj); nil value means each object will be just #inspect'ed} end |
#error(*args) ⇒ Object Also known as: fatal
controls:
-
@mute_warn, @mute_info, @mute_log, @mute_debug:
do not print this messages regardless of any globals
-
@out_all: write to file info and debug messages
-
@out: write to file
-
@print: write to stdout
195 196 197 198 199 200 201 202 203 204 |
# File 'lib/rmtools/dev/logging.rb', line 195 def error *args cfg = get_config! if (cfg.out or cfg.print) && !@mute_error text, bind, opts = args.get_opts [!block_given? && args[0].kinda(Hash) ? args[0] : "\b\b ", nil], :mute => 0 opts[:mute] |= NOLOG if !cfg.out opts[:mute] |= NOPRINT if !cfg.print return if block_given? && (text = yield).nil? _print(:error, text, opts[:mute], cfg._caller && (@current_caller || caller)[(opts[:caller] || opts[:caller_offset]).to_i], bind, cfg) end end |
#get_config(file = nil) ⇒ Object
184 185 186 |
# File 'lib/rmtools/dev/logging.rb', line 184 def get_config(file=nil) @file_formats[file && File.(file)] end |
#get_config! ⇒ Object
180 181 182 |
# File 'lib/rmtools/dev/logging.rb', line 180 def get_config! @file_formats.empty? ? @default_format : @file_formats[File.((@current_caller = caller)[1].till ':')] end |
#get_format(file = nil) ⇒ Object
139 140 141 142 143 |
# File 'lib/rmtools/dev/logging.rb', line 139 def get_format file=nil cfg = @file_formats[file && File.(file)] modes = Modes.reject {|m| send :"mute_#{m}"} %{<Logger #{cfg.fmt.sub('%time', "%time(#{cfg.tf*'.'})").sub('%caller', "%caller(#{cfg.cf0})")}#{' -> '+cfg.out if cfg.out} #{modes.b ? modes.inspect : 'muted'}>} end |
#info(*args) ⇒ Object Also known as: <<, puts
228 229 230 231 232 233 234 235 236 237 |
# File 'lib/rmtools/dev/logging.rb', line 228 def info *args cfg = get_config! if (cfg.print or cfg.out && cfg.out_all) && !@mute_info text, bind, opts = args.get_opts [!block_given? && args[0].kinda(Hash) ? args[0] : "\b\b ", nil], :mute => 0 opts[:mute] |= NOLOG if !(cfg.out && cfg.out_all) opts[:mute] |= NOPRINT if !cfg.print return if block_given? && (text = yield).nil? _print(:info, text, opts[:mute], cfg._caller && (@current_caller || caller)[(opts[:caller] || opts[:caller_offset]).to_i], bind, cfg) end end |
#inspect ⇒ Object
281 |
# File 'lib/rmtools/dev/logging.rb', line 281 def inspect() get_format end |
#log(*args) ⇒ Object
217 218 219 220 221 222 223 224 225 226 |
# File 'lib/rmtools/dev/logging.rb', line 217 def log *args cfg = get_config! if (cfg.out or cfg.print) && !@mute_log text, bind, opts = args.get_opts [!block_given? && args[0].kinda(Hash) ? args[0] : "\b\b ", nil], :mute => 0 opts[:mute] |= NOLOG if !cfg.out opts[:mute] |= NOPRINT if !(cfg.print && !@mute_debug) return if block_given? && (text = yield).nil? _print(:log, text, opts[:mute], cfg._caller && (@current_caller || caller)[(opts[:caller] || opts[:caller_offset]).to_i], bind, cfg) end end |
#print(text) ⇒ Object
256 257 258 |
# File 'lib/rmtools/dev/logging.rb', line 256 def print text info text, caller: 1, mute: INLINE end |
#set_format(*args) ⇒ Object
set any needed params, the rest will be set by default
120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 |
# File 'lib/rmtools/dev/logging.rb', line 120 def set_format *args global, format = args.fetch_opts [nil], :type => :console, :time => ["%H:%M:%S", "%03d"] format = if format[:type] == :html; { :caller => "<a class='l'>%f:%l</a> <a class='m'>:%m</a>", :format => "<div class='line'><a class='t'>%time</a> <a class='%mode'>%mode</m> [%caller]: <p>%text</p>%att</div>", :att =>"<div class='att'><div class='hide'>+</div><pre>%s</pre></div>", :serializer => RMTools::RMLogger::HTML }; else { :caller => "#{@c.gray('%f:%l')} #{@c.red_bold(':%m')}", :format => "%time %mode [%caller]: %text" } end.merge format if global _set_format @default_format, format else _set_format(file_format={}, format) @file_formats[File.(caller[0].till ':')] = file_format end end |
#warn(*args) ⇒ Object Also known as: <
206 207 208 209 210 211 212 213 214 215 |
# File 'lib/rmtools/dev/logging.rb', line 206 def warn *args cfg = get_config! if (cfg.out or cfg.print) && !@mute_warn text, bind, opts = args.get_opts [!block_given? && args[0].kinda(Hash) ? args[0] : "\b\b ", nil], :mute => 0 opts[:mute] |= NOLOG if !cfg.out opts[:mute] |= NOPRINT if !cfg.print return if block_given? && (text = yield).nil? _print(:warn, text, opts[:mute], cfg._caller && (@current_caller || caller)[(opts[:caller] || opts[:caller_offset]).to_i], bind, cfg) end end |