lib/loggability.rb in loggability-0.11.0 vs lib/loggability.rb in loggability-0.12.0.pre20161212115530

- old
+ new

@@ -7,25 +7,25 @@ # A mixin that provides a top-level logging subsystem based on Logger. module Loggability # Package version constant - VERSION = '0.11.0' + VERSION = '0.12.0' # VCS revision - REVISION = %q$Revision: fa08d10cb3b6 $ + REVISION = %q$Revision: 6379f2040f92 $ # The key for the global logger (Loggability's own logger) GLOBAL_KEY = :__global__ # The methods that are delegated across all loggers AGGREGATE_METHODS = [ :level=, :output_to, :write_to, :format_with, :format_as, :formatter= ] # Configuration defaults CONFIG_DEFAULTS = { :__default__ => 'warn STDERR', - } + }.freeze # Regexp for parsing logspec lines in the config LOGSPEC_PATTERN = %r{ ^ \s* @@ -50,11 +50,16 @@ ## # The Hash of modules that have a Logger, keyed by the name they register with class << self; attr_reader :log_hosts; end @log_hosts = {} + ## + # The last logging configuration that was installed + class << self; attr_accessor :config; end + @config = CONFIG_DEFAULTS.dup.freeze + # Automatically log the log host and log client mixins when they're referenced autoload :LogHost, 'loggability/loghost' autoload :LogClient, 'loggability/logclient' autoload :Override, 'loggability/override' @@ -79,16 +84,24 @@ ### Register the specified +host+ as a log host. It should already have been extended ### with LogHostMethods. def self::register_loghost( host ) key = host.log_host_key if self.log_hosts.key?( key ) + # raise "Can't set a log host for nil" if key.nil? self.logger.warn "Replacing existing log host for %p (%p) with %p" % [ key, self.log_hosts[key], host ] end - self.logger.debug "Registering %p log host: %p" % [ key, host ] if self.logger + #self.logger.debug "Registering %p log host: %p" % [ key, host ] if self.logger self.log_hosts[ key ] = host + if (( logspec = Loggability.config[key] )) + self.apply_config( host.logger, logspec ) + elsif (( defaultspec = (Loggability.config[:__default__] || Loggability.config['__default__']) )) + self.apply_config( host.logger, defaultspec ) + else + self.apply_config( host.logger, CONFIG_DEFAULTS[:__default__] ) + end end ### Return the log host key for +object+, using its #log_host_key method ### if it has one, or returning it as a Symbol if it responds to #to_sym. Returns @@ -116,14 +129,16 @@ raise ArgumentError, "no log host set up for %p yet." % [ key ] return loghost.logger end - ### Clear out all log hosts except for ones which start with '_'. This is intended - ### to be used for testing. - def self::clear_loghosts - self.log_hosts.delete_if {|key,_| !key.to_s.start_with?('_') } + ### Clear out all registered log hosts and reset the default logger. This is + ### mostly intended for facilitating tests. + def self::reset + self.log_hosts.clear + self.logger = self.default_logger = Loggability::Logger.new + Loggability.register_loghost( self ) end # # :section: Aggregate Methods @@ -261,68 +276,73 @@ self.log_host_key = Loggability.log_host_key_for( loghost ) end + + # + # :section: Configurability Support + # + + ### Configure the specified +logger+ (or anything that ducktypes the same) with the + ### configuration specified by +logspec+. + def self::apply_config( logger, logspec ) + level, format, target = self.parse_config_spec( logspec ) + logger.level = level if level + logger.format_with( format ) if format + logger.output_to( target ) if target + end + + + ### Parse the specified +spec+ into level, + def self::parse_config_spec( spec ) + match = LOGSPEC_PATTERN.match( spec ) or + raise ArgumentError, "Couldn't parse logspec: %p" % [ spec ] + # self.log.debug " parsed config spec %p -> %p" % [ spec, match ] + severity, target, format = match.captures + + target = case target + when 'STDOUT' then $stdout + when 'STDERR' then $stderr + else + target + end + + return severity, format, target + end + + # Install a global logger in Loggability itself extend( Loggability::LogHost ) self.log_host_key = GLOBAL_KEY self.logger = self.default_logger = Loggability::Logger.new Loggability.register_loghost( self ) - # - # :section: Configurability Support - # - ### Configurability API -- configure logging. - def self::configure( config=nil ) - if config - self.log.debug "Configuring Loggability with custom config." - confighash = config.to_hash + def self::configure( new_config=nil ) + if new_config + self.config = new_config.dup.freeze + confighash = new_config.to_hash # Set up all loggers with defaults first if defaultspec = confighash.delete( :__default__ ) || confighash.delete( '__default__' ) - level, format, target = self.parse_config_spec( defaultspec ) - Loggability.level = level if level - Loggability.format_as( format ) if format - Loggability.output_to( target ) if target + self.apply_config( self, defaultspec ) end # Then let individual configs override. confighash.each do |key, logspec| unless Loggability.log_host?( key ) self.log.debug " no such log host %p; skipping" % [ key ] next end - self.log.debug " configuring logger for %p: %s" % [ key, logspec ] - level, format, target = self.parse_config_spec( logspec ) - Loggability[ key ].level = level if level - Loggability[ key ].format_with( format ) if format - Loggability[ key ].output_to( target ) if target + # self.log.debug " configuring logger for %p: %s" % [ key, logspec ] + self.apply_config( Loggability[key], logspec ) end else - self.log.debug "Configuring Loggability with defaults." + self.config = self.defaults.dup.freeze end - end - - - ### Parse the specified +spec+ into level, - def self::parse_config_spec( spec ) - match = LOGSPEC_PATTERN.match( spec ) or - raise ArgumentError, "Couldn't parse logspec: %p" % [ spec ] - self.log.debug " parsed config spec %p -> %p" % [ spec, match ] - severity, target, format = match.captures - - target = case target - when 'STDOUT' then $stdout - when 'STDERR' then $stderr - else - target - end - - return severity, format, target end end # module Loggability