使用logrotate每小时分割日志并进行zstd压缩
服务器
Lastmod: 2023-11-30
Published: 2021-03-29

在使用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,可以实现秒级执行。