先日パーティにお招きいただいたM社の方から、mongrel_clusterで複数プロセス立ち上げている時、logroateすると、ひとつのプロセスを残して、ログファイルを見失って正常に動作できなくなる、というご相談をいただきました。
美味しいお酒をいっぱいのませていただいたのでちょうど僕も使うアテがあるので、僕がよく使っているthinのケースを書いてみます。たぶんmongrelでもそんなに変わらないんじゃないかな〜。
マルチプロセスで起動する
・セッションをファイルじゃなくてDBに保存するようにする。やり方はググれば出てくるので省略。
・ログはproduction.logじゃなくてSTDERRに出力して、thinの方でファイルに書いてもらう。具体的には、config/environments/production.rbとかで
config.logger = Logger.new(STDOUT)
という具合に。
・thinの設定
$ sudo ln -s /var/www/example/api/config/thin.conf /etc/thin/example.yaml $ sudo emacs /var/www/example/api/config/thin.conf --- chdir: /var/www/example/api environment: production servers: 3 address: 0.0.0.0 port: 3000 timeout: 30 log: log/thin_example.log pid: tmp/pids/thin_example.pid max_conns: 1024 max_persistent_conns: 100 require: [] wait: 30 daemonize: true
これでlocalhost:3000,3001,3002と3プロセスが立ち上がります。
ログは、
$ ls -la api/log/ -rw-r--r-- 1 root root 3081 Aug 6 20:42 thin_example.3000.log -rw-r--r-- 1 root root 1292 Aug 6 20:42 thin_example.3001.log -rw-r--r-- 1 root root 15632 Aug 6 20:42 thin_example.3002.log
という具合にプロセスごとに別々に出力されます。
Rails3.2からログの行が他プロセスのものと混ざるようになった件について – 昼メシ物語 などを見ていると、一つのファイルにかいた時ログが混じるという話が出ているのですけど、そもそも複数プロセスから一個のファイルに書き込む時点で怖くて仕方ないので、
最初から分けてあったほうがいっそスッキリするんじゃないかな〜。
ログが複数にわかれていても、
tail -f log/thin_example.*.log
とすれば一つの窓で監視することができます。
ロードバランサー(apache)の設定
こんなかんじで
$ sudo ln -s /var/www/example/api/config/httpd.conf /etc/httpd/conf.d/example.conf $ emacs /var/www/example/api/config/httpd.conf <VirtualHost *:80> ServerName example.com ServerAlias www.example.com DocumentRoot "/var/www/example/html/" ServerAdmin mogya+example@mogya.com ErrorLog "/var/www/example/log/error_log" TransferLog "/var/www/example/log/access_log" LogFormat "%h %l %u %t \"%r\" %>s %b \"%{Referer}i\" \"%{User-Agent}i\"" combined CustomLog /var/www/example/log/custom_log combined ProxyPass /api/v2 balancer://example ProxyPassReverse /api/v2 balancer://example </VirtualHost> <Proxy balancer://example> BalancerMember http://localhost:3000 BalancerMember http://localhost:3001 BalancerMember http://localhost:3002 </Proxy>
いまどきapacheなんて・・・という方はherokuでもAWSでもお好きなフロントエンドでどうぞ。
logrotate
sudo ln -s /var/www/example/api/config/logrotate.conf /etc/logrotate.d/example emacs /var/www/example/api/config/logrotate.conf /var/www/example/api/log/* { daily missingok rotate 1000 notifempty copytruncate create 0666 root root sharedscripts postrotate /etc/init.d/thin restart > /dev/null /etc/init.d/httpd restart > /dev/null endscript dateext }
thinだけrestartだと直後の挙動が怪しかったので、httpdもrestartするようにしてあげたほうがいいみたいです。
$ sudo logrotate -dv /etc/logrotate.d/example
で文法チェック。
$ sudo logrotate -f /etc/logrotate.d/example
で動作確認を行うことができます。
環境
$ rails -v Rails 3.2.13 $ thin -v thin 1.5.1 codename Straight Razor $ httpd -v Server version: Apache/2.2.24 (Unix) Server built: May 20 2013 21:12:45
参考になりました!ありがとうございます。
mongrel_cluster利用中、
logrotateの設定ファイル内で、たとえば以下のようにしたら、mongrel_clusterプロセスの再起動なしでログローテートできました。
{
daily
missingok
nocreate
copytruncate
rotate 7
}
copytruncateだと厳密には copyとtruncate処理の間のログ記述が欠落することがあり得ますが、この方法が一番、現状望む動きに近いようです!
あー。その手があったか!
でも、お役に立てたみたいでよかったです。
しまった。
logrotateの設定ファイル
/var/www/example/api/log/* {
だと、ローテートしたログをさらにローテートするからエラいことになりますね。
/var/www/example/api/log/thin_example.300?.log {
とかのほうがいいかもしれない。