Permalink
Browse files

Remove the logging gem, but provide similar functionality

Using _eric's ForwardingLogger, wrap the stdlib Logger to add originating
class name. Also, keep a registry, etc. ad-hoc ftw!
  • Loading branch information...
1 parent 2b4e273 commit 128260a792a5ce7d0b2361da03e5e78b2400c04c @slyphon slyphon committed Nov 14, 2012
View
@@ -32,6 +32,7 @@ def self.require_root(*relpaths)
'zookeeper/core_ext',
'zookeeper/monitor',
'zookeeper/logger',
+ 'zookeeper/logger/forwarding_logger',
'zookeeper/forked',
'zookeeper/latch',
'zookeeper/acls',
@@ -27,4 +27,32 @@ def to_std_format
end
end
+# this is borrowed from the excellent Logging gem: https://github.com/TwP/logging
+# @private
+class ::Module
+ # @private
+ # Returns a predictable logger name for the current module or class. If
+ # used within an anonymous class, the first non-anonymous class name will
+ # be used as the logger name. If used within a meta-class, the name of the
+ # actual class will be used as the logger name. If used within an
+ # anonymous module, the string 'anonymous' will be returned.
+ def _zk_logger_name
+ return name unless name.nil? or name.empty?
+
+ # check if this is a metaclass (or eigenclass)
+ if ancestors.include? Class
+ inspect =~ %r/#<Class:([^#>]+)>/
+ return $1
+ end
+
+ # see if we have a superclass
+ if respond_to? :superclass
+ return superclass.logger_name
+ end
+
+ # we are an anonymous module
+ return 'anonymous'
+ end
+end
+
@@ -1,15 +1,27 @@
-require 'logger'
-
module Zookeeper
module Logger
- def self.included(mod)
- return false if mod < self # avoid infinite recursion
- mod.class_eval do
- def self.logger
- ::Zookeeper.logger || ::Logger.new(STDOUT)
- end
+ def self.wrapped_logger
+ if defined?(@@wrapped_logger)
+ @@wrapped_logger
+ else
+ @@wrapped_logger = ::Logger.new(STDERR).tap { |l| l.level = ::Logger::FATAL }
end
- mod.extend(self)
+ end
+
+ def self.wrapped_logger=(log)
+ @@wrapped_logger = log
+ end
+
+ # @private
+ module ClassMethods
+ def logger
+ ::Zookeeper.logger || ForwardingLogger.for(::Zookeeper::Logger.wrapped_logger, _zk_logger_name)
+ end
+ end
+
+ def self.included(base)
+ # return false if base < self # avoid infinite recursion
+ base.extend(ClassMethods)
end
private
@@ -21,8 +33,7 @@ def log_realtime(what)
end
def logger
- @logger ||= (::Zookeeper.logger || ::Logger.new(STDOUT))
+ @logger ||= (::Zookeeper.logger || self.class.logger)
end
- end
-end
-
+ end # Logger
+end # Zookeeper
@@ -0,0 +1,84 @@
+module Zookeeper
+ module Logger
+ # h/t _eric and Papertrail
+ # @private
+ class ForwardingLogger
+ attr_accessor :level, :formatter
+
+ @@mutex = Monitor.new unless defined?(@@mutex)
+ @@loggers = {} unless defined?(@@loggers)
+
+ def self.for(logger, name)
+ @@mutex.synchronize do
+ @@loggers.fetch(name) do |k|
+ @@loggers[k] = new(logger, :formatter => lambda { |m| "%25.25s: #{m}" % name })
@eric
eric Jan 10, 2013 Member

This should be:

            @@loggers[k] = new(logger, :formatter => lambda { |m| "%25.25s: %s" % [ m, k ]})

otherwise, if the message contains a % it will mess up the formatting.

@slyphon
slyphon Jan 10, 2013 Contributor

@eric pretty sure you mean

            @@loggers[k] = new(logger, :formatter => lambda { |m| "%25.25s: %s" % [ k, m ]})

in that the k bit was supposed to show up in the string before the message

@slyphon
slyphon via email Jan 10, 2013 Contributor
@eric
eric Jan 10, 2013 Member

Indeed. Good catch.

