FreeBSDで構築されたWebサーバのログを別サーバに一定期間保管する必要があるため、logrotateを使用してローテートの後に別サーバへ転送していました。
newsyslogで同じこと出来ないのかなとnewsyslog.conf(5)を見てみるとflagsにRをつける事で、
ローテート後にコマンドを実行できそうなので、newsyslogで同じことができるかどうかやってみました。
FreeBSDのバージョンは12.1です。
# logfilename [owner:group] mode count size when flags [/path_to_pid_cmd_file] [sig_num]
/var/log/nginx/*.log root:wheel 644 7 * $D05 BGXR /usr/local/etc/nginx_rotate.sh 30
nginxのnewsyslogの設定に関してはこちらも参照
[/path_to_pid_cmd_file]の部分はRフラグによって実行コマンドになったので、シグナル発行をスクリプトの最初に入れています。
シグナルを投げたらローテーションされたファイルを転送するだけです。
#!/bin/sh
SIGNUM=$1
kill -$SIGNUM `/bin/cat /var/run/nginx.pid`
YMD=`date '+%Y%m%d'`
scp /var/log/nginx/access.log.0.xz server:"/savelog/access.log.${YMD}.xz"
scp /var/log/nginx/error.log.0.xz server:"/savelog/error.log.${YMD}.xz"
これでlogrotateが無くてもログのローテーション&ファイル転送ができました。
と思って後日確認してみたらファイルは転送されていませんでした。原因はnewsyslogの処理が
- ファイル名変更
- シグナル送信(コマンド実行)
- 圧縮
の順番で行われているためでした。考えてみたら圧縮後にシグナル送っても遅いですよね。
圧縮前のファイルを転送するようにすれば終わりですが、logrotateの時のように圧縮後の転送でないとlogrotateの代わりにはなれないと思い結局下記のようにしてみました。
# logfilename [owner:group] mode count size when flags [/path_to_pid_cmd_file] [sig_num]
/var/log/nginx/*.log root:wheel 644 7 * $D05 BGR /usr/local/etc/nginx_rotate.sh 30
logroateに圧縮させるのもやめてスクリプトで圧縮させてから転送するようにしました。
#!/bin/sh
SIGNUM=$1
kill -$SIGNUM `/bin/cat /var/run/nginx.pid`
/usr/bin/xz /var/log/nginx/access.log.0
/usr/bin/xz /var/log/nginx/error.log.0
YMD=`date '+%Y%m%d'`
scp /var/log/nginx/access.log.0.xz server:"/savelog/access.log.${YMD}.xz"
scp /var/log/nginx/error.log.0.xz server:"/savelog/error.log.${YMD}.xz"
これで今度こそlogrotateを使わずにログのローテーション&ファイル転送ができました。