Class: RightScale::Log
- Includes:
- RightSupport::Ruby::EasySingleton
- Defined in:
- lib/right_agent/log.rb
Overview
Logs both to syslog and to local file
Defined Under Namespace
Classes: Formatter
Constant Summary collapse
- LEVELS_MAP =
Map of log levels symbols associated with corresponding Logger constant
{:debug => Logger::DEBUG, :info => Logger::INFO, :warn => Logger::WARN, :error => Logger::ERROR, :fatal => Logger::FATAL}
- @@inverted_levels_map =
nil
Instance Method Summary collapse
-
#add_logger(logger) ⇒ Object
Add new logger to list of multiplexed loggers.
-
#error(description, exception = nil, backtrace = :caller) ⇒ Object
Log error and optionally append exception information.
-
#facility=(facility) ⇒ Object
Sets the syslog facility that will be used when emitting syslog messages.
-
#force_debug ⇒ Object
Force log level to debug and disregard any further attempt to change it.
-
#force_logger(logger) ⇒ Object
Force use of given logger and override all defaults.
-
#format(description, exception = nil, backtrace = :caller) ⇒ Object
Format error information.
-
#init(identity = nil, path = nil, opts = {}) ⇒ Object
Initialize logger.
-
#initialize ⇒ Log
constructor
A new instance of Log.
-
#initialized ⇒ Object
Was logger initialized?.
-
#level ⇒ Object
Current log level.
-
#level=(level) ⇒ Object
Sets the level for the Logger by symbol or by Logger constant.
-
#level_from_sym(sym) ⇒ Object
Map symbol log level to Logger constant.
-
#level_to_sym(lvl) ⇒ Object
Map Logger log level constant to symbol.
-
#log_to_file_only(val) ⇒ Object
Set whether syslog should be used or to log to an agent-specific file This should be called before anything else.
-
#logger ⇒ Object
Read access to internal multiplexer.
-
#method_missing(m, *args) ⇒ Object
Forward all method calls to underlying Logger object created with init Return the result of only the first registered logger to keep the interface consistent with that of a Logger.
-
#notify(callback) ⇒ Object
Register callback to be activated when there is a logging configuration change Currently the only logging change reported is log level.
-
#program_name=(prog_name) ⇒ Object
Sets the syslog program name that will be reported Can only be successfully called before logging is initialized.
-
#remove_logger(logger) ⇒ Object
Remove logger from list of multiplexed loggers.
-
#respond_to?(m, *args) ⇒ Boolean
Determine whether this object, or its method_missing proxy, responds to the given method name.
-
#warning(description, exception = nil, backtrace = :caller) ⇒ Object
(also: #warn)
Log warning and optionally append exception information.
Constructor Details
#initialize ⇒ Log
Returns a new instance of Log.
117 118 119 120 121 |
# File 'lib/right_agent/log.rb', line 117 def initialize # Was log ever used? @initialized = false @logger = RightSupport::Log::NullLogger.new # ensures respond_to? works before init is called end |
Dynamic Method Handling
This class handles dynamic methods through the method_missing method
#method_missing(m, *args) ⇒ Object
Forward all method calls to underlying Logger object created with init Return the result of only the first registered logger to keep the interface consistent with that of a Logger
Parameters
- m(Symbol)
-
Forwarded method name
- args(Array)
-
Forwarded method arguments
Return
- (Object)
-
Result from first registered logger
133 134 135 136 137 |
# File 'lib/right_agent/log.rb', line 133 def method_missing(m, *args) init unless @initialized @logger.level = level_from_sym(level) if @level_frozen @logger.send(m, *args) end |
Instance Method Details
#add_logger(logger) ⇒ Object
Add new logger to list of multiplexed loggers
Parameters
- logger(Object)
-
Logger that should get log messages
Return
- @logger(RightScale::Multiplexer)
-
Multiplexer logger
263 264 265 266 267 |
# File 'lib/right_agent/log.rb', line 263 def add_logger(logger) init unless @initialized logger.level = level_from_sym(Log.instance.level) @logger.add(logger) end |
#error(description, exception = nil, backtrace = :caller) ⇒ Object
Log error and optionally append exception information
Parameters
- description(String)
-
Error description
- exception(Exception|String)
-
Associated exception or other parenthetical error information
- backtrace(Symbol)
-
Exception backtrace extent: :no_trace, :caller, or :trace,
defaults to :caller
Return
- (Object)
-
Result from first registered logger
180 181 182 183 |
# File 'lib/right_agent/log.rb', line 180 def error(description, exception = nil, backtrace = :caller) init unless @initialized @logger.error(format(description, exception, backtrace)) end |
#facility=(facility) ⇒ Object
Sets the syslog facility that will be used when emitting syslog messages. Can only be successfully called before logging is initialized
Parameters
- facility(String)
-
A syslog facility name, e.g. ‘user’ or ‘local0’
Return
- program_name(String)
-
The input string
Raise
- RuntimeError
-
If logger is already initialized
333 334 335 336 |
# File 'lib/right_agent/log.rb', line 333 def facility=(facility) raise 'Logger already initialized' if @initialized @facility = facility end |
#force_debug ⇒ Object
Force log level to debug and disregard any further attempt to change it
Return
- true
-
Always return true
400 401 402 403 |
# File 'lib/right_agent/log.rb', line 400 def force_debug self.level = :debug @level_frozen = true end |
#force_logger(logger) ⇒ Object
Force use of given logger and override all defaults
Parameters
- logger(Logger)
-
Logger compatible object
Return
- true
-
Always return true
412 413 414 415 |
# File 'lib/right_agent/log.rb', line 412 def force_logger(logger) @initialized = true @logger = logger end |
#format(description, exception = nil, backtrace = :caller) ⇒ Object
Format error information
Parameters
- description(String)
-
Error description
- exception(Exception|String)
-
Associated exception or other parenthetical error information
- backtrace(Symbol)
-
Exception backtrace extent: :no_trace, :caller, or :trace,
defaults to :caller
Return
- (Object)
-
Result from first registered logger
195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 |
# File 'lib/right_agent/log.rb', line 195 def format(description, exception = nil, backtrace = :caller) if exception if exception.respond_to?(:message) description += " (#{exception.class}: #{exception.}" else description += " (#{exception}" backtrace = :no_trace end if exception.respond_to?(:backtrace) && exception.backtrace case backtrace when :no_trace then description += ")" when :caller then description += " in " + exception.backtrace[0] + ")" when :trace then description += " in\n " + exception.backtrace.join("\n ") + ")" end else description += ")" end end description end |
#init(identity = nil, path = nil, opts = {}) ⇒ Object
Initialize logger
Parameters
- identity(String)
-
Log identity
- path(String)
-
Log directory path
- opts(TrueClass|FalseClass)
-
Whether to re-initialize if logger is already initialized
- opts(TrueClass|FalseClass)
-
Whether to print to STDOUT log destination
Return
- logger(RightScale::Multiplexer)
-
logger instance
428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 |
# File 'lib/right_agent/log.rb', line 428 def init(identity=nil, path=nil, opts={}) if opts[:force] || !@initialized @initialized = true @level_frozen = false logger = nil if @log_to_file_only || Platform.windows? if path file = File.join(path, "#{identity}.log") else file = STDOUT end $stderr.puts "Logging to #{file}" if opts[:print] logger = Logger.new(file) logger.formatter = Formatter.new logger.progname = @program_name || identity || 'RightAgent' logger.formatter.datetime_format = "%b %d %H:%M:%S" else $stderr.puts "Logging to syslog" if opts[:print] program_name = @program_name || identity || 'RightAgent' facility = @facility || 'local0' logger = RightSupport::Log::SystemLogger.new(program_name, :facility=>facility) end @logger = Multiplexer.new(logger) self.level = :info end @logger end |
#initialized ⇒ Object
Was logger initialized?
Return
- true
-
if logger has been initialized
- false
-
Otherwise
300 301 302 |
# File 'lib/right_agent/log.rb', line 300 def initialized @initialized end |
#level ⇒ Object
Current log level
Return
- level(Symbol)
-
One of :debug, :info, :warn, :error or :fatal
376 377 378 379 |
# File 'lib/right_agent/log.rb', line 376 def level init unless @initialized level = level_to_sym(@level) end |
#level=(level) ⇒ Object
Sets the level for the Logger by symbol or by Logger constant
Parameters
- level(Object)
-
One of :debug, :info, :warn, :error, :fatal or one of “debug”, “info”, “warn”, “error”, “fatal” or one of Logger::INFO … Logger::FATAL
Return
- level(Symbol)
-
New log level, or current level if frozen
347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 |
# File 'lib/right_agent/log.rb', line 347 def level=(level) init unless @initialized unless @level_frozen new_level = case level when Symbol then level_from_sym(level) when String then level_from_sym(level.to_sym) else level end if new_level != @level @logger.info("[setup] Setting log level to #{level_to_sym(new_level).to_s.upcase}") if new_level == Logger::DEBUG && !RightScale::Platform.windows? @logger.info("[setup] Check syslog configuration to ensure debug messages are not discarded!") else end @logger.level = @level = new_level end # Notify even if unchanged since don't know when callback was set @notify.each { |n| n.call(@level) } if @notify end level = level_to_sym(@level) end |
#level_from_sym(sym) ⇒ Object
Map symbol log level to Logger constant
Parameters
- sym(Symbol)
-
Log level symbol, one of :debug, :info, :warn, :error or :fatal
Return
- lvl(Constant)
-
One of Logger::DEBUG … Logger::FATAL
Raise
- (ArgumentError)
-
if level symbol is invalid
226 227 228 229 |
# File 'lib/right_agent/log.rb', line 226 def level_from_sym(sym) raise ArgumentError, "Invalid log level symbol :#{sym}" unless LEVELS_MAP.include?(sym) lvl = LEVELS_MAP[sym] end |
#level_to_sym(lvl) ⇒ Object
Map Logger log level constant to symbol
Parameters
- lvl(Constant)
-
Log level constant, one of Logger::DEBUG … Logger::FATAL
Return
- sym(Symbol)
-
One of :debug, :info, :warn, :error or :fatal
Raise
- (ArgumentError)
-
if level is invalid
241 242 243 244 245 |
# File 'lib/right_agent/log.rb', line 241 def level_to_sym(lvl) @@inverted_levels_map ||= LEVELS_MAP.invert raise ArgumentError, "Invalid log level: #{lvl}" unless @@inverted_levels_map.include?(lvl) sym = @@inverted_levels_map[lvl] end |
#log_to_file_only(val) ⇒ Object
Set whether syslog should be used or to log to an agent-specific file This should be called before anything else
Parameters
- val(Boolean)
-
Whether syslog should be used (false) or a agent-specific log file (true)
Raise
- RuntimeError
-
If logger is already initialized
290 291 292 293 |
# File 'lib/right_agent/log.rb', line 290 def log_to_file_only(val) raise 'Logger already initialized' if @initialized @log_to_file_only = !!val end |
#logger ⇒ Object
Read access to internal multiplexer
Return
- logger(RightScale::Multiplexer)
-
Multiplexer logger
251 252 253 254 |
# File 'lib/right_agent/log.rb', line 251 def logger init unless @initialized logger = @logger end |
#notify(callback) ⇒ Object
Register callback to be activated when there is a logging configuration change Currently the only logging change reported is log level
Parameters
- callback(Proc)
-
Block to be activated with following parameter when log level changes:
- log_level(Symbol)
-
Current log level
Return
- true
-
Always return true
390 391 392 393 |
# File 'lib/right_agent/log.rb', line 390 def notify(callback) @notify = (@notify ||= []) << callback true end |
#program_name=(prog_name) ⇒ Object
Sets the syslog program name that will be reported Can only be successfully called before logging is initialized
Parameters
- prog_name(String)
-
An arbitrary string, or “nil” to use
the default name that is based on the agent's identity
Return
- program_name(String)
-
The input string
Raise
- RuntimeError
-
If logger is already initialized
317 318 319 320 |
# File 'lib/right_agent/log.rb', line 317 def program_name=(prog_name) raise 'Logger already initialized' if @initialized @program_name = prog_name end |
#remove_logger(logger) ⇒ Object
Remove logger from list of multiplexed loggers
Parameters
- logger(Object)
-
Logger to be removed
Return
- @logger(RightScale::Multiplexer)
-
Multiplexer logger
276 277 278 279 |
# File 'lib/right_agent/log.rb', line 276 def remove_logger(logger) init unless @initialized @logger.remove(logger) end |
#respond_to?(m, *args) ⇒ Boolean
Determine whether this object, or its method_missing proxy, responds to the given method name. This follows the best practice of always overriding #respond_to? whenever one implements dynamic dispatch via #method_missing.
Parameters
- m(Symbol)
-
Forwarded method name
Return
- (true|false)
-
True if this object or its proxy responds to the names method, false otherwise
149 150 151 |
# File 'lib/right_agent/log.rb', line 149 def respond_to?(m, *args) super(m, *args) || @logger.respond_to?(m, *args) end |
#warning(description, exception = nil, backtrace = :caller) ⇒ Object Also known as: warn
Log warning and optionally append exception information
Parameters
- description(String)
-
Error description
- exception(Exception|String)
-
Associated exception or other parenthetical error information
- backtrace(Symbol)
-
Exception backtrace extent: :no_trace, :caller, or :trace,
defaults to :caller
Return
- (Object)
-
Result from first registered logger
163 164 165 166 |
# File 'lib/right_agent/log.rb', line 163 def warning(description, exception = nil, backtrace = :caller) init unless @initialized @logger.warn(format(description, exception, backtrace)) end |