AR ホームベーカリー

オイラのアウトプット用ホームベーカリー!

delayed_job の動作ログを Rails ログファイル以外に出力する

production.log に大量の UPDATE クエリが記録されてログファイル汚染で「ウッ!」となるやつを回避する。

どうする

以下は production 想定のログファイルだけど、他の実ファイルと重複しなければなんでもよい。 このへんを参考にしました。

github.com

config/environments/production.rb

Rails.application.configure do の中のどっかに書く。

if caller_locations.map(&:path).any? { |c| c =~ %r{bin\/delayed_job} }
  ActiveRecord::Base.logger =
    Logger.new(Rails.root.join('log', 'delayed_job.production.log'))
end

ログ出力を抑制してしまう

以下のようにすると、そも出力しないようにできる。 しかし本来出るはずのものを抑制していいのか? という疑問があったので、こちらのチャートは採用を見送りました。

config/initializers/delayed_job.rb

unless Rails.env.development?
  module Delayed
    module Backend
      module ActiveRecord
        class Job
          class << self
            alias_method :reserve_original, :reserve
            def reserve(worker, max_run_time = Worker.max_run_time)
              previous_level = ::ActiveRecord::Base.logger.level
              ::ActiveRecord::Base.logger.level = Logger::WARN if previous_level < Logger::WARN
              value = reserve_original(worker, max_run_time)
              ::ActiveRecord::Base.logger.level = previous_level
              value
            end
          end
        end
      end
    end
  end
end

注意

delayed_job を出力するログファイルを作る場合、こいつのログローテートと、ローテート時ファイルポインタ開放してやらないといけない。 僕は現状、 logrotate で以下のように truncate で運用するようにしています。 ちゃんとやるなら、 deamon 化を systemctl に任せたりとかしないといけない気がしてる。

/etc/logrotate.d/rails

/var/www/PROJECT/current/log/*.log {
  su ec2-user ec2-user
  #create 664 ec2-user ec2-user
  daily
  missingok
  rotate 90
  compress
  delaycompress
  dateext
  notifempty
  copytruncate
}