在使用logrotate对nginx日志进行每小时分割并压缩为zstd格式时,
我留下了这个备忘录。
概述
如果直接在/etc/logrotate.conf或/etc/logrotate.d/中进行设置,基本上
会通过/etc/cron.daily/logrotate的每日CRON进行执行。
这次我希望进行每小时的日志轮转,因此准备了单独的logrotate设置,并利用
systemd的定时器功能来执行。
安装zstd
# 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
- 定义服务
# 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_
- 定义定时器
# 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
- 启用定时器
# systemctl enable logrotate-nginx.timer
- 启动定时器
# systemctl start logrotate-nginx.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月补充
如果是每小时分割日志的话,通常并不会太在意,但如果是按分钟分割日志,可能会因为定时器的精度而造成
时间错位,从而包含预期之外的时间。
因此,如果希望精确在0秒执行,可以按以下方式进行配置。
[Unit]
Description=logrotate-nginx
[Timer]
OnCalendar=*:*:00
AccuracySec=1s
[Install]
WantedBy=timers.target
通过指定AccuracySec,可以实现秒级执行。