railsマルチプロセスとログとlogrotate

先日パーティにお招きいただいた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
カテゴリ:

トラックバック(0)

このブログ記事を参照しているブログ一覧: railsマルチプロセスとログとlogrotate

このブログ記事に対するトラックバックURL: http://mogya.com/mt/mt-tb.cgi/1639

コメント(3)

k_matsuda :

参考になりました!ありがとうございます。
mongrel_cluster利用中、
logrotateの設定ファイル内で、たとえば以下のようにしたら、mongrel_clusterプロセスの再起動なしでログローテートできました。

{
daily
missingok
nocreate
copytruncate
rotate 7
}

copytruncateだと厳密には copyとtruncate処理の間のログ記述が欠落することがあり得ますが、この方法が一番、現状望む動きに近いようです!

mogya :

あー。その手があったか!
でも、お役に立てたみたいでよかったです。

mogya :

しまった。

logrotateの設定ファイル
/var/www/example/api/log/* {
だと、ローテートしたログをさらにローテートするからエラいことになりますね。

/var/www/example/api/log/thin_example.300?.log {

とかのほうがいいかもしれない。

コメントする


画像の中に見える文字を入力してください。

このブログ記事について

このページは、 もぎゃが 2013年8月 6日 22:08に書いたブログ記事です。

ひとつ前のブログ記事は「 Evernote Devcup Workshop "世界に伝わる製品紹介ビデオの作り方" 」です。

次のブログ記事は「 Titanium SDKとiOS/Android SDKの関係 」です。

最近のコンテンツは インデックスページ で見られます。過去に書かれたものは アーカイブのページ で見られます。

Powered by
Movable Type