X-Git-Url: https://git.netwichtig.de/gitweb/?a=blobdiff_plain;f=lib%2Frbot%2Fircbot.rb;h=564403f5d3bdfb7868708e6a874bc1cb0ae59b4e;hb=3c9454d8a1f649f62a4f45461337434a791b1109;hp=eb158c6329fcb1a55a169b50fc3f80d086b35b66;hpb=8c666c5d1172310a693bf004cf33063f516cba28;p=user%2Fhenk%2Fcode%2Fruby%2Frbot.git diff --git a/lib/rbot/ircbot.rb b/lib/rbot/ircbot.rb index eb158c63..564403f5 100644 --- a/lib/rbot/ircbot.rb +++ b/lib/rbot/ircbot.rb @@ -9,20 +9,6 @@ require 'thread' require 'etc' require 'date' require 'fileutils' -require 'logger' - -$debug = false unless $debug -$daemonize = false unless $daemonize - -$dateformat = "%Y/%m/%d %H:%M:%S" -$logger = Logger.new($stderr) -$logger.datetime_format = $dateformat -$logger.level = $cl_loglevel if defined? $cl_loglevel -$logger.level = 0 if $debug -$logger_stderr = $logger - -$log_queue = Queue.new -$log_thread = nil require 'pp' @@ -47,106 +33,14 @@ end class ServerError < RuntimeError end -def rawlog(level, message=nil, who_pos=1) - 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 [level, l.chomp, who] - who = ' ' * who.size - } - if level >= Logger::Severity::WARN and not $daemonize - qmsg.each do |l| - $logger_stderr.add(*l) - end - end - $log_queue.push qmsg -end - -def halt_logger - if $log_thread && $log_thread.alive? - $log_queue << nil - $log_thread.join - $log_thread = nil - end -end - -END { halt_logger } - -def restart_logger(newlogger = false) - halt_logger - - $logger = newlogger if newlogger - - $log_thread = Thread.new do - ls = nil - while ls = $log_queue.pop - ls.each { |l| $logger.add(*l) } - end - end -end - -restart_logger - -def log_session_start - $logger << "\n\n=== #{botclass} session started on #{Time.now.strftime($dateformat)} ===\n\n" - restart_logger -end - -def log_session_end - $logger << "\n\n=== #{botclass} session ended on #{Time.now.strftime($dateformat)} ===\n\n" - $log_queue << nil -end - -def debug(message=nil, who_pos=1) - rawlog(Logger::Severity::DEBUG, message, who_pos) -end - -def log(message=nil, who_pos=1) - rawlog(Logger::Severity::INFO, message, who_pos) -end - -def warning(message=nil, who_pos=1) - rawlog(Logger::Severity::WARN, message, who_pos) -end - -def error(message=nil, who_pos=1) - rawlog(Logger::Severity::ERROR, message, who_pos) -end - -def fatal(message=nil, who_pos=1) - rawlog(Logger::Severity::FATAL, message, who_pos) -end - -debug "debug test" -log "log test" -warning "warning test" -error "error test" -fatal "fatal test" - # The following global is used for the improved signal handling. $interrupted = 0 # these first +require 'rbot/logger' require 'rbot/rbotconfig' -begin - require 'rubygems' -rescue LoadError - log "rubygems unavailable" -end - require 'rbot/load-gettext' require 'rbot/config' - require 'rbot/irc' require 'rbot/rfc2812' require 'rbot/ircsocket' @@ -156,6 +50,7 @@ require 'rbot/registry' require 'rbot/plugins' require 'rbot/message' require 'rbot/language' +require 'rbot/httputil' module Irc @@ -163,7 +58,7 @@ module Irc # handles them or passes them to plugins, and contains core functionality. class Bot COPYRIGHT_NOTICE = "(c) Giuseppe Bilotta and the rbot development team" - SOURCE_URL = "http://ruby-rbot.org" + SOURCE_URL = "https://ruby-rbot.org" # the bot's Auth data attr_reader :auth @@ -201,6 +96,7 @@ class Bot # loads and opens new registry databases, used by the plugins attr_accessor :registry_factory + # web service attr_accessor :webservice # server we are connected to @@ -367,7 +263,7 @@ class Bot :default => 1, :requires_restart => false, :validate => Proc.new { |v| (0..5).include?(v) }, :on_change => Proc.new { |bot, v| - $logger.level = v + LoggerManager.instance.set_level(v) }, :desc => "The minimum logging level (0=DEBUG,1=INFO,2=WARN,3=ERROR,4=FATAL) for console messages") Config.register Config::IntegerValue.new('log.keep', @@ -477,13 +373,6 @@ class Bot repopulate_botclass_directory - save_dir = File.join(@botclass, 'safe_save') - Dir.mkdir(save_dir) unless File.exist?(save_dir) - unless FileTest.directory? save_dir - error "safe save location #{save_dir} is not a directory" - exit 2 - end - # Time at which the last PING was sent @last_ping = nil # Time at which the last line was RECV'd from the server @@ -496,7 +385,6 @@ class Bot @config.bot_associate(self) rescue Exception => e fatal e - log_session_end exit 2 end @@ -508,13 +396,15 @@ class Bot @registry_factory.migrate_registry_folder(path) @logfile = @config['log.file'] - if @logfile.class!=String || @logfile.empty? + if @logfile.class != String || @logfile.empty? logfname = File.basename(botclass).gsub(/^\.+/,'') logfname << ".log" @logfile = File.join(botclass, logfname) debug "Using `#{@logfile}' as debug log" end + LoggerManager.instance.flush + # See http://blog.humlab.umu.se/samuel/archives/000107.html # for the backgrounding code if $daemonize @@ -533,20 +423,18 @@ class Bot # File.umask 0000 # Ensure sensible umask. Adjust as needed. end - logger = Logger.new(@logfile, - @config['log.keep'], - @config['log.max_size']*1024*1024) - logger.datetime_format= $dateformat - logger.level = @config['log.level'] - logger.level = $cl_loglevel if defined? $cl_loglevel - logger.level = 0 if $debug - - restart_logger(logger) + # setup logger based on bot configuration, if not set from the command line + loglevel_set = $opts.has_key?('debug') or $opts.has_key?('loglevel') + LoggerManager.instance.set_level(@config['log.level']) unless loglevel_set - log_session_start + # Set the logfile + LoggerManager.instance.set_logfile(@logfile, @config['log.keep'], @config['log.max_size']) if $daemonize - log "Redirecting standard input/output/error" + log "Redirecting standard input/output/error, console logger disabled" + LoggerManager.instance.flush + LoggerManager.instance.disable_console_logger + [$stdin, $stdout, $stderr].each do |fd| begin fd.reopen "/dev/null" @@ -556,18 +444,22 @@ class Bot end end - def $stdout.write(str=nil) + def $stdout.write(*args) + str = args.map { |s| s.to_s }.join("") log str, 2 - return str.to_s.size + return str.bytesize end - def $stdout.write(str=nil) + def $stderr.write(*args) + str = args.map { |s| s.to_s }.join("") if str.to_s.match(/:\d+: warning:/) warning str, 2 else error str, 2 end - return str.to_s.size + return str.bytesize end + + LoggerManager.instance.log_session_start end File.open($opts['pidfile'] || File.join(@botclass, 'rbot.pid'), 'w') do |pf| @@ -585,6 +477,7 @@ class Bot @plugins = nil @lang = Language.new(self, @config['core.language']) + @httputil = Utils::HttpUtil.new(self) begin @auth = Auth::manager @@ -592,7 +485,6 @@ class Bot # @auth.load("#{botclass}/botusers.yaml") rescue Exception => e fatal e - log_session_end exit 2 end @auth.everyone.set_default_permission("*", true) @@ -697,7 +589,7 @@ class Bot # to inform us that our nick has been changed. if data[:target] == '*' debug "setting my connection nick to #{new}" - nick = new + @client.user.nick = new end @plugins.delegate "nicktaken", data[:nick] } @@ -955,7 +847,6 @@ class Bot debug "interrupted #{$interrupted} times" if $interrupted >= 3 debug "drastic!" - log_session_end exit 2 end end @@ -1030,7 +921,6 @@ class Bot connect rescue SystemExit - log_session_end exit 0 rescue Exception => e error e @@ -1041,7 +931,8 @@ class Bot # begin event handling loop def mainloop - while true + @keep_looping = true + while @keep_looping too_fast = 0 quit_msg = nil valid_recv = false # did we receive anything (valid) from the server yet? @@ -1071,8 +962,8 @@ class Bot # exceptions that ARENT SocketError's. How am I supposed to handle # that? rescue SystemExit - log_session_end - exit 0 + @keep_looping = false + break rescue Errno::ETIMEDOUT, Errno::ECONNABORTED, TimeoutError, SocketError => e error "network exception: #{e.pretty_inspect}" quit_msg = e.to_s @@ -1115,7 +1006,6 @@ class Bot quit_msg = e.to_s rescue => e fatal "unexpected exception: #{e.pretty_inspect}" - log_session_end exit 2 end end @@ -1355,6 +1245,7 @@ class Bot debug "\tignoring cleanup error: #{$!}" end end + @httputil.cleanup # debug "\tstopping timers ..." # @timer.stop # debug "Closing registries" @@ -1369,7 +1260,7 @@ class Bot begin shutdown(message) ensure - exit 0 + @keep_looping = false end end @@ -1379,16 +1270,18 @@ class Bot :wait => @config['server.reconnect_wait'] } if (!message || message.empty?) shutdown(message) + + Irc::Bot::LoggerManager.instance.flush + Irc::Bot::LoggerManager.instance.log_session_end + sleep @config['server.reconnect_wait'] begin # now we re-exec # Note, this fails on Windows debug "going to exec #{$0} #{@argv.inspect} from #{@run_dir}" - log_session_end Dir.chdir(@run_dir) exec($0, *@argv) rescue Errno::ENOENT - log_session_end exec("ruby", *(@argv.unshift $0)) rescue Exception => e $interrupted += 1