X-Git-Url: https://review.fuel-infra.org/gitweb?a=blobdiff_plain;ds=sidebyside;f=lib%2Fmcollective%2Flog.rb;fp=lib%2Fmcollective%2Flog.rb;h=7e3d774c65ef4255a0af9ceb3b2df14ec1719439;hb=b87d2f4e68281062df1913440ca5753ae63314a9;hp=0000000000000000000000000000000000000000;hpb=ab0ea530b8ac956091f17b104ab2311336cfc250;p=packages%2Fprecise%2Fmcollective.git diff --git a/lib/mcollective/log.rb b/lib/mcollective/log.rb new file mode 100644 index 0000000..7e3d774 --- /dev/null +++ b/lib/mcollective/log.rb @@ -0,0 +1,168 @@ +module MCollective + # A simple class that allows logging at various levels. + class Log + class << self + @logger = nil + + VALID_LEVELS = [:error, :fatal, :debug, :warn, :info] + + # Obtain the class name of the currently configured logger + def logger + @logger.class + end + + # Logs at info level + def info(msg) + log(:info, msg) + end + + # Logs at warn level + def warn(msg) + log(:warn, msg) + end + + # Logs at debug level + def debug(msg) + log(:debug, msg) + end + + # Logs at fatal level + def fatal(msg) + log(:fatal, msg) + end + + # Logs at error level + def error(msg) + log(:error, msg) + end + + # handle old code that relied on this class being a singleton + def instance + self + end + + # increments the active log level + def cycle_level + @logger.cycle_level if @configured + end + + def config_and_check_level(level) + configure unless @configured + check_level(level) + @logger.should_log?(level) + end + + def check_level(level) + raise "Unknown log level" unless valid_level?(level) + end + + def valid_level?(level) + VALID_LEVELS.include?(level) + end + + def message_for(msgid, args={}) + "%s: %s" % [msgid, Util.t(msgid, args)] + end + + def logexception(msgid, level, e, backtrace=false, args={}) + return false unless config_and_check_level(level) + + origin = File.basename(e.backtrace[1]) + + if e.is_a?(CodedError) + msg = "%s: %s" % [e.code, e.to_s] + else + error_string = "%s: %s" % [e.class, e.to_s] + msg = message_for(msgid, args.merge(:error => error_string)) + end + + log(level, msg, origin) + + if backtrace + e.backtrace.each do |line| + log(level, "%s: %s" % [msgid, line], origin) + end + end + end + + # Logs a message at a certain level, the message must be + # a token that will be looked up from the i18n localization + # database + # + # Messages can interprolate strings from the args hash, a + # message with "foo %{bar}" in the localization database + # will use args[:bar] for the value there, the interprolation + # is handled by the i18n library itself + def logmsg(msgid, default, level, args={}) + return false unless config_and_check_level(level) + + msg = message_for(msgid, {:default => default}.merge(args)) + + log(level, msg) + end + + # logs a message at a certain level + def log(level, msg, origin=nil) + return unless config_and_check_level(level) + + origin = from unless origin + + if @logger + @logger.log(level, origin, msg) + else + t = Time.new.strftime("%H:%M:%S") + + STDERR.puts "#{t}: #{level}: #{origin}: #{msg}" + end + end + + # sets the logger class to use + def set_logger(logger) + @logger = logger + end + + # configures the logger class, if the config has not yet been loaded + # we default to the console logging class and do not set @configured + # so that future calls to the log method will keep attempting to configure + # the logger till we eventually get a logging preference from the config + # module + def configure(logger=nil) + unless logger + logger_type = "console" + + config = Config.instance + + if config.configured + logger_type = config.logger_type + @configured = true + end + + require "mcollective/logger/%s_logger" % logger_type.downcase + + logger_class = MCollective::Logger.const_get("%s_logger" % logger_type.capitalize) + + set_logger(logger_class.new) + else + set_logger(logger) + @configured = true + end + + + @logger.start + rescue Exception => e + @configured = false + STDERR.puts "Could not start logger: #{e.class} #{e}" + end + + def unconfigure + @configured = false + set_logger(nil) + end + + # figures out the filename that called us + def from + from = File.basename(caller[2]) + end + end + end +end