metasploit-framework/lib/rex/logging/log_dispatcher.rb

127 lines
2.6 KiB
Ruby

require 'Rex'
module Rex
module Logging
###
#
# LogDispatcher
# -------------
#
# The log dispatcher associates log sources with log sinks. A log source
# is a unique identity that is associated with one and only one log sink.
# For instance, the framework-core registers the 'core'
#
###
class LogDispatcher
def initialize()
self.log_sinks = {}
self.log_sinks_rwlock = ReadWriteLock.new
end
# Returns the sink that is associated with the supplied source
def [](src)
sink = nil
log_sinks_rwlock.synchronize_read {
sink = log_sinks[src]
}
return sink
end
# Calls the source association routnie
def []=(src, sink)
store(src, sink)
end
# Associates the supplied source with the supplied sink
def store(src, sink)
log_sinks_rwlock.synchronize_write {
if (log_sinks[src] == nil)
log_sinks[src] = sink
else
raise(
RuntimeError,
"The supplied log source #{src} is already registered.",
caller)
end
}
end
# Removes a source association if one exists
def delete(src)
sink = nil
log_sinks_rwlock.synchronize_write {
sink = log_sinks[src]
log_sinks.delete(src)
}
if (sink)
sink.cleanup
return true
end
return false
end
# Performs the actual log operation against the supplied source
def log(sev, src, level, msg, from)
log_sinks_rwlock.synchronize_read {
if ((sink = log_sinks[src]))
sink.log(sev, src, level, msg, from)
end
}
end
attr_accessor :log_sinks, :log_sinks_rwlock
end
end
end
###
#
# An instance of the log dispatcher exists in the global namespace, along
# with stubs for many of the common logging methods. Various sources can
# register themselves as a log sink such that logs can be directed at
# various targets depending on where they're sourced from. By doing it
# this way, things like sessions can use the global logging stubs and
# still be directed at the correct log file.
#
###
def dlog(msg, src = 'core', level = 0, from = caller)
$dispatcher.log(LOG_DEBUG, src, level, msg, from)
end
def elog(msg, src = 'core', level = 0, from = caller)
$dispatcher.log(LOG_ERROR, src, level, msg, from)
end
def wlog(msg, src = 'core', level = 0, from = caller)
$dispatcher.log(LOG_WARN, src, level, msg, from)
end
def ilog(msg, src = 'core', level = 0, from = caller)
$dispatcher.log(LOG_INFO, src, level, msg, from)
end
def rlog(msg, src = 'core', level = 0, from = caller)
$dispatcher.log(LOG_RAW, src, level, msg, from)
end
def register_log_source(src, sink)
$dispatcher[src] = sink
end
def deregister_log_source(src, sink)
$dispatcher.delete(src)
end
# Creates the global log dispatcher
$dispatcher = Rex::Logging::LogDispatcher.new