How to write/flush the Rails log when the process dies
The Rails logger has the auto_flushing method. It delays writing to the log until the number of entries is the same as whatever this has been set to. This has been around since Rails 2, and is meant to speed things up by stopping constant writes to disk under load.
This is fine most of the time, but we have short running jobs that never hang around long enough to get past the flush - any errors disappear.
Is there any way to guarantee that the l开发者_JS百科og is flushed when the process dies?
EDIT
In the end I did this (but it's very verbose)
af = Rails.logger.auto_flushing
Rails.logger.auto_flushing = true
Rails.logger.error "my message"
Rails.logger.auto_flushing = af
This forces the message out but puts auto flushing back afterwards
For the really complete solution put this in an initializer:
class << Rails.logger
def flush_error( message )
Rails.logger.error message
Rails.logger.flush
end
end
Then just use the method as and when ...
If, for some reason, rails does not run the at_exit
hook (flying monkeys absconding with your sanity), and you really really want those log entries, do as some people said and run this after the important logging statements:
Rails.logger.flush
or
logger.flush
Voila.
Can't you set that to "1" and it will flush after every message?
config.logger.auto_flushing = 1
[EDIT: as madlep points out in a comment above - this is going to be a total resource hog and is likely not the best way of logging in general. But if you're bug-hunting - it's a way of finding it. That and switching your log to "debug level"]
You can also switch it off with:
config.logger.auto_flushing = false
But that just means you have to manually flush...
alternatively, you can specifically flush the log at the end of each of your scripts with:
Rails.logger.flush
Try something like
Signal.trap("EXIT") { Rails.logger.flush }
When you're initialising logging to register a signal handler with the process. When it dies, it'll execute whatever is in the block before terminating
See the docs for more info
(note - totally untested code with rails logger, but works in the general case of just doing something when the process dies.
As of Rails 3.1 this is no longer necessary: The code in Railties application/bootstrap.rb now includes at at_exit to flush the log.
Enjoy.
精彩评论