Guy Rosen
10/5/2006 9:19:00 AM
Hi,
There seems to be a bug (or just unexpected behavior...) in logger.rb's
rotation that causes it to either misbehave or fail the application
when running in a multi-process environment - specifically Rails.
I have Ruby on Rails under FastCGI, with multiple dispatch.fcgi
processes alive. My logger is configured for daily rotation. The
problematic scenario is this:
- Come midnight, the _first_ Rails process that happens to get a
request renames the log file (production.log =>
production.log.yyyymmdd)
- Subsequently, the remaining Rails processes attempt to rename the
file as well, but fail completely because production.log.yyyymmdd
already exists. Logger raises an exception, and users receive "500
Internal Server Error".
- Until all Rails processes are restarted, only the first one will
work and all the rest will continue to fail violently.
I'm including a patch for logger.rb that fixes Logger#shift_log_period
so that it doesn't fail violently if log.yyyymmdd already exists, but
rather just reopens the logfile and keeps on working.
Note there is probably a bug when rotating by size
(Logger#shift_log_age) in the same environment (haven't tested it, but
reading the code seems to indicate it will happen). Although nothing
will fail violently, each Rails process, ignorant of its peers, will
rotate the logs and the end result will be multiple rotations!
- Guy.
-----8<-----
Index: logger.rb
===================================================================
RCS file: /src/ruby/lib/logger.rb,v
retrieving revision 1.5.2.9
diff -r1.5.2.9 logger.rb
568,570d567
< if FileTest.exist?(age_file)
< raise RuntimeError.new("'#{ age_file }' already exists.")
< end
572c569,571
< File.rename("#{@filename}", age_file)
---
> if not FileTest.exist?(age_file)
> File.rename("#{@filename}", age_file)
> end