What is the best way to rotate logs for rails application

I also use logrotate (you'll have to install via apt-get). Create a new logrotate file in your /etc/logrotate.d/ directory. Here's an example of one of mine:

# for the rails logs
/home/apps/*/shared/log/*log {
  daily
  rotate 14
  notifempty
  missingok
  compress
  sharedscripts
  postrotate
    /usr/bin/touch /home/apps/application1/current/tmp/restart.txt
    /usr/bin/touch /home/apps/application2/current/tmp/restart.txt
  endscript
}
# for the apache logs
/home/apps/logs/*log {
  daily
  rotate 14
  notifempty
  missingok
  compress
  sharedscripts
  postrotate
    /etc/init.d/apache2 restart
  endscript
}

This rotates both rails production.log logs and the apache access/error logs (I run my apps under passenger).


This is meta-programming and whether it should be on ServerFault or SO is debatable.

logrotate, a standard package for a number of operating systems, and you can apt-get install logrotate to get it if you do not already. It can be coerced into rotating whatever logs you want, using whatever schedule you want, and with differing policies a la "gzip 7 days then rm" per-file.

Investigate /etc/logrotate.d.


I'd just use the built-in rotation offered by the rails logger:

# in config/application.rb
config.logger = Logger.new(Rails.root.join('log', "#{Rails.env}.log"), 3, 10.megabytes)

This will rotate the log files once they reach 10MB and save the 3 most recent rotated logs.


We recently had to deal with this, and realized that logrotate is not the best solution. Using it requires that you restart the rails app every time logs are rotated, which seems like an unnecessary performance hit.

A better solution is to override the default rails logger in your application's configuration file(s).

# in config/environments/development.rb
config.logger = Logger.new("#{Rails.env}.log", "daily")

and, then use a script that cleans up files older than n days. You could use logrotate for this part if you like. We use a rake task like,

desc "Cleanup application logs older than 30 days"
task :logs => :environment do
  require 'fileutils'
  Dir.glob("#{Rails.root}/log/*.log.*").
    select{|f| File.mtime(f) < (Time.now - (60*60*24*30)) }. # older than 30 days
    each { |f| 
      puts "Removing #{f}"
      FileUtils.rm f 
    }
end