Created
May 24, 2010 19:49
-
-
Save fj/412342 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
=begin | |
I'm writing a small framework to help me with building some things, | |
and I'd like to give every class in the framework opt-in access to | |
logging. First I do that by defining a Log class which uses Singleton | |
to ensure that there's only one instance of a Log for the whole | |
application: | |
=end | |
require 'log4r' | |
module Constructify | |
class Log | |
include Singleton | |
include Log4r | |
def initialize | |
Logger['global'].level = DEBUG | |
fmt = PatternFormatter.new(:pattern => "%d [%5l] (%c) %M", | |
:date_pattern => "%y-%m-%d %H:%M:%S") | |
StderrOutputter.new('stderr', :level => Log4r::INFO, :formatter => fmt) | |
end | |
def log_init(name, level, target) | |
Logger.new(name, Log4r.const_get(level)).outputters = target | |
Logger[name] | |
end | |
end | |
end | |
=begin | |
Next, I add a has_logging method to every class: | |
=end | |
class Module | |
def has_logging(level='DEBUG', target=['stderr']) | |
class_eval { | |
@log = Constructify::Log.instance.log_init(self.name, | |
"#{level}", target.dup) | |
def log | |
self.class.instance_variable_get :@log | |
end | |
} | |
end | |
end | |
=begin | |
Now, one should be able to add logging to a particular class like this: | |
=end | |
class Foo | |
has_logging | |
end | |
=begin | |
But instead, I get this: | |
/home/johnf/dev/constructify/lib/constructify/logging.rb:31:in | |
`class_eval': deadlock; recursive locking (ThreadError) | |
from <internal:prelude>:6:in `synchronize' | |
from <internal:prelude>:20:in `exclusive' | |
from /home/johnf/.rvm/gems/ruby-1.9.1-p378@standard/gems/log4r-1.1.7/src/log4r/repository.rb:34:in | |
`[]' | |
from /home/johnf/.rvm/gems/ruby-1.9.1-p378@standard/gems/log4r-1.1.7/src/log4r/repository.rb:75:in | |
`block in find_ancestor' | |
from <internal:prelude>:21:in `block in exclusive' | |
from <internal:prelude>:8:in `synchronize' | |
from <internal:prelude>:20:in `exclusive' | |
from /home/johnf/.rvm/gems/ruby-1.9.1-p378@standard/gems/log4r-1.1.7/src/log4r/repository.rb:73:in | |
`find_ancestor' | |
from /home/johnf/.rvm/gems/ruby-1.9.1-p378@standard/gems/log4r-1.1.7/src/log4r/logger.rb:62:in | |
`deal_with_inheritance' | |
from /home/johnf/.rvm/gems/ruby-1.9.1-p378@standard/gems/log4r-1.1.7/src/log4r/logger.rb:36:in | |
`initialize' | |
from /home/johnf/dev/constructify/lib/constructify/logging.rb:17:in `new' | |
from /home/johnf/dev/constructify/lib/constructify/logging.rb:17:in `log_init' | |
from (eval):2:in `logger' | |
from /home/johnf/dev/constructify/lib/constructify/logging.rb:31:in | |
`class_eval' | |
=end | |
=begin | |
I have temporarily worked around the problem by defining a MockLog class instead: | |
=end | |
module Constructify | |
class MockLog | |
def self.log_stub_method(*args) | |
args.each do |a| | |
define_method "#{a}" do |msg| | |
t = Time.now.strftime("%Y-%m-%d %H:%M:%S") | |
$stderr.puts "[#{a.upcase}] \u00bb [#{t}] #{msg}" | |
end | |
end | |
end | |
log_stub_method :fatal, :error, :warn, :info, :debug | |
end | |
end | |
class Module | |
def has_logging(level='DEBUG', target=['stderr']) | |
class_eval { | |
# @log = Constructify::Log.instance.log_init(self.name, "#{level}", target.dup) | |
@log = Constructify::MockLog.new # Use MockLog instead of Log4r. | |
def log | |
self.class.instance_variable_get :@log | |
end | |
} | |
end | |
end | |
=begin | |
Commenting out the Log4r instantiation, not surprisingly, fixes the issue. | |
=end |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment