class Swiftcore::LoggerClass
Constants
- DefaultSeverityLevels
- EXEC_ARGUMENTS
- EXIT_SIGNALS
- RELOAD_SIGNALS
- RESTART_SIGNALS
- VERSION
Public Class Methods
_handle_pending_and_exit()
click to toggle source
# File lib/swiftcore/Analogger.rb, line 101 def _handle_pending_and_exit if any_in_queue? write_queue EventMachine.next_tick {_handle_pending_and_exit} else EventMachine.stop end end
add_log(log)
click to toggle source
# File lib/swiftcore/Analogger.rb, line 206 def add_log(log) @queue[log.first] << log @rcount += 1 end
any_in_queue?()
click to toggle source
# File lib/swiftcore/Analogger.rb, line 211 def any_in_queue? any = 0 @queue.each do |service, q| q.each do |m| next unless levels.has_key?(m[1]) any += 1 end end any > 0 ? any : false end
check_config_settings()
click to toggle source
# File lib/swiftcore/Analogger.rb, line 174 def check_config_settings raise NoPortProvided unless @config[-"port"] raise BadPort.new(@config[-"port"]) unless @config[-"port"].to_i > 0 end
cleanup()
click to toggle source
# File lib/swiftcore/Analogger.rb, line 110 def cleanup @logs.each do |service,l| l.logfile.fsync if !l.logfile.closed? and l.logfile.fileno > 2 l.logfile.close unless l.logfile.closed? or l.logfile.fileno < 3 end end
cleanup_and_reopen()
click to toggle source
# File lib/swiftcore/Analogger.rb, line 117 def cleanup_and_reopen @logs.each do |service,l| l.logfile.fsync if !l.logfile.closed? and l.logfile.fileno > 2 l.logfile.reopen(l.logfile.path, -"ab+") if l.logfile.fileno > 2 end end
config()
click to toggle source
# File lib/swiftcore/Analogger.rb, line 128 def config @config end
config=(conf)
click to toggle source
# File lib/swiftcore/Analogger.rb, line 132 def config=(conf) @config = conf end
daemonize()
click to toggle source
# File lib/swiftcore/Analogger.rb, line 76 def daemonize if (child_pid = fork) puts "PID #{child_pid}" unless @config[-"pidfile"] exit! end Process.setsid exit if fork rescue NotImplementedError puts "Platform (#{RUBY_PLATFORM}) does not appear to support fork/setsid; skipping" end
flush_queue()
click to toggle source
# File lib/swiftcore/Analogger.rb, line 255 def flush_queue @logs.each_value do |l| #if !l.logfile.closed? and l.logfile.fileno > 2 if l.logfile.fileno > 2 l.logfile.fdatasync rescue l.logfile.fsync end end end
handle_pending_and_exit()
click to toggle source
Before exiting, try to get any logs that are still in memory handled and written to disk.
# File lib/swiftcore/Analogger.rb, line 94 def handle_pending_and_exit EventMachine.stop_server(@server) EventMachine.add_timer(1) do _handle_pending_and_exit end end
key()
click to toggle source
# File lib/swiftcore/Analogger.rb, line 264 def key @config[-"key"].to_s end
logfile_destination(logfile)
click to toggle source
# File lib/swiftcore/Analogger.rb, line 189 def logfile_destination(logfile) # We're reloading if it's already an IO. if logfile.is_a?(IO) return $stdout if logfile == $stdout return $stderr if logfile == $stderr return logfile.reopen(logfile.path, -"ab+") end if logfile =~ /^STDOUT$/i $stdout elsif logfile =~ /^STDERR$/i $stderr else File.open(logfile, -"ab+") end end
new_log(facility = -"default", levels = @config[-"levels"] || DefaultSeverityLevels, log = @config[-"default_log"], cull = true)
click to toggle source
# File lib/swiftcore/Analogger.rb, line 89 def new_log(facility = -"default", levels = @config[-"levels"] || DefaultSeverityLevels, log = @config[-"default_log"], cull = true) Log.new({-"service" => facility, -"levels" => levels, -"logfile" => log, -"cull" => cull}) end
normalize_levels(levels)
click to toggle source
# File lib/swiftcore/Analogger.rb, line 160 def normalize_levels(levels) if String === levels and levels =~ /,/ levels.split(/,/).inject({}) {|h,k| h[k.to_s] = true; h} elsif Array === levels levels.inject({}) {|h,k| h[k.to_s] = true; h} elsif levels.nil? DefaultSeverityLevels elsif !(Hash === levels) [levels.to_s => true] else levels end end
populate_logs()
click to toggle source
# File lib/swiftcore/Analogger.rb, line 136 def populate_logs @config[-"logs"].each do |log| next unless log[-"service"] if Array === log[-"service"] log[-"service"].each do |loglog| @logs[loglog] = new_log(loglog,log[-"levels"],logfile_destination(log[-"logfile"]),log[-"cull"]) end else @logs[log[-"service"]] = new_log(log[-"service"],log[-"levels"],logfile_destination(log[-"logfile"]),log[-"cull"]) end end end
postprocess_config_load()
click to toggle source
# File lib/swiftcore/Analogger.rb, line 149 def postprocess_config_load @config[-"logs"] ||= [] if @config[-"levels"] @config[-"levels"] = normalize_levels(@config[-"levels"]) end @config[-"logs"].each do |log| log[-"levels"] = normalize_levels(log[-"levels"]) end end
safe_trap(siglist, &operation)
click to toggle source
# File lib/swiftcore/Analogger.rb, line 27 def safe_trap(siglist, &operation) (Signal.list.keys & siglist).each {|sig| trap(sig, &operation)} end
set_config_defaults()
click to toggle source
# File lib/swiftcore/Analogger.rb, line 179 def set_config_defaults @config[-"host"] ||= -"127.0.0.1" @config[-"interval"] ||= 1 @config[-"syncinterval"] ||= 60 @config[-"syncinterval"] = nil if @config[-"syncinterval"] == 0 @config[-"default_log"] = @config[-"default_log"].nil? || @config[-"default_log"] == -"-" ? -"STDOUT" : @config[-"default_log"] @config[-"default_log"] = logfile_destination(@config[-"default_log"]) @logs[-"default"] = new_log end
start(config,protocol = AnaloggerProtocol)
click to toggle source
# File lib/swiftcore/Analogger.rb, line 31 def start(config,protocol = AnaloggerProtocol) @config = config daemonize if @config[-"daemonize"] File.open(@config[-"pidfile"],-"w+") {|fh| fh.puts $$} if @config[-"pidfile"] @logs = Hash.new {|h,k| h[k] = new_log(k)} @queue = Hash.new {|h,k| h[k] = []} postprocess_config_load check_config_settings populate_logs set_config_defaults @rcount = 0 @wcount = 0 @server = nil safe_trap(EXIT_SIGNALS) {handle_pending_and_exit} safe_trap(RELOAD_SIGNALS) {cleanup_and_reopen} safe_trap(RESTART_SIGNALS) {exec(*EXEC_ARGUMENTS)} ##### # This is gross. EM needs to change so that it defaults to the faster # platform specific methods, allowing the user the option to downgrade # to a simple select() loop if they have a good reason for it. # EventMachine.epoll rescue nil EventMachine.kqueue rescue nil # # End of gross. # # TODO: The above was written YEARS ago. See if EventMachine is smarter, now. ##### EventMachine.set_descriptor_table_size(4096) EventMachine.run { EventMachine.add_shutdown_hook do write_queue flush_queue cleanup end @server = EventMachine.start_server @config[-"host"], @config[-"port"], protocol EventMachine.add_periodic_timer(1) {Analogger.update_now} EventMachine.add_periodic_timer(@config[-"interval"]) {write_queue} EventMachine.add_periodic_timer(@config[-"syncinterval"]) {flush_queue} } exit end
update_now()
click to toggle source
# File lib/swiftcore/Analogger.rb, line 124 def update_now @now = Time.now.strftime(-"%Y/%m/%d %H:%M:%S") end
write_queue()
click to toggle source
# File lib/swiftcore/Analogger.rb, line 222 def write_queue @queue.each do |service, q| last_sv = nil last_m = nil last_count = 0 next unless log = @logs[service] lf = log.logfile cull = log.cull levels = log.levels q.each do |m| next unless levels.has_key?(m[1]) if cull if m.last == last_m and m[0..1] == last_sv last_count += 1 next elsif last_count > 0 lf.write_nonblock "#{@now}|#{last_sv.join(-"|")}|Last message repeated #{last_count} times\n" last_sv = last_m = nil last_count = 0 end lf.write_nonblock "#{@now}|#{m.join(-"|")}\n" last_m = m.last last_sv = m[0..1] else lf.write_nonblock "#{@now}|#{m.join(-"|")}\n" end @wcount += 1 end lf.write_nonblock "#{@now}|#{last_sv.join(-"|")}|Last message repeated #{last_count} times\n" if cull and last_count > 0 end @queue.each {|service,q| q.clear} end