Class: Furnish::Logger
- Inherits:
-
Object
- Object
- Furnish::Logger
- Defined in:
- lib/furnish/logger.rb
Overview
Furnish::Logger is a thread safe, auto-flushing, IO-delegating logger with numeric level control.
See Furnish::Logger::Mixins for functionality you can add to your provisioners to deal with loggers easily.
Example:
# debug level is 0
logger = Furnish::Logger.new($stderr, 0)
# IO methods are sent straight to the IO object, synchronized by a
# mutex:
logger.puts "foo"
logger.print "foo"
# if_debug is a way to scope log writes:
# this will never run because debug level is 0
logger.if_debug(1) do
# self is the IO object here
puts "foo"
end
logger.if_debug(0) do # this will run
puts "foo"
end
logger.debug_level = 2
# if_debug's parameter merely must equal or be less than the debug
# level to process.
logger.if_debug(1) do # will run
puts "bar"
end
Defined Under Namespace
Modules: Mixins
Instance Attribute Summary collapse
-
#debug_level ⇒ Object
Set the debug level - adjustable after creation.
-
#io ⇒ Object
readonly
The IO object.
-
#tag ⇒ Object
readonly
Optional tag.
Instance Method Summary collapse
-
#close ⇒ Object
Hacky close method that keeps us from closing stdio.
-
#hijack_stdio ⇒ Object
Makes stdio Furnish::Logger objects for the duration of the block.
-
#if_debug(level = 1, else_block = nil, &block) ⇒ Object
Runs the block if the level is equal to or lesser than the Furnish::Logger#debug_level.
-
#initialize(logger_io = $stderr, debug_level = 0) ⇒ Logger
constructor
Create a new Furnish::Logger.
-
#method_missing(sym, *args) ⇒ Object
Delegates to the Furnish::Logger#io if possible.
-
#puts(*args) ⇒ Object
Hacky puts method to handle tags.
-
#redirect(new_io, &block) ⇒ Object
Temporarily redirects IO to a new IO object for the duration of the block.
-
#with_tag(new_tag, &block) ⇒ Object
Prefixes all ‘puts’ calls with a string of text (a “tag”) provided for the duration of the block.
-
#write(*args) ⇒ Object
Makes it possible to assign this to $stdout and $stderr.
Constructor Details
#initialize(logger_io = $stderr, debug_level = 0) ⇒ Logger
Create a new Furnish::Logger. Takes an IO object and an Integer debug level. See Furnish::Logger class documentation for more information.
86 87 88 89 90 91 |
# File 'lib/furnish/logger.rb', line 86 def initialize(logger_io=$stderr, debug_level=0) @write_mutex = Mutex.new @io = logger_io @io.sync = true @debug_level = debug_level end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(sym, *args) ⇒ Object
Delegates to the Furnish::Logger#io if possible. If not possible, raises a NoMethodError. All calls are synchronized over the logger’s mutex.
219 220 221 222 223 224 225 |
# File 'lib/furnish/logger.rb', line 219 def method_missing(sym, *args) raise NoMethodError, "#{io.inspect} has no method #{sym}" unless io.respond_to?(sym) run = lambda { io.__send__(sym, *args) } @write_mutex.synchronize { run.call } rescue ThreadError run.call end |
Instance Attribute Details
#debug_level ⇒ Object
Set the debug level - adjustable after creation.
69 70 71 |
# File 'lib/furnish/logger.rb', line 69 def debug_level @debug_level end |
#io ⇒ Object (readonly)
The IO object. Probably best to not mess with this attribute directly, most methods will be proxied to it.
75 76 77 |
# File 'lib/furnish/logger.rb', line 75 def io @io end |
#tag ⇒ Object (readonly)
Optional tag. See #with_tag for an example.
80 81 82 |
# File 'lib/furnish/logger.rb', line 80 def tag @tag end |
Instance Method Details
#close ⇒ Object
Hacky close method that keeps us from closing stdio.
209 210 211 212 213 |
# File 'lib/furnish/logger.rb', line 209 def close # XXX StringIO apparently overrides respond_to_missing for #to_i but # doesn't implement #to_i io.close unless io == $stdout or io == $stderr end |
#hijack_stdio ⇒ Object
Makes stdio Furnish::Logger objects for the duration of the block. Used by #if_debug for the purposes of not breaking expectations.
128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 |
# File 'lib/furnish/logger.rb', line 128 def hijack_stdio orig_stdout, orig_stderr = nil, nil if io != $stdout orig_stdout = $stdout $stdout = self end if io != $stderr orig_stderr = $stderr $stderr = self end yield ensure $stdout = orig_stdout if orig_stdout $stderr = orig_stderr if orig_stderr end |
#if_debug(level = 1, else_block = nil, &block) ⇒ Object
Runs the block if the level is equal to or lesser than the Furnish::Logger#debug_level. The default debug level is 1.
The block runs in the context of the Furnish::Logger#io object, that is, ‘self` is the IO object.
If an additional proc is applied, will run that if the debug block would not fire, effectively creating an else. Generally an anti-pattern, but is useful in a few situations.
if_debug is synchronized over the logger’s mutex.
106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/furnish/logger.rb', line 106 def if_debug(level=1, else_block=nil, &block) hijack_stdio do begin run = lambda do if debug_level >= level and block instance_eval(&block) elsif else_block instance_eval(&else_block) end end @write_mutex.synchronize { run.call } rescue ThreadError run.call end end end |
#puts(*args) ⇒ Object
Hacky puts method to handle tags.
191 192 193 194 195 196 197 |
# File 'lib/furnish/logger.rb', line 191 def puts(*args) if tag io.print("[#{tag}] ") end method_missing(:puts, *args) end |
#redirect(new_io, &block) ⇒ Object
160 161 162 163 164 165 |
# File 'lib/furnish/logger.rb', line 160 def redirect(new_io, &block) tmp_io = @io @io = new_io yield @io = tmp_io end |
#with_tag(new_tag, &block) ⇒ Object
Prefixes all ‘puts’ calls with a string of text (a “tag”) provided for the duration of the block.
Example:
@logger.with_tag("hi") do
@logger.if_debug do
puts "hello" # "[hi] hello"
end
end
@logger.puts "hello" # "hello"
182 183 184 185 186 |
# File 'lib/furnish/logger.rb', line 182 def with_tag(new_tag, &block) @tag = new_tag yield @tag = nil end |
#write(*args) ⇒ Object
Makes it possible to assign this to $stdout and $stderr.
202 203 204 |
# File 'lib/furnish/logger.rb', line 202 def write(*args) method_missing(:write, *args) end |