Railsのログのログローテーションはlogrotateを使うことにした

概要

Linux上で稼働しているRuby on RailsアプリケーションのログローテーションにRubyの Logger クラスの機能を使うか、Linuxの logrotate を使うか検討してみました。

環境

  • Ruby 2.2.3
  • Ruby on Rails 4.2.4
  • Puma 3.8.2
  • Amazon Linux

結論

Railsではログローテーションは行わず、 logrotate で行う

理由:

  • Rails(Puma)以外にもログを出力するプロセスは複数存在しており、ログローテーションの管理を1系統にしたい
  • 現在はEC2で稼働させているが、Docker + Amazon ECSの環境に移行することを考えた場合、ログはCloudWatch Logsに直接送信する構成にするので、その時はRailsアプリケーションにログローテーションの設定が入っている必要がない(あると移行したときにハマる可能性がある)

Loggerクラスの利用する場合

Ruby on RailsではデフォルトでRubyの Logger クラスがログ出力に利用されており、その Logger クラスにはログローテーション機能が含まれています。

https://docs.ruby-lang.org/ja/2.2.0/class/Logger.html

例えば以下のように設定することで、ファイルサイズが10MBを超えたらログをローテーションし、古いログファイルを最大30件保持するような動作が実現できます。

config/application.rb
config.logger = Logger.new('log/application.log', 30, 10 * 1024 * 1024)

logrotateを使う場合

/etc/logrotate.d/myapp に以下のような設定を記述する

/etc/logrotate.d/myapp
/var/www/log/*.log {
  size 5M
  rotate 5
  create 0644 rails rails
  copytruncate
  missingok
  notifempty
  nocompress
}
  • Railsのログは /var/www/log に出力されるので、対象は /var/www/log/*.log にする
  • アプリケーションはユーザー rails 、グループ rails で稼働させているので、ローテーション後に作成するログも同様にする
  • ログファイルのパーミッションは 664 なので、ローテーション後に作成するログも同様にする
  • ログのローテーション後にRailsプロセスを再起動しなくていいように、 copytruncate をオンにする

感想

最近はAWSのマネージドサービスを組み合わせてシステムを構築することも多くなってきたので、こういったLinuxの設定周りはあまりやらなくなってきましたが、こういった運用周りの設定は嫌いじゃないです。