# :include: ../rdoc/syslogoutputter # # Version:: $Id: syslogoutputter.rb,v 1.3 2009/09/23 06:20:19 colbygk Exp $ # Author:: Steve Lumos # Author:: Leon Torres require 'log4r/formatter/formatter' require 'log4r/outputter/outputter' require 'log4r/configurator' require 'syslog' module Log4r # syslog needs to set the custom levels #if LNAMES.size > 1 # raise LoadError, "Must let syslogger.rb define custom levels" #end # tune log4r to syslog priorities #Configurator.custom_levels("DEBUG", "INFO", "NOTICE", "WARNING", "ERR", "CRIT", "ALERT", "EMERG") SYSLOGNAMES = Hash.new class SyslogOutputter < Outputter include Syslog::Constants # maps default log4r levels to syslog priorities (logevents never see ALL and OFF) SYSLOG_LEVELS_MAP = { "DEBUG" => LOG_DEBUG, "INFO" => LOG_INFO, "NOTICE" => LOG_NOTICE, # by default NOTICE is not in log4r "WARN" => LOG_WARNING, "ERROR" => LOG_ERR, "FATAL" => LOG_CRIT, "ALERT" => LOG_ALERT, # by default ALERT is not in log4r "EMERG" => LOG_EMERG, # by default EMERG is not in log4r } SYSLOG_LOG4R_MAP = { "DEBUG" => "DEBUG", "INFO" => "INFO", "WARN" => "WARN", "ERROR" => "ERROR", "FATAL" => "FATAL" # "NOTICE" => "INFO", # by default NOTICE is not in log4r # "ALERT" => "FATAL", # by default ALERT is not in log4r # "EMERG" => "FATAL" # by default EMERG is not in log4r } @levels_map = SYSLOG_LOG4R_MAP # There are 3 hash arguments # # [:ident] syslog ident, defaults to _name # [:logopt] syslog logopt, defaults to LOG_PID | LOG_CONS # [:facility] syslog facility, defaults to LOG_USER def initialize(_name, hash={}) super(_name, hash) ident = (hash[:ident] or hash['ident'] or _name) logopt = (hash[:logopt] or hash['logopt'] or LOG_PID | LOG_CONS).to_i facility = (hash[:facility] or hash['facility'] or LOG_USER).to_i map_levels_by_name_to_syslog() @syslog = Syslog.open(ident, logopt, facility) end def closed? return !@syslog.opened? end def close @syslog.close unless @syslog.nil? @level = OFF OutputterFactory.create_methods(self) Logger.log_internal {"Outputter '#{@name}' closed Syslog and set to OFF"} end # A single hash argument that maps custom names to syslog names # # [levels_map] A map that will create a linkage between levels # in a hash and underlying syslog levels. # By default, these are direct mapping of the log4r # levels (e.g. "DEBUG" => "DEBUG") # If you have defined your own custom levels, you # should provide this underlying mapping, otherwise # all messages will be mapped to the underlying syslog # level of INFO by default. def map_levels_by_name_to_syslog( lmap = SYSLOG_LOG4R_MAP ) @levels_map = lmap end def get_levels_map() return @levels_map end private def canonical_log(logevent) pri = SYSLOG_LEVELS_MAP[@levels_map[LNAMES[logevent.level]]] rescue pri = LOG_INFO o = format(logevent) if o.kind_of? Exception then msg = "#{o.class} at (#{o.backtrace[0]}): #{o.message}" elsif o.respond_to? :to_str then msg = o.to_str else msg = o.inspect end @syslog.log(pri, '%s', msg) end end end