logrotateでzstdで圧縮しつつ、1時間ごとにnginxのログを分割したかった時の
メモを残しておきます。
概要
素直に、/etc/logrotate.conf
や /etc/logrotate.d/
に設定を入れると基本的に/etc/cron.daily/logrotate
のデイリーCRONで実行されてしまう。
今回は1時間ごとのログローテートをしたいので、logroateの設定を別に用意して、
systemdのtimer機能を使い実行するようにしてみました。
ztsdを使えるようにする
# apt install zstd
logrotate
/etc/logrotate-nginx.conf
を作ることにします。
今回はzstdですが、bzip2なども設定同じようにすれば変更することが可能です。
# cat << _EOF_ > /etc/logrotate-nginx.conf
compresscmd /usr/bin/zstd # zstdのパスを指定
compressoptions -12 # zstdに渡すオプション。個人的には-12がいい感じだった
compressext .zst # 付与する拡張子
/var/log/nginx/*.log {
missingok
rotate 720 # 24時間 * 30日
dateext
dateformat -%Y%m%d%H
compress
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
}
_EOF_
systemd
- serviceを定義
# cat << _EOF_ > /etc/systemd/system/logrotate-nginx.service
[Unit]
Description=logrotate-nginx
After=network.target
[Service]
Type=simple
ExecStart=/usr/sbin/logrotate -f /etc/logrotate-nginx.conf
PrivateTmp=true
[Install]
WantedBy=multi-user.target
_EOF_
- timerを定義
# cat << _EOF_ > /etc/systemd/system/logrotate-nginx.timer
[Unit]
Description=logrotate-nginx
[Timer]
OnCalendar=*:00:00
[Install]
WantedBy=timers.target
_EOF_
- systemdの設定を読み込み
# systemctl daemon-reload
- timerをenableにする
# systemctl enable logrotate-nginx.timer
- timerの開始
# systemctl start logrotate-nginx.timer
- timerのステータスを確認
# systemctl status logrotate-nginx.timer
● logrotate-nginx.timer - logrotate-nginx
Loaded: loaded (/etc/systemd/system/logrotate-nginx.timer; enabled; vendor preset: enabled)
Active: active (running) since Mon 2021-03-29 20:00:00 JST; 5h 58min ago
Trigger: n/a
Triggers: ● logrotate-nginx.service
Mar 29 19:00:00 log systemd[1]: Started logrotate-nginx.
Activeで次回実行される時間、ログで過去に実行された時間を知ることができます🎉
2023年11月追記
1時間ごとであればあまり気になりませんが、1分単位でログを分割するとtimerの精度で、 ズレが生じてしまい、想定した時間以外が含まれてしまいます。
そのため、きっちり0秒で実行してほしい場合は、以下のように設定するとよいです。
[Unit]
Description=logrotate-nginx
[Timer]
OnCalendar=*:*:00
AccuracySec=1s
[Install]
WantedBy=timers.target
AccuracySecを指定することで、1秒単位で実行することができます。