delayed_job の logrotate を使ったログローテーションって
どうやるものなんだろう。
- logrotate を使わず TwP/logging の daily ローテーションもありだけど
- logrotate の copytruncate は最終手段
- delayed_job を Capistrano でオプション付きで起動してるので、logrotate の postscript で restart や start する場合は、同じオプションの指定が必要(だと思う)
Unicorn::Util.reopen_logs
を使って USR1 シグナルでログのリオープンできるようにしたら良いのかなと思ったけど、どうも上手くいかない模様。
どうやら、delayed_job の Delayed::Worker.after_fork
にて "a+" モードでリオープンしているため、Unicorn::Util.is_log?
で許容するモードにマッチせずに対象外とされる模様。
(一律で a+ モードで開き直すという挙動は、それはそれで大丈夫なのかな?)
def self.before_fork unless @files_to_reopen @files_to_reopen = [] ObjectSpace.each_object(File) do |file| @files_to_reopen << file unless file.closed? end end backend.before_fork end def self.after_fork # Re-open file handles @files_to_reopen.each do |file| begin file.reopen file.path, 'a+' file.sync = true rescue ::Exception # rubocop:disable HandleExceptions, RescueException end end backend.after_fork end
んー、どうするのがいいんだろうか。
こんな感じはありだろうか?
class Delayed::Worker module TrapUsr1ForReopenLogs def start ObjectSpace.each_object(File) do |file| begin next unless file.path.ends_with?('.log') file.reopen file.path, 'a' file.sync = true rescue ::Exception # rubocop:disable HandleExceptions, RescueException end end trap('USR1') do Thread.new { say 'Reopen logs...' } Unicorn::Util.reopen_logs end super end end prepend Delayed::Worker::TrapUsr1ForReopenLogs end