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