Class MUES::Logger
In: lib/mues/logger/fileoutputter.rb  (CVS)
lib/mues/logger/outputter.rb  (CVS)
lib/mues/logger.rb  (CVS)
Parent: Object

A log class for MUES systems.

Methods

Classes and Modules

Class MUES::Logger::FileOutputter
Class MUES::Logger::Outputter

Constants

SVNRev = %q$Rev: 1236 $   SVN Revision
SVNId = %q$Id: logger.rb 1236 2004-08-24 02:15:21Z stillflame $   SVN Id
SVNURL = %q$URL: svn+ssh://deveiate.org/usr/local/svn/MUES/trunk/lib/mues/logger.rb $   SVN URL
Levels = { :debug => 0, :info => 1, :notice => 2, :warning => 3, :error => 4, :crit => 5, :alert => 6, :emerg => 7, }   Log levels array (in order of decreasing verbosity)
DebugLogger = false   Constant for debugging the logger - set to true to output internals to $stderr.

Attributes

level  [R]  The integer level of the logger.
loggers  [R]  The hierarchy of all MUES::Logger objects.
name  [R]  The name of this logger
outputters  [RW]  The outputters attached to this branch of the logger tree.
subloggers  [RW]  The branches of the logging hierarchy that fall below this one.
superlogger  [R]  The logger object that is this logger‘s parent (if any).
trace  [RW]  Set to a true value to turn tracing on

Public Class methods

Return the MUES::Logger for the given module mod, which can be a Module object, a Symbol, or a String.

[Source]

# File lib/mues/logger.rb, line 97
        def self::[]( mod=nil )
            modname = mod.to_s
            return self::global if modname.empty?

            modname = '::' + modname unless /^::/ =~ modname
            names = modname.split( /::/ )

            # Create the global logger if it isn't already created
            @loggers[ '' ] ||= new( '' )

            names.inject( @loggers ) {|logger,key| logger[key]}
        end

Configure the logger with the given config (a MUES::Config object).

[Source]

# File lib/mues/logger.rb, line 120
        def self::configure( config )
            config.logging.each {|logger, cfg|
                if cfg.key?( :level )
                    self[ logger ].level = cfg[:level].to_s.intern
                end

                if cfg.key?( :outputters )
                    op = []

                    case cfg[:outputters]
                    when String
                        debugMsg( "Creating new outputter '%p'" % cfg[:outputters] )
                        op << Outputter::create( cfg[:outputters] )

                    when Hash
                        op = cfg[:outputters].collect do |kind,args|
                            debugMsg( "Creating new outputter '%p:%p'" % [kind,args]  )
                            Outputter::create( kind.to_s, *args )
                        end

                    when Array
                        op = cfg[:outputters].collect do |kind,args|
                            debugMsg( "Creating new outputter '%p:%p'" % [kind,args]  )
                            Outputter::create( kind.to_s, *args )
                        end

                    else
                        raise TypeError,
                            "Illegal outputters specification: %p" %
                            cfg[:outputters]
                    end
                end

                debugMsg( "Created %d outputters for %p" % [op.length, logger] )
                self[ logger ].outputters += op
            }
        end

Return the global MUES logger, setting it up if it hasn‘t been already.

[Source]

# File lib/mues/logger.rb, line 113
        def self::global
            @loggers[ '' ] ||= new( '' )
        end

Autoload global logging methods for the log levels

[Source]

# File lib/mues/logger.rb, line 160
        def self::method_missing( sym, *args )
            return super unless Levels.key?( sym )

            self.global.debug( "Autoloading class log method '#{sym}'." )
            (class << self; self; end).class_eval {
                define_method( sym ) {|*args|
                    self.global.send( sym, *args )
                }
            }

            self.global.send( sym, *args )
        end

Create and return a new MUES::Logger object with the given name at the specified level, with the specified superlogger. Any outputters that are specified will be added.

[Source]

# File lib/mues/logger.rb, line 181
        def initialize( name, level=:info, superlogger=nil, *outputters )
            if name.empty?
                debugMsg "Creating global logger"
            else
                debugMsg "Creating logger for #{name}"
            end
            
            @name = name
            @outputters = outputters
            @subloggers = {}
            @superlogger = superlogger
            @trace = false
            @level = nil

            self.level = level
        end

Public Instance methods

Return the sublogger for the given module mod (a Module, a String, or a Symbol) under this logger. A new one will instantiated if it does not already exist.

