Class: Logging::Logger
- Inherits:
-
Object
- Object
- Logging::Logger
- Defined in:
- lib/logging/logger.rb
Overview
The Logger
class is the primary interface to the Logging
framework. It provides the logging methods that will be called from user methods, and it generates logging events that are sent to the appenders (the appenders take care of sending the log events to the logging destinations – files, sockets, etc).
Logger
instances are obtained from the Repository
and should not be directly created by users.
Example:
log = Logging.logger['my logger']
log.add_appenders( Logging.appenders.stdout ) # append to STDOUT
log.level = :info # log 'info' and above
log.info 'starting foo operation'
...
log.info 'finishing foo operation'
...
log.fatal 'unknown exception', exception
Direct Known Subclasses
Instance Attribute Summary collapse
-
#additive ⇒ Object
class << self.
-
#name ⇒ Object
readonly
class << self.
-
#parent ⇒ Object
readonly
class << self.
-
#trace ⇒ Object
class << self.
Class Method Summary collapse
-
.define_log_methods(logger) ⇒ Object
This is where the actual logging methods are defined.
-
.new(*args) ⇒ Object
(also: [])
Overrides the new method such that only one Logger will be created for any given logger name.
-
.root ⇒ Object
call-seq: Logger.root.
Instance Method Summary collapse
-
#<<(msg) ⇒ Object
(also: #write)
call-seq: log << “message”.
-
#<=>(other) ⇒ Object
call-seq: log <=> other.
-
#_dump_configuration(io = STDOUT, indent = 0) ⇒ Object
call-seq: _dump_configuration( io = STDOUT, indent = 0 ).
-
#_meta_eval(code, file = nil, line = nil) ⇒ Object
call-seq: _meta_eval( code ).
-
#_setup(name, opts = {}) ⇒ Object
call-seq: _setup( name, opts = {} ).
-
#add(lvl, data = nil, progname = nil) ⇒ Object
call-seq: add( severity, message = nil ) block.
-
#add_appenders(*args) ⇒ Object
call-seq: add_appenders( appenders ).
-
#appenders ⇒ Object
Returns the list of appenders.
-
#appenders=(args) ⇒ Object
call-seq: appenders = app.
-
#clear_appenders ⇒ Object
call-seq: clear_appenders.
-
#initialize(name) ⇒ Logger
constructor
call-seq: Logger.new( name ) Logger.
-
#inspect ⇒ Object
call-seq: inspect => string.
-
#level ⇒ Object
call-seq: level => integer.
-
#level=(level) ⇒ Object
call-seq: level = :all.
-
#remove_appenders(*args) ⇒ Object
call-seq: remove_appenders( appenders ).
Constructor Details
#initialize(name) ⇒ Logger
call-seq:
Logger.new( name )
Logger[name]
Returns the logger identified by name.
When name is a String
or a Symbol
it will be used “as is” to retrieve the logger. When name is a Class
the class name will be used to retrieve the logger. When name is an object the name of the object’s class will be used to retrieve the logger.
Example:
obj = MyClass.new
log1 = Logger.new(obj)
log2 = Logger.new(MyClass)
log3 = Logger['MyClass']
log1.object_id == log2.object_id # => true
log2.object_id == log3.object_id # => true
151 152 153 154 155 156 157 158 159 |
# File 'lib/logging/logger.rb', line 151 def initialize( name ) case name when String raise(ArgumentError, "logger must have a name") if name.empty? else raise(ArgumentError, "logger name must be a String") end repo = ::Logging::Repository.instance _setup(name, :parent => repo.parent(name)) end |
Instance Attribute Details
#additive ⇒ Object
class << self
127 128 129 |
# File 'lib/logging/logger.rb', line 127 def additive @additive end |
#name ⇒ Object (readonly)
class << self
127 128 129 |
# File 'lib/logging/logger.rb', line 127 def name @name end |
#parent ⇒ Object
class << self
127 128 129 |
# File 'lib/logging/logger.rb', line 127 def parent @parent end |
#trace ⇒ Object
class << self
127 128 129 |
# File 'lib/logging/logger.rb', line 127 def trace @trace end |
Class Method Details
.define_log_methods(logger) ⇒ Object
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
98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 |
# File 'lib/logging/logger.rb', line 98 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" 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, @trace)) true end CODE end logger.(code, __FILE__, __LINE__) end logger end |
.new(*args) ⇒ Object Also known as: []
Overrides the new method such that only one Logger will be created for any given logger name.
45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 |
# File 'lib/logging/logger.rb', line 45 def new( *args ) return super if args.empty? repo = ::Logging::Repository.instance name = repo.to_key(args.shift) @mutex.synchronize do logger = repo[name] if logger.nil? master = repo.master_for(name) if master if repo.has_logger?(master) logger = repo[master] else logger = super(master) repo[master] = logger repo.children(master).each {|c| c.__send__(:parent=, logger)} end repo[name] = logger else logger = super(name) repo[name] = logger repo.children(name).each {|c| c.__send__(:parent=, logger)} end end logger end end |
.root ⇒ Object
36 37 38 |
# File 'lib/logging/logger.rb', line 36 def root ::Logging::Repository.instance[:root] end |
Instance Method Details
#<<(msg) ⇒ Object Also known as: write
call-seq:
log << "message"
Log the given message without any formatting and without performing any level checks. The message is logged to all appenders. The message is passed up the logger tree if this logger’s additivity is true
.
182 183 184 185 |
# File 'lib/logging/logger.rb', line 182 def <<( msg ) @appenders.each {|a| a << msg} @parent << msg if @additive end |
#<=>(other) ⇒ Object
call-seq:
log <=> other
Compares this logger by name to another logger. The normal return codes for String
objects apply.
167 168 169 170 171 172 173 |
# File 'lib/logging/logger.rb', line 167 def <=>( other ) case other when self; 0 when ::Logging::RootLogger; 1 when ::Logging::Logger; @name <=> other.name else raise ArgumentError, 'expecting a Logger instance' end end |
#_dump_configuration(io = STDOUT, indent = 0) ⇒ Object
call-seq:
_dump_configuration( io = STDOUT, indent = 0 )
An internal method that is used to dump this logger’s configuration to the given io stream. The configuration includes the logger’s name, level, additivity, and trace settings. The configured appenders are also printed to the io stream.
462 463 464 465 466 467 468 469 470 471 472 473 474 475 476 477 478 479 480 481 482 483 484 485 486 487 488 489 490 491 492 493 494 495 496 497 498 499 500 501 502 503 504 |
# File 'lib/logging/logger.rb', line 462 def _dump_configuration( io = STDOUT, indent = 0 ) str, spacer, base = '', ' ', 50 indent_str = indent == 0 ? '' : ' ' * indent str << indent_str str << self.name.reduce(base - indent) if (str.length + spacer.length) < base str << spacer str << '.' * (base - str.length) end io.write(str.ljust(base)) io.write(spacer) level_str = @level.nil? ? '' : '*' level_str << if level < ::Logging::LEVELS.length ::Logging.levelify(::Logging::LNAMES[level]) else 'off' end level_len = ::Logging::MAX_LEVEL_LENGTH + 1 io.write("%#{level_len}s" % level_str) io.write(spacer) if self.respond_to?(:additive) io.write(additive ? '+A' : '-A') else io.write(' ') end io.write(spacer) io.write(trace ? '+T' : '-T') io.write("\n") @appenders.each do |appender| io.write(indent_str) io.write('- ') io.write(appender.inspect) io.write("\n") end return io end |
#_meta_eval(code, file = nil, line = nil) ⇒ Object
call-seq:
( code )
Evaluates the given string of code if the singleton class of this Logger object.
433 434 435 436 |
# File 'lib/logging/logger.rb', line 433 def ( code, file = nil, line = nil ) = class << self; self end .class_eval code, file, line end |
#_setup(name, opts = {}) ⇒ Object
call-seq:
_setup( name, opts = {} )
Configures internal variables for the logger. This method can be used to avoid storing the logger in the repository.
444 445 446 447 448 449 450 451 452 |
# File 'lib/logging/logger.rb', line 444 def _setup( name, opts = {} ) @name = name @parent = opts.getopt(:parent) @appenders = opts.getopt(:appenders, []) @additive = opts.getopt(:additive, true) @trace = opts.getopt(:trace, false) @level = opts.getopt(:level) ::Logging::Logger.define_log_methods(self) end |
#add(lvl, data = nil, progname = nil) ⇒ Object
call-seq:
add( severity, = nil ) {block}
Log a message if the given severity is high enough. This is the generic logging method. Users will be more inclined to use #debug, #info, #warn, #error, and #fatal.
Message format: message
can be any object, but it has to be converted to a String in order to log it. The Logging::format_as method is used to determine how objects chould be converted to strings. Generally, inspect
is used.
A special case is an Exception
object, which will be printed in detail, including message, class, and backtrace.
If a message is not given, then the return value from the block is used as the message to log. This is useful when creating the actual message is an expensive operation. This allows the logger to check the severity against the configured level before actually constructing the message.
This method returns true
if the message was logged, and false
is returned if the message was not logged.
212 213 214 215 216 217 218 219 |
# File 'lib/logging/logger.rb', line 212 def add( lvl, data = nil, progname = nil ) lvl = Integer(lvl) return false if lvl < level data = yield if block_given? log_event(::Logging::LogEvent.new(@name, lvl, data, @trace)) true end |
#add_appenders(*args) ⇒ Object
call-seq:
add_appenders( appenders )
Add the given appenders to the list of appenders, where appenders can be either a single appender or an array of appenders.
333 334 335 336 337 338 339 340 |
# File 'lib/logging/logger.rb', line 333 def add_appenders( *args ) args.flatten.each do |arg| o = arg.kind_of?(::Logging::Appender) ? arg : ::Logging::Appenders[arg.to_s] raise ArgumentError, "unknown appender #{arg.inspect}" if o.nil? @appenders << o unless @appenders.include?(o) end self end |
#appenders ⇒ Object
Returns the list of appenders.
312 313 314 |
# File 'lib/logging/logger.rb', line 312 def appenders @appenders.dup end |
#appenders=(args) ⇒ Object
call-seq:
appenders = app
Clears the current list of appenders and replaces them with app, where app can be either a single appender or an array of appenders.
322 323 324 325 |
# File 'lib/logging/logger.rb', line 322 def appenders=( args ) @appenders.clear add_appenders(*args) unless args.nil? end |
#clear_appenders ⇒ Object
call-seq:
clear_appenders
Remove all appenders from this logger.
369 |
# File 'lib/logging/logger.rb', line 369 def clear_appenders( ) @appenders.clear end |
#inspect ⇒ Object
call-seq:
inspect => string
Returns a string representation of the logger.
376 377 378 |
# File 'lib/logging/logger.rb', line 376 def inspect "<%s:0x%x name=\"%s\">" % [self.class.name, self.object_id, self.name] end |
#level ⇒ Object
call-seq:
level => integer
Returns an integer which is the defined log level for this logger.
256 257 258 259 |
# File 'lib/logging/logger.rb', line 256 def level return @level unless @level.nil? @parent.level end |
#level=(level) ⇒ Object
call-seq:
level = :all
Set the level for this logger. The level can be either a String
, a Symbol
, or a Fixnum
. An ArgumentError
is raised if this is not the case.
There are two special levels – “all” and “off”. The former will enable log messages from this logger. The latter will disable all log messages from this logger.
Setting the logger level to nil
will cause the parent’s logger level to be used.
Example:
log.level = :debug
log.level = "INFO"
log.level = 4
log.level = 'off'
log.level = :all
These produce an ArgumentError
log.level = Object
log.level = -1
log.level = 1_000_000_000_000
289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 |
# File 'lib/logging/logger.rb', line 289 def level=( level ) @level = if level.nil? then level else lvl = case level when String, Symbol; ::Logging::level_num(level) when Fixnum; level else raise ArgumentError, "level must be a String, Symbol, or Integer" end if lvl.nil? or lvl < 0 or lvl > ::Logging::LEVELS.length raise ArgumentError, "unknown level was given '#{level}'" end lvl end define_log_methods(true) self.level end |
#remove_appenders(*args) ⇒ Object
call-seq:
remove_appenders( appenders )
Remove the given appenders from the list of appenders. The appenders to remove can be identified either by name using a String
or by passing the appender instance. appenders can be a single appender or an array of appenders.
350 351 352 353 354 355 356 357 358 359 360 361 362 |
# File 'lib/logging/logger.rb', line 350 def remove_appenders( *args ) args.flatten.each do |arg| @appenders.delete_if do |a| case arg when String; arg == a.name when ::Logging::Appender; arg.object_id == a.object_id else raise ArgumentError, "#{arg.inspect} is not a 'Logging::Appender'" end end end self end |