lib/logging/logger.rb in logging-2.0.0 vs lib/logging/logger.rb in logging-2.1.0

- old
+ new

@@ -24,91 +24,101 @@ # class Logger @mutex = Mutex.new # :nodoc: + # Returns the root logger. + def self.root + ::Logging::Repository.instance[:root] + end + class << self + alias_method :instantiate, :new # `instantiate` becomes the "real" `new` + end - # Returns the root logger. - def root - ::Logging::Repository.instance[:root] - end + # Overrides the new method such that only one Logger will be created + # for any given logger name. + def self.new( *args ) + args.empty? ? super : self[args.shift] + end - alias_method :instantiate, :new # the "real" new + # Returns a logger instance for the given name. + def self.[]( name ) + repo = ::Logging::Repository.instance + name = repo.to_key(name) + logger = repo[name] + return logger unless logger.nil? - # Overrides the new method such that only one Logger will be created - # for any given logger name. - def new( *args ) - args.empty? ? super : self[args.shift] - end - - # Returns a logger instance for the given name. - def []( name ) - repo = ::Logging::Repository.instance - name = repo.to_key(name) + @mutex.synchronize do logger = repo[name] - return logger unless logger.nil? + return logger unless logger.nil? # thread-safe double checking - @mutex.synchronize do - logger = repo[name] - return logger unless logger.nil? # thread-safe double checking - - logger = instantiate(name) - repo[name] = logger - repo.children(name).each { |c| c.__send__(:parent=, logger) } - logger - end + logger = instantiate(name) + repo[name] = logger + repo.children(name).each { |child| child.__send__(:parent=, logger) } + logger end + end - # This is where the actual logging methods are defined. Two methods - # are created for each log level. The first is a query method used to - # determine if that perticular logging level is enabled. The second is - # the actual logging method that accepts a list of objects to be - # logged or a block. If a block is given, then the object returned - # from the block will be logged. - # - # Example - # - # log = Logging::Logger['my logger'] - # log.level = :warn - # - # log.info? # => false - # log.warn? # => true - # log.warn 'this is your last warning' - # log.fatal 'I die!', exception - # - # log.debug do - # # expensive method to construct log message - # msg - # end - # - def define_log_methods( logger ) - ::Logging::LEVELS.each do |name,num| - code = "undef :#{name} if method_defined? :#{name}\n" - code << "undef :#{name}? if method_defined? :#{name}?\n" + # This is where the actual logging methods are defined. Two methods + # are created for each log level. The first is a query method used to + # determine if that perticular logging level is enabled. The second is + # the actual logging method that accepts a list of objects to be + # logged or a block. If a block is given, then the object returned + # from the block will be logged. + # + # Example + # + # log = Logging::Logger['my logger'] + # log.level = :warn + # + # log.info? # => false + # log.warn? # => true + # log.warn 'this is your last warning' + # log.fatal 'I die!', exception + # + # log.debug do + # # expensive method to construct log message + # msg + # end + # + def self.define_log_methods( logger ) + code = log_methods_for_level(logger.level) + logger._meta_eval(code, __FILE__, __LINE__) + logger + end - if logger.level > num - code << <<-CODE - def #{name}?( ) false end - def #{name}( data = nil ) false end - CODE - else - code << <<-CODE - def #{name}?( ) true end - def #{name}( data = nil ) - data = yield if block_given? - log_event(::Logging::LogEvent.new(@name, #{num}, data, @caller_tracing)) - true - end - CODE - end + # This generator is used to define the log methods for the given `level`. + # This code is evaluated in the context of a Logger instance. + # + # Returns log methods as a String + def self.log_methods_for_level( level ) + code = [] + ::Logging::LEVELS.each do |name,num| + code << <<-CODE + undef :#{name} if method_defined? :#{name} + undef :#{name}? if method_defined? :#{name}? + CODE - logger._meta_eval(code, __FILE__, __LINE__) + if level > num + code << <<-CODE + def #{name}?( ) false end + def #{name}( data = nil ) false end + CODE + else + code << <<-CODE + def #{name}?( ) true end + def #{name}( data = nil ) + data = yield if block_given? + log_event(::Logging::LogEvent.new(@name, #{num}, data, @caller_tracing)) + true + end + CODE end - logger end - end # class << self + code.join("\n") + end attr_reader :name, :parent, :additive, :caller_tracing # call-seq: # Logger.new( name ) @@ -195,11 +205,18 @@ # def add( lvl, data = nil, progname = nil ) lvl = Integer(lvl) return false if lvl < level - data = yield if block_given? + if data.nil? + if block_given? + data = yield + else + data = progname + end + end + log_event(::Logging::LogEvent.new(@name, lvl, data, @caller_tracing)) true end # call-seq: @@ -290,10 +307,15 @@ define_log_methods(true) self.level end + # Returns `true` if the logger has its own level defined. + def has_own_level? + !@level.nil? + end + # Returns the list of appenders. # def appenders @appenders.dup end @@ -351,22 +373,12 @@ # # Remove all appenders from this logger. # def clear_appenders( ) @appenders.clear end - # call-seq: - # inspect => string - # - # Returns a string representation of the logger. - # - def inspect - "<%s:0x%x name=\"%s\">" % [self.class.name, self.object_id, self.name] - end + protected - - protected - # call-seq: # parent = ParentLogger # # Set the parent logger for this logger. This method will be invoked by # the +Repository+ class when a parent or child is added to the @@ -394,23 +406,31 @@ # and define log levels accordingly. The force flag will skip this # check. # # Recursively call this method on all our children loggers. # - def define_log_methods( force = false ) - return if @level and !force + def define_log_methods( force = false, code = nil ) + return if has_own_level? and !force - ::Logging::Logger.define_log_methods(self) - ::Logging::Repository.instance.children(name).each do |c| - c.define_log_methods + ::Logging::Logger._reentrant_mutex.synchronize do + ::Logging::Logger.define_log_methods(self) + ::Logging::Repository.instance.children(name).each do |child| + child.define_log_methods + end end self end # :stopdoc: - public + public + @reentrant_mutex = ReentrantMutex.new + + def self._reentrant_mutex + @reentrant_mutex + end + # call-seq: # _meta_eval( code ) # # Evaluates the given string of _code_ if the singleton class of this # Logger object. @@ -481,10 +501,10 @@ str << "\n" @appenders.each do |appender| str << indent_str str << '- ' - str << appender.inspect + str << appender.to_s str << "\n" end return str end