[Source]

# File lib/mues/logger.rb, line 333
        def []( mod )
            @subloggers[ mod.to_s ] ||=
                self.class.new( @name + "::" + mod.to_s, self.level, self )
        end

Return a uniquified Array of the loggers which are more-generally related hierarchically to the receiver, inclusive.

[Source]

# File lib/mues/logger.rb, line 256
        def hierloggers( level=0 )
            level = Levels[ level ] if level.is_a?( Symbol )
            loggers = []
            logger = self
            lastlogger = nil

            debugMsg "Searching for loggers in the hierarchy whose level <= %p" % level

            begin
                lastlogger = logger
                if logger.level <= level
                    debugMsg "hierloggers: added %s" % logger.readableName
                    loggers.push( logger )
                    yield( logger ) if block_given?
                else
                    debugMsg "hierloggers: discarding %s (%p)" %
                        [ logger.readableName, logger.levelSym ]
                end
            end while (( logger = lastlogger.superlogger ))

            return loggers
        end

Return a uniquified Array of all outputters for this logger and all of the loggers above it in the logging hierarchy.

[Source]

# File lib/mues/logger.rb, line 282
        def hieroutputters( level=0 )
            outputters = []
            level = Levels[ level ] if level.is_a?( Symbol )

            self.hierloggers( level ) {|logger|
                outpary = logger.outputters
                newoutpary = outpary - (outpary & outputters)
                unless newoutpary.empty?
                    debugMsg "hieroutputters: adding: %s" %
                        newoutpary.collect {|outp| outp.description}.join(", ")
                    if block_given?
                        newoutpary.each {|outputter| yield(outputter)}
                    end
                    outputters += newoutpary
                end
            }

            return outputters
        end

Set the level of this logger to level. The level can be a String, a Symbol, or an Integer.

[Source]

# File lib/mues/logger.rb, line 233
        def level=( level )
            case level
            when String
                @level = Levels[ level.intern ]
            when Symbol
                @level = Levels[ level ]
            when Integer
                @level = level
            else
                raise ArgumentError, "Illegal level specification: %s" %
                    level.class.name
            end
        end

Return the level of this logger as a Symbol

[Source]

# File lib/mues/logger.rb, line 249
        def levelSym
            Levels.invert[ @level ]
        end

Return the name of the logger formatted to be suitable for reading.

[Source]

# File lib/mues/logger.rb, line 223
        def readableName
            logname = self.name.sub( /^::/, '' )
            logname = '(global)' if logname.empty?

            return logname
        end

Write the given args to any connected outputters if level is less than or equal to this logger‘s level. If the first item in args is a String and contains %<char> codes, the message will formed by using the first argument as a format string in sprintf with the remaining items. Otherwise, the message will be formed by catenating the results of calling formatObject on each of them.

[Source]

# File lib/mues/logger.rb, line 309
        def write( level, *args )
            debugMsg "Writing message at %p: %p" % [ level, args ]
                
            msg, frame = nil, nil
            time = Time::now

            # If tracing is turned on, pick the first frame in the stack that
            # isn't in this file, or the last one if that fails to yield one.
            if @trace
                re = Regexp::new( Regexp::quote(__FILE__) + ":\d+:" )
                frame = caller(1).find {|fr| re !~ fr} || caller(1).last
            end

            self.hieroutputters( level ) {|outp|
                debugMsg "Got outputter %p" % outp
                msg ||= args.collect {|obj| self.stringifyObject(obj)}.join
                outp.write( time, level, self.readableName, frame, msg )
            }
        end

Protected Instance methods

Auto-install logging methods (ie., methods whose names match one of MUES::Logger::Levels.

[Source]

# File lib/mues/logger.rb, line 358
        def method_missing( id, *args )
            super unless MUES::Logger::Levels.member?( id )

            debugMsg "Autoloading instance log method '#{id}'"
            self.class.class_eval {
                define_method( id ) {|*args| self.write(id, *args)}
            }

            self.send( id, *args )
        end

Dump the given object for output in the log.

[Source]

# File lib/mues/logger.rb, line 344
        def stringifyObject( obj )
            return case obj
                   when Exception
                       "%s:\n    %s" % [ obj.message, obj.backtrace("\n    ") ]
                   when String
                       obj
                   else
                       obj.inspect
                   end
        end

Private Instance methods

[Source]

# File lib/mues/logger.rb, line 380
            def debugMsg( *parts ); end

[Validate]