summaryrefslogtreecommitdiff
path: root/lib/rbot/logger.rb
diff options
context:
space:
mode:
Diffstat (limited to 'lib/rbot/logger.rb')
-rw-r--r--lib/rbot/logger.rb128
1 files changed, 128 insertions, 0 deletions
diff --git a/lib/rbot/logger.rb b/lib/rbot/logger.rb
new file mode 100644
index 00000000..1598f7bd
--- /dev/null
+++ b/lib/rbot/logger.rb
@@ -0,0 +1,128 @@
+# encoding: UTF-8
+#-- vim:sw=2:et
+#++
+#
+# :title: rbot logger
+
+require 'logger'
+require 'thread'
+require 'singleton'
+
+module Irc
+class Bot
+
+ class LoggerManager
+ include Singleton
+
+ def initialize
+ @dateformat = "%Y/%m/%d %H:%M:%S"
+
+ @logger = Logger.new(STDERR)
+ @logger.datetime_format = @dateformat
+ @logger.level = Logger::Severity::DEBUG
+ @file_logger = nil
+
+ @queue = Queue.new
+ @thread = start_thread
+ end
+
+ def set_logfile(filename, keep, max_size)
+ @file_logger = Logger.new(filename, keep, max_size*1024*1024)
+ @file_logger.datetime_format = @dateformat
+ end
+
+ def set_level(level)
+ @logger.level = level
+ if @file_logger
+ @file_logger.level = level
+ end
+ end
+
+ def sync_log(severity, message = nil, progname = nil)
+ @logger.add(severity, message, progname)
+ if @file_logger
+ @file_logger.add(severity, message, progname)
+ end
+ end
+
+ def async_log(severity, message=nil, who_pos=1)
+ unless @thread
+ STDERR.puts('logger thread already destroyed, cannot log message!')
+ end
+
+ call_stack = caller
+ if call_stack.length > who_pos
+ who = call_stack[who_pos].sub(%r{(?:.+)/([^/]+):(\d+)(:in .*)?}) { "#{$1}:#{$2}#{$3}" }
+ else
+ who = "(unknown)"
+ end
+ # Output each line. To distinguish between separate messages and multi-line
+ # messages originating at the same time, we blank #{who} after the first message
+ # is output.
+ # Also, we output strings as-is but for other objects we use pretty_inspect
+ message = message.kind_of?(String) ? message : (message.pretty_inspect rescue '?')
+ qmsg = Array.new
+ message.each_line { |l|
+ qmsg.push [severity, l.chomp, who]
+ who = ' ' * who.size
+ }
+ @queue.push qmsg
+ end
+
+ def log_session_start
+ if @file_logger
+ @file_logger << "\n\n=== session started on #{Time.now.strftime(@dateformat)} ===\n\n"
+ end
+ end
+
+ def log_session_end
+ if @file_logger
+ @file_logger << "\n\n=== session ended on #{Time.now.strftime(@dateformat)} ===\n\n"
+ end
+ end
+
+ def halt_logger
+ if @thread and @thread.alive?
+ @queue << nil
+ @thread.join
+ @thread = nil
+ end
+ end
+
+ private
+
+ def start_thread
+ Thread.new do
+ lines = nil
+ while lines = @queue.pop
+ lines.each { |line|
+ sync_log(*line)
+ }
+ end
+ end
+ end
+
+ end
+
+end
+end
+
+def debug(message=nil, who_pos=1)
+ Irc::Bot::LoggerManager.instance.async_log(Logger::Severity::DEBUG, message, who_pos)
+end
+
+def log(message=nil, who_pos=1)
+ Irc::Bot::LoggerManager.instance.async_log(Logger::Severity::INFO, message, who_pos)
+end
+
+def warning(message=nil, who_pos=1)
+ Irc::Bot::LoggerManager.instance.async_log(Logger::Severity::WARN, message, who_pos)
+end
+
+def error(message=nil, who_pos=1)
+ Irc::Bot::LoggerManager.instance.async_log(Logger::Severity::ERROR, message, who_pos)
+end
+
+def fatal(message=nil, who_pos=1)
+ Irc::Bot::LoggerManager.instance.async_log(Logger::Severity::FATAL, message, who_pos)
+end