目录
1. logrotate 简介和作用
1.1 什么是 logrotate?
logrotate 是 Linux 系统自带的日志管理工具,用于自动轮转、压缩、删除日志文件。
1.2 解决的问题
| 问题 | 说明 |
|---|---|
| 磁盘空间 | 日志无限增长会占满磁盘 |
| 性能下降 | 大文件读写影响系统性能 |
| 难以查看 | GB 级别的日志文件无法打开 |
| 无法排查 | 磁盘写满后服务崩溃,无法记录日志 |
1.3 核心功能
| 功能 | 说明 |
|---|---|
| 轮转 | 当日志达到指定大小或时间,自动创建新文件 |
| 压缩 | 轮转后的旧日志自动压缩为 .gz 文件 |
| 删除 | 超过保留数量的旧日志自动删除 |
| 通知 | 轮转后可执行脚本(如通知服务重新打开日志) |
2. logrotate 执行机制
2.1 触发条件
logrotate 在以下情况下会触发轮转:
| 条件 | 说明 |
|---|---|
daily |
每天检查一次 |
weekly |
每周检查一次 |
monthly |
每月检查一次 |
size 50M |
文件大小超过指定值立即轮转 |
注意:size 优先级高于时间条件。
2.2 执行流程
┌─────────────────────────────────────────┐
│ 定时任务触发(每天凌晨 4 点) │
└────────────────┬────────────────────────┘
│
▼
┌─────────────────────────────────────────┐
│ 读取配置文件 │
│ /etc/logrotate.conf │
│ + /etc/logrotate.d/* │
└────────────────┬────────────────────────┘
│
▼
┌─────────────────────────────────────────┐
│ 检查每个日志文件 │
│ 1. 是否达到 size 大小 │
│ 2. 是否到了 daily/weekly 时间 │
└────────────────┬────────────────────────┘
│
┌────────┴────────┐
│ 不满足条件 │ 满足条件
▼ ▼
┌───────────────┐ ┌─────────────────────────────────────────┐
│ 跳过,不轮转 │ │ 执行轮转 │
└───────────────┘ │ 1. 重命名当前日志 │
│ mongodb.log → mongodb.log.1 │
│ 2. 创建新日志文件 │
│ mongodb.log(空文件) │
│ 3. 执行 postrotate 脚本 │
│ 4. 压缩旧日志(如配置 compress) │
│ mongodb.log.1 → mongodb.log.1.gz │
│ 5. 删除超量旧日志 │
└─────────────────────────────────────────┘
2.3 cron 定时任务
logrotate 由系统的 cron 定时任务驱动。
# 查看 cron 配置
cat /etc/crontab
# 输出示例:
# 0 4 * * * root test -x /usr/sbin/anacron || (cd / && run-parts --report /etc/cron.daily)
这表示每天凌晨 4 点,系统会执行 /etc/cron.daily 目录下的脚本,而 logrotate 就在其中。
3. logrotate 常用命令
3.1 查看配置
# 查看全局配置
cat /etc/logrotate.conf
# 查看所有配置
ls -la /etc/logrotate.d/
# 查看具体配置
cat /etc/logrotate.d/mongodb
3.2 测试和调试
# 模拟运行(不实际执行,只显示会发生什么)
sudo logrotate -d /etc/logrotate.d/mongodb
# 强制执行一次(用于测试)
sudo logrotate -f /etc/logrotate.d/mongodb
# 指定配置文件执行
sudo logrotate -f /etc/logrotate.conf
3.3 手动轮转
# 手动轮转单个日志
sudo logrotate -f /etc/logrotate.d/mongodb
# 查看日志文件变化
ls -lh /data/gamedb/mongodb.log*
4. 配置示例
4.1 MongoDB 日志配置
# 创建配置文件
sudo tee /etc/logrotate.d/mongodb << 'EOF'
/data/gamedb/mongodb.log {
daily # 每天检查一次
size 50M # 超过 50MB 立即轮转(优先于 daily)
rotate 7 # 保留 7 个文件
compress # 压缩旧文件为 .gz
delaycompress # 延迟压缩(下一次轮转时压缩)
missingok # 文件不存在不报错
notifempty # 空文件不轮转
create 0640 root root # 新文件权限(用户名改成实际用户)
postrotate
# 轮转后通知 MongoDB 重新打开日志文件
pkill -USR1 mongod
endscript
}
EOF
4.2 PM2 日志配置
sudo tee /etc/logrotate.d/pm2 << 'EOF'
/home/用户名/.pm2/logs/*.log {
daily
size 10M
rotate 5
compress
missingok
notifempty
create 0640 用户名 用户名
postrotate
pm2 reloadLogs > /dev/null 2>&1
endscript
}
EOF
4.3 Nginx 日志配置
sudo tee /etc/logrotate.d/nginx << 'EOF'
/var/log/nginx/*.log {
daily
size 100M
rotate 14
compress
delaycompress
missingok
notifempty
create 0640 www-data adm
sharedscripts
postrotate
[ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid`
endscript
}
EOF
5. 注意事项
5.1 用户权限
| 注意点 | 说明 |
|---|---|
create 参数 |
必须使用实际用户名,不能用 $(whoami) |
| 文件权限 | 确保运行用户对日志目录有写权限 |
| sudo 权限 | 配置和执行 logrotate 通常需要 root 权限 |
5.2 postrotate 脚本
| 注意点 | 说明 |
|---|---|
| 必须通知服务 | 否则服务会继续往旧日志文件写内容 |
| MongoDB | 使用 pkill -USR1 mongod 或 db.adminCommand({logRotate: 1}) |
| PM2 | 使用 pm2 reloadLogs |
| Nginx | 使用 kill -USR1 $(cat /var/run/nginx.pid) |
5.3 compress 延迟压缩
| 参数 | 说明 |
|---|---|
compress |
立即压缩旧日志 |
delaycompress |
下次轮转时才压缩(配合使用更安全) |
6. 常见问题
问题 1:unknown user 错误
错误:
error: unknown user '$(whoami)'
原因:$(whoami) 在 logrotate 配置中不生效。
解决:替换为实际用户名。
create 0640 root root # 用实际用户替换
问题 2:日志没有轮转
检查:
# 模拟运行查看原因
sudo logrotate -d /etc/logrotate.d/mongodb
# 手动强制执行
sudo logrotate -f /etc/logrotate.d/mongodb
常见原因:
- 日志文件大小没达到
size阈值 - 时间没到
daily指定的时间 - 文件权限不足
问题 3:postrotate 不生效
检查:
# 查看 MongoDB 是否收到信号
ps aux | grep mongod
# 手动测试
pkill -USR1 mongod
# 查看日志是否还在写入
tail /data/gamedb/mongodb.log
问题 4:磁盘空间不足但日志没删除
检查:
# 查看日志文件
ls -lh /data/gamedb/mongodb.log*
# 检查 rotate 数量
grep rotate /etc/logrotate.d/mongodb
# 手动清理
sudo logrotate -f /etc/logrotate.d/mongodb
附录:配置参数速查
| 参数 | 说明 |
|---|---|
daily |
每天检查 |
weekly |
每周检查 |
monthly |
每月检查 |
size 50M |
超过指定大小轮转 |
rotate 7 |
保留 7 个文件 |
compress |
压缩旧文件 |
delaycompress |
延迟压缩 |
missingok |
文件不存在不报错 |
notifempty |
空文件不轮转 |
create 0640 user group |
新文件权限 |
prerotate |
轮转前执行的脚本 |
postrotate |
轮转后执行的脚本 |
endscript |
脚本结束标记 |