跳转至

logrotate 日志轮转

logrotate 是 Linux 系统自带的日志管理工具,自动压缩、删除旧日志文件,防止日志把磁盘撑爆。白话说就是"给日志文件设保质期,过期自动清理"。

核心知识点

概念说明
logrotate日志轮转程序,定期处理日志文件
轮转(rotate)把当前日志重命名并创建新日志文件
压缩(compress)把旧日志压缩成 .gz 节省空间
/etc/logrotate.conf全局配置文件
/etc/logrotate.d/各个应用的独立配置目录
postrotate轮转后执行的脚本(如通知服务重新打开日志)

安装配置

# 大多数 Linux 发行版自带 logrotate
which logrotate  # 确认是否已安装

# Ubuntu/Debian 安装
sudo apt install logrotate  # 安装 logrotate

# CentOS/RHEL 安装
sudo yum install logrotate  # 安装 logrotate

# 查看版本
logrotate --version  # 确认版本号

# logrotate 由 cron 每天自动执行,配置在:
cat /etc/cron.daily/logrotate  # 查看 cron 是怎么调用 logrotate 的

基本使用

全局配置

# 查看全局配置文件
cat /etc/logrotate.conf  # 默认全局设置
# /etc/logrotate.conf 典型内容
weekly              # 默认每周轮转一次
rotate 4            # 保留 4 个旧日志文件
create              # 轮转后创建新的空日志文件
dateext             # 旧日志文件名加日期后缀
compress            # 压缩旧日志文件(gzip)
include /etc/logrotate.d  # 加载各应用的独立配置

编写应用配置

# 为自己的应用创建配置文件
sudo vim /etc/logrotate.d/myapp  # 在配置目录下新建文件
# /etc/logrotate.d/myapp
/var/log/myapp/*.log {    # 要管理的日志文件路径(支持通配符)
    daily                  # 每天轮转
    rotate 30              # 保留 30 个旧日志(30 天)
    compress               # 压缩旧日志为 .gz
    delaycompress          # 最近一次的旧日志不压缩(方便查看)
    missingok              # 日志文件不存在也不报错
    notifempty             # 空日志文件不轮转
    create 0644 myapp myapp  # 创建新日志文件,权限 0644,属主 myapp

    postrotate                           # 轮转后执行的命令
        systemctl reload myapp > /dev/null 2>&1 || true  # 通知应用重新打开日志
    endscript                            # 命令结束标记
}

常用配置指令

# === 轮转频率 ===
daily       # 每天
weekly      # 每周
monthly     # 每月
yearly      # 每年

# === 保留策略 ===
rotate 7        # 保留 7 个旧日志
maxage 30       # 删除超过 30 天的旧日志
maxsize 100M    # 日志超过 100MB 就轮转(不管时间)
minsize 10M     # 日志至少 10MB 才轮转
size 50M        # 只按大小轮转,忽略时间

# === 压缩选项 ===
compress           # 压缩旧日志
nocompress         # 不压缩
delaycompress      # 延迟一次压缩
compresscmd /usr/bin/xz  # 用 xz 压缩(默认 gzip)

# === 文件处理 ===
create 0644 user group  # 轮转后创建新文件
copytruncate       # 复制后截断原文件(适合不支持 reload 的程序)
nocreate           # 不创建新文件
missingok          # 日志不存在不报错
notifempty         # 空文件不轮转
dateext            # 文件名用日期而不是数字编号
dateformat -%Y%m%d # 日期格式

高级用法

按大小轮转

# /etc/logrotate.d/biglog
/var/log/bigapp.log {
    size 500M         # 超过 500MB 才轮转(不管时间)
    rotate 5          # 保留 5 个
    compress          # 压缩
    missingok         # 不存在别报错
    copytruncate      # 复制截断模式(程序一直往里写也不怕)
}

Nginx 日志轮转

# /etc/logrotate.d/nginx
/var/log/nginx/*.log {
    daily                 # 每天轮转
    rotate 14             # 保留 14 天
    compress              # 压缩
    delaycompress         # 最近一次不压缩
    missingok             # 文件不存在不报错
    notifempty            # 空文件不轮转
    sharedscripts         # 多个日志文件只执行一次 postrotate

    postrotate
        # 给 nginx 发信号让它重新打开日志文件
        if [ -f /var/run/nginx.pid ]; then
            kill -USR1 $(cat /var/run/nginx.pid)  # USR1 信号让 nginx 重新打开日志
        fi
    endscript
}

手动测试轮转

# 测试配置是否正确(不实际执行)
sudo logrotate -d /etc/logrotate.d/myapp  # -d 是 debug 模式,只显示会做什么

# 强制立即执行轮转(用于测试)
sudo logrotate -f /etc/logrotate.d/myapp  # -f 强制执行,不管时间到没到

# 显示详细信息
sudo logrotate -v /etc/logrotate.conf  # -v 显示详细过程

多日志文件共享脚本

# 多个日志文件使用同一个 postrotate 脚本
/var/log/app/access.log /var/log/app/error.log {
    daily              # 每天轮转
    rotate 7           # 保留 7 天
    compress           # 压缩
    sharedscripts      # postrotate 只执行一次(不是每个文件执行一次)

    postrotate
        systemctl reload myapp  # 只通知一次应用重新打开日志
    endscript
}

常见报错

问题原因解决
error: skipping "xxx" because parent directory has insecure permissions日志目录权限不对chmod 755 /var/log/myapp
日志没有被轮转配置有语法错误logrotate -d 检查配置
轮转后应用不写新日志了应用没有重新打开日志文件在 postrotate 中 reload 服务或用 copytruncate
duplicate log entry同一个日志文件被多个配置管理检查 /etc/logrotate.d/ 下有没有重复
磁盘还是满了rotate 数太大或没有 compress减少 rotate 数量,启用压缩
error: stat of /var/log/xxx failed日志文件不存在missingok 指令

速查表

# === 常用命令 ===
logrotate -d /etc/logrotate.d/myapp   # 调试模式(不实际执行)
logrotate -f /etc/logrotate.d/myapp   # 强制执行
logrotate -v /etc/logrotate.conf      # 详细模式
cat /var/lib/logrotate/status         # 查看上次轮转状态

# === 配置模板 ===
# 基础模板
/var/log/xxx.log {
    daily
    rotate 7
    compress
    delaycompress
    missingok
    notifempty
    create 0644 user group
}

# 按大小模板
/var/log/xxx.log {
    size 100M
    rotate 5
    compress
    copytruncate
}

# === 常用指令 ===
daily/weekly/monthly    # 轮转频率
rotate N                # 保留 N 个旧日志
compress                # 压缩旧日志
delaycompress           # 延迟压缩
copytruncate            # 复制截断(不需要 postrotate)
missingok               # 文件不存在不报错
notifempty              # 空文件不轮转
create 权限 用户       # 创建新文件
size 大小               # 按大小轮转
maxage 天数             # 超龄删除
sharedscripts           # 共享脚本
postrotate/endscript    # 轮转后执行命令