Carpe Diem

備忘録。https://github.com/jun06t

Nginxのログをlogrotateでローテーション

概要

アクセスログをそのままにすると肥大化するので、ローテーションして分割する必要があります。

環境

  • Ubuntu 14.04
  • Nginx 1.4.6
  • logrotate 3.8.7

Nginxの用意

$ sudo aptitude install nginx

インストール後、自動でlogrotateのnginx用設定が/etc/logrotate.d/に入ります。
logrotateは/etc/logrotate.d/の設定をincludeしてくれるので、これを設定します。

設定の詳細

以下にデフォルトの設定を書きます。

/var/log/nginx/*.log {
        weekly
        missingok
        rotate 52
        compress
        delaycompress
        notifempty
        create 0640 www-data adm
        sharedscripts
        prerotate
                if [ -d /etc/logrotate.d/httpd-prerotate ]; then \
                        run-parts /etc/logrotate.d/httpd-prerotate; \
                fi \
        endscript
        postrotate
                [ -s /run/nginx.pid ] && kill -USR1 `cat /run/nginx.pid`
        endscript
}

これをベースによく使う設定を以下に並べます。

プロパティ 役割
weekly ログローテーションを週毎に行う
missingok ログファイルが見つからなくてもエラーにしない。
rotate n n世代までログをローテート。それ以上は削除
dateext ローテーションされたログファイルのサフィックスを日付形式にする
compress ローテートしてログを圧縮
delaycompress 1つ前のファイルはまだ圧縮しない。それ以外を圧縮
notifempty ログファイルが空ならローテーションしない
create ローテーション後、新たにログファイルを作成する。
権限、ユーザ、グループを指定。
sharedscripts スクリプト宣言文。
以降に記述された処理をワイルドカードの指定に関わらず、1度だけ実行する
prerotate ログローテーション実施前に実行される部分
postrotate ログローテーション実施後に実行される部分

設定例

注意点として、ログを単純にローテートしても、Nginxのログの書き込み先は変わりません
つまりaccess.log.1とリネームして、新しくaccess.logを作っても、ログはaccess.log.1に書き込まれ続けます。
なので書き込み先を新しいaccess.logにする処理をpostrotateに設定するのが普通です。

ただデフォルトはスクリプトの部分が古いようで、わざわざpidを指定してkillしてますがNginxの場合もっと簡単に書けます。

/var/log/nginx/*.log {
        daily
        missingok
        rotate 52
        dateext
        compress
        notifempty
        create 0644 www-data adm
        sharedscripts
        postrotate
               /etc/init.d/nginx rotate >/dev/null 2>&1
        endscript
}

このように/etc/init.d/nginx rotateを実行してあげると、作りなおしたaccess.logerror.logに向きなおしてくれます。
>/dev/null 2>&1はよくある書き方で、コンソールに出る結果やエラーを表示しないためのやつです。

動作検証

以下のオプションがあります。

オプション 役割
-f 強制実行
-v verbose
-d dry run

まずはdry runで問題なく動くか確認し、

logrotate -df /etc/logrotate.d/nginx

大丈夫であれば実行してみてください。

logrotate -fv /etc/logrotate.d/nginx

※dry runではログのリネームや圧縮部分で「ファイルがない」とエラーが出る時がありますが、普通に動かすときはエラーは出ないです。

ソース