2008/02/26 (Tue)
■ mongrel_clusterを使う場合のlogger 
production環境では、たいていはログのためにサーバが止まるのを避けるため、cronでrake log:clearしてるから、余り問題にされないのかもしれない。私は客先のイントラネットでRailsを使うことが多いので、ログを保存しておきたいケースが多い。
production環境ではmongrel_clusterやfastcgiを使って複数のRubyプロセスを立ち上げるのが普通だとおもうけど、Rails標準のロガーはそれに関して面倒は見てくれないので、production.logには時間が前後したログが記録されてしまう。
もっと問題なのは、ログローテーションが難しいということだ。
#environment.rb config.logger = Logger.new(config.log_path, 14, 1048576) config.log_level = :debug
とかやったところで、プロセスによってまちまちなログファイルを掴んでしまい、うまくいかない。
Rubyで完結したいならdRubyでやるだろうと思ったけど、すでに誰かが何らかの対策をしていると思ったし、探してみることにした。
最初に発見したのはlogrotateを使う方法だった。id:hiro-ueda:20080112:1200111879
mongrel_clusterは再起動に時間がかかるし、その間にアクセスがきたときに起動中のプロセスがあったら、Apacheにクラスタのメンバからはずされてしまうんではなかろうかとか、いろいろ不安だったので、別のを探すことにした。
次はSyslog路線で探してSyslogLoggerというgemを発見したものの、うまくいかなくて挫折した。
半日かかってようやくぴったりな情報を発見したら、やっぱりdRubyだった。DrbLogger
Rails2.0では以下の修正が必要だった。
#require 'active_support/clean_logger' require 'active_support'
あとはlogserverのdaemon化と自動起動のための修飾を加えて、なんとかできた。
いわどんさんありがとう。
なお、今回はmongrel_clusterでやったのだけど、私はrailsというユーザで実行しているので、logserverもrailsで実行したかった。rootで実行するとローテーションの際にパーミッションが変わってしまうから。
方法としてはinit.dの起動スクリプト中でsudoするくらいしか思いつかなかったんだけど、
"sorry, you must have a tty to run sudo"というエラーになるので、ここを参考にして対策した。
あとlogserverでLogger.newした後にレベルを設定しとかないとデバッグ情報が出力されて遅くなってしまうのでINFO以上にした。
if rails_env == 'production'
@logger[rails_env].level = Logger::INFO
else
@logger[rails_env].level = Logger::DEBUG
end
@logger[rails_env]
ここまで書いてあれなんだけど、INFOはApacheのアクセスログをみればいい内容だから、ほんとはERROR以上で十分かもしれない。それだとログはほとんど増えないからそもそもログローテーションいらないじゃないか!
#environments/production.rb config.log_level = :error