+ end
+ end
+ end
+
+ def initialize(logger, options = {})
+ @level = ::Logger::DEBUG
+ @logger = logger
+ @formatter = options[:formatter]
+ end
+
+ def add(severity, message = nil, progname = nil, &block)
+ severity ||= ::Logger::UNKNOWN
+ if !@logger || severity < @level
+ return true
+ end
+
+ message = (message || (block && block.call) || progname).to_s
+
+ if @formatter && @formatter.respond_to?(:call)
+ message = @formatter.call(message)
+ end
+
+ # If a newline is necessary then create a new message ending with a newline.
+ # Ensures that the original message is not mutated.
+ # message = "#{message}\n" unless message[-1] == ?\n
+
+ @logger.add(severity, message)
+ end
+
+ def <<(msg); @logger << msg; end
+ def write(msg); @logger.write(msg); end
+
+ def debug(progname = nil, &block)
+ add(::Logger::DEBUG, nil, progname, &block)
+ end
+
+ def info(progname = nil, &block)
+ add(::Logger::INFO, nil, progname, &block)
+ end
+
+ def warn(progname = nil, &block)
+ add(::Logger::WARN, nil, progname, &block)
+ end
+
+ def error(progname = nil, &block)
+ add(::Logger::ERROR, nil, progname, &block)
+ end
+
+ def fatal(progname = nil, &block)
+ add(::Logger::FATAL, nil, progname, &block)
+ end
+
+ def unknown(progname = nil, &block)
+ add(::Logger::UNKNOWN, nil, progname, &block)
+ end
+
+ def debug?; @level <= DEBUG; end
+
+ def info?; @level <= INFO; end
+
+ def warn?; @level <= WARN; end
+
+ def error?; @level <= ERROR; end
+
+ def fatal?; @level <= FATAL; end
+ end # ForwardingLogger
+ end # Logger
+end # Zookeeper
+
+
View
@@ -21,7 +21,7 @@
end
if ENV['ZKRB_NOLOG']
- ::Logging.logger['Zookeeper'].level = :off
+ SpecGlobalLogger.logger.level = ::Logger::FATAL
Zookeeper.set_debug_level(0)
end
@@ -36,7 +36,7 @@
require 'zk-server'
config.before(:suite) do
- ::Logging.logger['spec'].debug { "Starting zookeeper service" }
+ SpecGlobalLogger.logger.debug { "Starting zookeeper service" }
ZK::Server.run do |c|
c.base_dir = File.expand_path('../../.zkserver', __FILE__)
c.client_port = Zookeeper.test_port
@@ -46,7 +46,7 @@
end
config.after(:suite) do
- ::Logging.logger['spec'].debug { "stopping zookeeper service" }
+ SpecGlobalLogger.logger.debug { "stopping zookeeper service" }
ZK::Server.shutdown
end
end
@@ -1,33 +1,34 @@
module Zookeeper
TEST_LOG_PATH = File.expand_path('../../../test.log', __FILE__)
-end
-layout = Logging.layouts.pattern(
- :pattern => '%.1l, [%d #%p] %25.25c{2}: %m\n',
- :date_pattern => '%Y-%m-%d %H:%M:%S.%6N'
-)
+ def self.setup_test_logger
+ log =
+ if (ENV['ZOOKEEPER_DEBUG'] || ENV['ZKRB_DEBUG'])
+ ::Logger.new(STDERR)
+ else
+ ::Logger.new(TEST_LOG_PATH)
+ end
-appender = (ENV['ZOOKEEPER_DEBUG'] || ENV['ZKRB_DEBUG']) ? Logging.appenders.stderr : Logging.appenders.file(Zookeeper::TEST_LOG_PATH)
-appender.layout = layout
-appender.auto_flushing = 25
-appender.flush_period = 5
+ log.level = ::Logger::DEBUG
-%w[spec Zookeeper].each do |name|
- ::Logging.logger[name].tap do |log|
- log.appenders = [appender]
- log.level = :debug
+ Zookeeper::Logger.wrapped_logger = log
end
end
+Zookeeper.setup_test_logger
+
module SpecGlobalLogger
+ extend self
+
def logger
- @spec_global_logger ||= ::Logging.logger['spec']
+ @spec_global_logger ||= Zookeeper::Logger::ForwardingLogger.for(Zookeeper::Logger.wrapped_logger, 'spec')
end
# sets the log level to FATAL for the duration of the block
def mute_logger
- zk_log = Logging.logger['Zookeeper']
- orig_level, zk_log.level = zk_log.level, :off
+ zk_log = Zookeeper::Logger.wrapped_logger
+
+ orig_level, zk_log.level = zk_log.level, ::Logger::FATAL
orig_zk_level, Zookeeper.debug_level = Zookeeper.debug_level, Zookeeper::Constants::ZOO_LOG_LEVEL_ERROR
yield
ensure
@@ -5,7 +5,7 @@ module Core
module Formatters
class ProgressFormatter
def example_started(example)
- ::Logging.logger['spec'].write(yellow("\n=====<([ #{example.full_description} ])>=====\n"))
+ SpecGlobalLogger.logger << yellow("\n=====<([ #{example.full_description} ])>=====\n")
super(example)
end
end

0 comments on commit 128260a

Please sign in to comment.