放っておくといつの間にか容量が膨れ上がっているログファイル。
ふと気づくとディスク容量があっぷあっぷしている、なんてこともあるので、静かな侵略者と勝手に思っています。
rotateの設定をしていないのが悪いんですけどね。
Linuxのlogrotateを使ってもできるのですが、Puma+logrotate+Capistranoだとログ周りがうまく動かないという記事を見たので、RailsのLoggerでrotateする方法にしてみました。
Loggerの設定
config/environments/production.rb
やconfig/environments/development.rb
などの各環境で設定します。
Rails.application.configure do # 日別にrotateされるように設定 logger = ActiveSupport::Logger.new('log/production.log', 'daily') logger.formatter = config.log_formatter if ENV["RAILS_LOG_TO_STDOUT"].present? # 'log/production.log'以外(ex. 標準出力)にログ出力先を追加する場合 stdout_logger = ActiveSupport::Logger.new(STDOUT) stdout_logger.formatter = config.log_formatter multiple_loggers = ActiveSupport::Logger.broadcast(stdout_logger) logger.extend(multiple_loggers) end config.logger = ActiveSupport::TaggedLogging.new(logger) end
日別にしたかったので
ActiveSupport::Logger.new('log/production.log', 'daily')
としていますが、daily
の部分をmonthly
にすると月別、weekly
にすると週別でのrotateになります。
また、
ActiveSupport::Logger.new('log/production.log', 5, 10 * 1024 * 1024)
のようにすると、10Mbずつ、5ファイル分保持します。
ファイルサイズで分割した時は指定したファイル数(ex. 5)を越えると自動で削除してくれますが、期間で分割した時は削除されないので、延々と過去ログが溜まっていきます。
このまま放っておいても、またサーバを圧迫してしまうので、削除バッチを作ってcron実行するようにします。
古いログファイル削除バッチの作成
namespace :log_rotate do desc "rotateされたログファイルのうち、1週間前のファイルを削除する" task :destroy_old_file => :environment do # 対象のファイルを取得 log_files = Dir.glob(Rails.root.join("log/#{Rails.env}.log*")) log_files.each do |file| # 1週間前の日付 last_week_date = Time.zone.today.weeks_ago(1) # ファイルの更新日を取得 file_modified_date = File.mtime(file).in_time_zone.to_date # 更新日が1週間前のファイルは削除 if file_modified_date < last_week_date FileUtils.rm file end end end end
コードの通りですね。
ログ出力対象(log/env.log
)のファイルの
File.mtimeを使って対象ログファイルの最終更新日時を取得します。
取得した最終更新日時と一週間前の日時を比較して、古いものはFileUtils.rmで削除します。
あとはwhenever等でCronに登録しておきます。
puma起動
設定が終わったら、pumaコマンド(or pumactl)で起動します。
$ bundle exec puma -C config/puma.rb -e production -d
rails s
でもpumaは起動しますが、この場合はlogrotateの設定が上手く反映されず、1ファイルに出力され続けるようです。
この辺りはもっとちゃんと調査したいところ…。