前書き
私の環境では、 fluentd で /var/log/nginx/access.log
や /var/log/nginx/error.log
を tail し収集するようにしています。
しかし、 Ubuntu 14.04 に PPA を追加し nginx をインストールした際に tail 出来なくなってしまいました。
※ Ubuntu 14.04 に PPA を追加せず nginx をインストールした際は tail 出来ていました。
ログファイルを確認したところ、 /var/log/nginx/access.log
に出力されるべきログが /var/log/nginx/access.log.1
に、そして /var/log/nginx/error.log
に出力されるべきログが /var/log/nginx/error.log.1
になってました。
調査を行ったところ、 PPA を追加し nginx をインストールした際の logrotate のデフォルト設定が間違っているようでした。
環境
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=14.04
DISTRIB_CODENAME=trusty
DISTRIB_DESCRIPTION="Ubuntu 14.04.5 LTS"
nginx のバージョン
ppa:nginx/stable
を追加し nginx をインストールしました。
$ nginx -v
nginx version: nginx/1.10.1
logrotate のデフォルト設定がどう間違っているのか
デフォルト設定
nginx インストールした際の logrotate デフォルト設定は以下の通りです。
/var/log/nginx/*.log {
daily
missingok
rotate 14
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
invoke-rc.d nginx rotate >/dev/null 2>&1
endscript
}
デフォルト設定の解説
プロパティ | 役割 |
---|---|
daily |
ログローテーションを日毎に行う。 |
missingok |
ログファイルが見つからなくてもエラーにしない。 |
rotate n |
n 世代までログをローテート。それ以上は削除。 |
compress |
ローテートしてログを圧縮。 |
delaycompress |
1つ前のファイルはまだ圧縮しない。それ以外を圧縮。 |
notifempty |
ログファイルが空ならローテーションしない。 |
create |
ローテーション後、新たにログファイルを作成する。権限、ユーザ、グループを指定。 |
sharedscripts |
スクリプト宣言文。以降に記述された処理をワイルドカードの指定に関わらず、1度だけ実行する。 |
postrotate |
ログローテーション実施後に実行される部分。 |
どこが間違っているのか
デフォルト設定の postrotate
に設定されているコマンドが間違っています。
postrotate
invoke-rc.d nginx rotate >/dev/null 2>&1
endscript
ログをローテートしても、 nginx のログ出力先のファイルは変更されません。
access.log
をロテートし、access.log.1
とリネームされたところでログの出力先は access.log.1
のままです。
そのため、 postrotate
で新規の access.log
に出力先を変更するよう設定する必要があります。
しかし、上記で設定されているコマンドは実行時以下のようにエラーが発生してしまいます。
$ invoke-rc.d nginx rotate
initctl: invalid command: rotate
Try `initctl --help' for more information.
invoke-rc.d: initscript nginx, action "rotate" failed.
$ initctl --help
Usage: initctl [OPTION]... COMMAND [OPTION]... [ARG]...
Options:
--session use existing D-Bus session bus to connect to init daemon (for testing)
--system use D-Bus system bus to connect to init daemon
--dest=NAME destination well-known name on D-Bus bus
--user run in user mode (as used for user sessions)
-q, --quiet reduce output to errors only
-v, --verbose increase output to include informational messages
--help display this help and exit
--version output version information and exit
For a list of commands, try `initctl help'.
Report bugs to <upstart-devel@lists.ubuntu.com>
解決策は、以下のコマンドを実行するように設定することです。
$ sudo /etc/init.d/nginx rotate
* Re-opening nginx log files nginx
...done.
or
$ sudo service nginx rotate
* Re-opening nginx log files nginx
...done.
正しい設定
それでは上記で説明したコマンドを実行するように設定しましょう。
/var/log/nginx/*.log {
daily
missingok
rotate 14
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
- invoke-rc.d nginx rotate >/dev/null 2>&1
+ /etc/init.d/nginx rotate >/dev/null 2>&1
endscript
}
設定後、 logrotate
コマンドを使いデバッグします。
-d
--debug
オプションでデバッグモードに入ります。
$ sudo logrotate -d /etc/logrotate.d/nginx
reading config file /etc/logrotate.d/nginx
Handling 1 logs
rotating pattern: /var/log/nginx/*.log after 1 days (14 rotations)
empty log files are not rotated, old logs are removed
considering log /var/log/nginx/access.log
log needs rotating
considering log /var/log/nginx/error.log
log does not need rotating
rotating log /var/log/nginx/access.log, log->rotateCount is 14
付録
せっかくなので PPA リポジトリを追加せず Ubuntu 14.04 に nginx をインストールした際の logrotate のデフォルト設定を見てみましょう。
nginx のバージョン
$ nginx -v
nginx version: nginx/1.4.6 (Ubuntu)
デフォルト設定
/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
}
postrotate
のコマンドを見た所、 nginx の pid を kill している。
だから動いたのか!と納得しました。