跳至正文

Linux logrotate 日志轮转工具指南

目录

  1. logrotate 简介和作用
  2. logrotate 执行机制
  3. logrotate 常用命令
  4. 配置示例
  5. 注意事项
  6. 常见问题

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 mongoddb.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 脚本结束标记

发表回复

您的邮箱地址不会被公开。 必填项已用 * 标注