第4回 uWSGIのログをローテート
第3回では、uWSGIをsystemdのサービスとして登録してOS起動時にuWSGIも自動的に起動するようにしました。
第4回ではuWSGIのログをローテートし、ログファイルが無限に増えてディスク容量を圧迫しないようにします。また、せっかくなので一般的にサービスと同じようにログファイルの保存場所を /var/log/demo
配下に移動します。
uwsgi.iniの編集
uwsgi.iniの [uwsgi]
セクションにパラメータを追加・編集する。
daemonize = /var/log/demo/demo.log
logfile-chown
disable-logging = false
log-4xx = false
log-5xx = true
touch-logreopen = /var/log/demo/logreopen
第2回と重複するパラメータも記載するが、ログ関連の設定内容を以下に列挙する。
実際に変更・追加したのは、ログファイルのパスを /var/log/demo
配下に変更するための daemonize
と、ログローテート関連の logfile-chown
および touch-logreopen
となる。
パラメータ | 意味 |
---|---|
daemonize | uWSGIのログを記録するファイルのパス。(編集) |
logfile-chown | 作成するログファイルの所有権を、別途uid、gidパラメータで指定したuWSGIワーカープロセスと同じオーナーおよびグループに変更する。 |
disable-logging | リクエスト毎にログ記録しない。 |
log-4xx | HTTP STATUS 4xxのエラーをログに記録する。 |
log-5xx | HTTP STATUS 5xxのエラーをログに記録する。 |
touch-logreopen | 指定したパスの更新日時が変わったらログを再度オープンする。 |
touch-logreopen
後述するlogrotateが行うローテート機能のデフォルト動作は、現行のログファイルをリネームして新たなログファイルを作成する。しかしuWSGIは現行のファイルをオープンしているため、新たなログファイルを作成してもリネームされたファイルに書き込みを続けてしまう。
touch-logreopenは、uWSGIにログファイルを再オープンするタイミングを伝える。このパラメータに指定したファイルの更新日時が変わった時、uWSGIはログを再オープンし、新しいログファイルに書き込みを始める。
logfile-chown
uWSGIマスタープロセスをrootユーザで起動すると、ログファイルのオーナーはrootになる。しかしながら、touch-logreopenでログを再オープンした後はuWSGIワーカープロセスのユーザで書き込もうとする (uWSGI 2.0.19にて確認。本当に仕様?) ため、ログファイルのオーナーをワーカープロセスに合わせる。
ログファイル配置場所の作成
ログファイルを /var/log/demo
配下にするため、uWSGI起動スクリプト start.sh
に以下を追加する。
LOG_DIR=/var/log/demo
mkdir -p $LOG_DIR
uWSGIの再起動
uWSGIを再起動し、ログファイルが作成されていれば正しく設定されたことがわかる。
$ sudo systemctl restart demo
$ ls -la /var/log/demo
total 8
drwxr-xr-x 2 root root 22 Aug 15 18:45 .
drwxr-xr-x. 10 root root 4096 Aug 15 15:27 ..
-rw-r----- 1 hiyoko www-users 2056 Aug 15 18:45 demo.log
logrotateのインストール
ほとんどの場合はlogrotateコマンドがデフォルトでインストールされているが、CentOS 8をMinimalインストールした場合は入っていないため、インストールする。
$ sudo dnf install logrotate
logrotateの設定
logrotateはcronで定期実行され、/etc/logrotate.d/
配下の設定ファイルに従ってログファイルをローテートする。/etc/logrotate.d/
配下に demo
というファイルを以下の内容で作成する。
/var/log/demo/*.log {
dateext
daily
rotate 7
notifempty
missingok
compress
delaycompress
create 640 hiyoko www-users
sharedscripts
postrotate
touch /var/log/demo/logreopen
endscript
}
logrotateの設定ファイルに指定した内容は以下のとおり。
パラメータ | 内容 |
---|---|
dateext | ローテートしたファイルの拡張子を日付 (.YYYYMMDD) にする。デフォルトは通し番号。 |
daily | 日次ローテートする。 |
rotate | 指定数のローテートファイルを保持し、それ以上古いものは削除する。 |
notifempty | ファイルが空の場合はローテートしない。 |
missingok | ファイルが無くてもエラー表示を行わない。 |
compress | ローテートしたファイルを圧縮する。 |
delaycompress | ローテートした1世代目のファイルは圧縮しない。(ローテートの瞬間にまだログ書き込みしている可能性があるため) |
create | 指定したパーミッション、ユーザ、グループで新規ログファイルを作成する。 |
sharedscripts | ログファイルに対し、postrotateまたはprerotateで指定したスクリプトを実行する。 |
postrotate | ローテート後に実行するコマンド。ここでは touch コマンドで logreopen ファイルを作成し、uWSGIにログ再オープンのタイミングを伝えている。 |
endscript | コマンドスクリプト指定の終了。 |
logrotateの仮実行
作成した定義ファイルにより正しく動作できるか、logrotateを仮実行して確かめる。-d
はデバッグモード実行で、ログファイルは実際にはローテートされない。-f
は強制指定で、定義ファイル内で日次ローテートを指定しても強制的にローテートを行う。
$ sudo logrotate -d -f /etc/logrotate.d/demo
WARNING: logrotate in debug mode does nothing except printing debug messages! Consider using verbose mode (-v) instead if this is not what you want.
reading config file /etc/logrotate.d/demo
Reading state from file: /var/lib/logrotate/logrotate.status
Allocating hash table for state file, size 64 entries
Creating new state
Handling 1 logs
rotating pattern: /var/log/demo/*.log forced from command line (7 rotations)
empty log files are not rotated, old logs are removed
considering log /var/log/demo/demo.log
Now: 2020-08-15 18:47
Last rotated at 2020-08-15 16:10
log needs rotating
rotating log /var/log/demo/demo.log, log->rotateCount is 7
dateext suffix '-20200815'
glob pattern '-[0-9][0-9][0-9][0-9][0-9][0-9][0-9][0-9]'
glob finding logs to compress failed
glob finding old rotated logs failed
renaming /var/log/demo/demo.log to /var/log/demo/demo.log-20200815
creating new /var/log/demo/demo.log mode = 0640 uid = 1101 gid = 1100
running postrotate script
running script with arg /var/log/demo/*.log : "
touch /var/log/demo/logreopen
"
これで、logrotateも正しく実行されることが確認できた。あとはcronにより実行され、ログファイルが日次ローテートするのを待つ。
コメント