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 # 轮转后执行命令