跳转到内容
搜索 Rocky Linux 文档

    浏览当前文档目录

    logrotate 实战:copytruncate 与 -f 的坑(Rocky 9 实测)

    应用自己写的日志不会自动切分,几天就把分区写满。logrotate 是 EL 自带的轮转工具:按时间或大小切分、压缩、保留 N 份。本页用一个自建应用日志跑完整流程。

    Terminal window
    sudo dnf install -y logrotate
    head -20 /etc/logrotate.conf
    ls /etc/logrotate.d/ | head -5
    btmp
    dnf
    wtmp

    /etc/logrotate.d/ 下每个文件是一个配置片段;系统自带的 btmp、wtmp 就在这里。不要改 logrotate.conf 去塞应用配置,放 /etc/logrotate.d/ 更清晰。

    Terminal window
    cat | sudo tee /etc/logrotate.d/myapp <<'EOF'
    /var/log/myapp/*.log {
    daily
    rotate 3
    compress
    missingok
    notifempty
    copytruncate
    }
    EOF

    六个指令的含义:

    指令作用
    daily每天轮转一次(也可 size 50M、weekly)
    rotate 3保留 3 份历史,第 4 份起删除
    compress轮转后 gzip
    missingok日志不存在不报错
    notifempty空文件不轮转
    copytruncate先复制再清空原文件,应用不需要重开文件句柄
    Terminal window
    sudo logrotate -d /etc/logrotate.d/myapp
    rotating pattern: /var/log/myapp/*.log after 1 days (3 rotations)
    empty log files are not rotated, old logs are removed
    considering log /var/log/myapp/app.log
    ...
    log does not need rotating (log has already been rotated)

    -d 是 dry-run,只打印不执行。确认配置没问题后强制跑一次:

    Terminal window
    sudo logrotate -f /etc/logrotate.d/myapp
    ls -l /var/log/myapp/
    -rw-r--r-- 1 root root 0 Oct 18 15:44 app.log
    -rw-r--r-- 1 root root 4023 Oct 18 15:44 app.log.1.gz

    app.log 被清空成 0 字节、内容进了 app.log.1.gz——这就是 copytruncate 的效果。

    EL10 实测:同一配置在 Alma/Rocky 10.2 上

    Section titled “EL10 实测:同一配置在 Alma/Rocky 10.2 上”

    在 PVE 的 AlmaLinux 10.2 与 Rocky Linux 10.2 虚拟机里,用同一份片段实测:

    /var/log/lab/app.log {
    daily
    rotate 3
    copytruncate
    notifempty
    missingok
    su root root
    }

    logrotate -d 预演(状态文件说当天已轮转过):

    log does not need rotating (log has already been rotated)

    logrotate -f 强制轮转后:

    -rw-r--r--. 1 root root 0 ... app.log
    -rw-r--r--. 1 root root 21 ... app.log.1

    再写一行、再强制轮转:

    -rw-r--r--. 1 root root 0 ... app.log
    -rw-r--r--. 1 root root 5 ... app.log.1
    -rw-r--r--. 1 root root 21 ... app.log.2

    copytruncate 的效果很清楚:原文件被截断为 0,旧内容进 .1,再轮转时 .1 顺延为 .2。好处是写入进程不用重开文件;代价是「复制完到截断之间」有极短窗口,可能丢几行。

    • copytruncate 会丢日志:复制与清空之间写入的行会丢;能重开文件句柄的应用优先用 create + postrotate 发信号;
    • 只写 size 不写 daily:size 触发与时间无关,别把两者混用还指望「每天一次」;
    • 权限:/var/log/myapp 属主不是 root 时,copytruncate 后新建文件可能属主不对,必要时加 su myapp myapp。

    前置:Rocky 9,已安装 logrotate。

    Terminal window
    sudo mkdir -p /var/log/lab && sudo sh -c 'head -c 200000 /dev/urandom > /var/log/lab/a.log'
    sudo tee /etc/logrotate.d/lab >/dev/null <<'EOF'
    /var/log/lab/*.log { daily rotate 3 compress copytruncate }
    EOF
    sudo logrotate -f /etc/logrotate.d/lab # 第 1 次
    sudo logrotate -f /etc/logrotate.d/lab # 第 2 次
    ls /var/log/lab/

    检查:

    1. 存在 a.log.1.gz、a.log.2.gz
    2. a.log 大小为 0
    3. 连续强制 5 次后,*.gz 不超过 3 个(rotate 3 生效)