13
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

More than 5 years have passed since last update.

Ubuntu に nginx をインストールした際の logrotate のデフォルト設定が間違ってる!

Last updated at Posted at 2016-12-01

前書き

私の環境では、 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 のデフォルト設定が間違っているようでした。

環境

/etc/lsb-release
DISTRIB_ID=Ubuntu
DISTRIB_RELEASE=14.04
DISTRIB_CODENAME=trusty
DISTRIB_DESCRIPTION="Ubuntu 14.04.5 LTS"

nginx のバージョン

ppa:nginx/stable を追加し nginx をインストールしました。

nginx
$ nginx -v
nginx version: nginx/1.10.1

logrotate のデフォルト設定がどう間違っているのか

デフォルト設定

nginx インストールした際の logrotate デフォルト設定は以下の通りです。

/etc/logrotate.d/nginx
/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.

正しい設定

それでは上記で説明したコマンドを実行するように設定しましょう。

/etc/logrotate.d/nginx
  /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
$ 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 している。
だから動いたのか!と納得しました。

参考文献

13
9
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
13
9

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?