1
0
Fork 0
mirror of https://github.com/mperham/sidekiq.git synced 2022-11-09 13:52:34 -05:00
mperham--sidekiq/lib/sidekiq/logging.rb
2015-06-10 10:09:48 -07:00

104 lines
3 KiB
Ruby

require 'time'
require 'logger'
module Sidekiq
module Logging
class Pretty < Logger::Formatter
SPACE = " "
# Provide a call() method that returns the formatted message.
def call(severity, time, program_name, message)
"#{time.utc.iso8601(3)} #{::Process.pid} TID-#{Thread.current.object_id.to_s(36)}#{context} #{severity}: #{message}\n"
end
def context
c = Thread.current[:sidekiq_context]
" #{c.join(SPACE)}" if c && c.any?
end
end
class WithoutTimestamp < Pretty
def call(severity, time, program_name, message)
"#{::Process.pid} TID-#{Thread.current.object_id.to_s(36)}#{context} #{severity}: #{message}\n"
end
end
def self.with_context(msg)
Thread.current[:sidekiq_context] ||= []
Thread.current[:sidekiq_context] << msg
yield
ensure
Thread.current[:sidekiq_context].pop
end
def self.initialize_logger(log_target = STDOUT)
oldlogger = defined?(@logger) ? @logger : nil
@logger = Logger.new(log_target)
@logger.level = Logger::INFO
@logger.formatter = ENV['DYNO'] ? WithoutTimestamp.new : Pretty.new
oldlogger.close if oldlogger && !$TESTING # don't want to close testing's STDOUT logging
@logger
end
def self.logger
defined?(@logger) ? @logger : initialize_logger
end
def self.logger=(log)
@logger = (log ? log : Logger.new('/dev/null'))
end
# This reopens ALL logfiles in the process that have been rotated
# using logrotate(8) (without copytruncate) or similar tools.
# A +File+ object is considered for reopening if it is:
# 1) opened with the O_APPEND and O_WRONLY flags
# 2) the current open file handle does not match its original open path
# 3) unbuffered (as far as userspace buffering goes, not O_SYNC)
# Returns the number of files reopened
def self.reopen_logs
to_reopen = []
append_flags = File::WRONLY | File::APPEND
ObjectSpace.each_object(File) do |fp|
begin
if !fp.closed? && fp.stat.file? && fp.sync && (fp.fcntl(Fcntl::F_GETFL) & append_flags) == append_flags
to_reopen << fp
end
rescue IOError, Errno::EBADF
end
end
nr = 0
to_reopen.each do |fp|
orig_st = begin
fp.stat
rescue IOError, Errno::EBADF
next
end
begin
b = File.stat(fp.path)
next if orig_st.ino == b.ino && orig_st.dev == b.dev
rescue Errno::ENOENT
end
begin
File.open(fp.path, 'a') { |tmpfp| fp.reopen(tmpfp) }
fp.sync = true
nr += 1
rescue IOError, Errno::EBADF
# not much we can do...
end
end
nr
rescue RuntimeError => ex
# RuntimeError: ObjectSpace is disabled; each_object will only work with Class, pass -X+O to enable
puts "Unable to reopen logs: #{ex.message}"
end
def logger
Sidekiq::Logging.logger
end
end
end