使用logrotate实现日志轮转

logrotate 是一个强大的 Linux 工具,用于自动化管理日志文件的轮转、压缩、删除和归档。它能有效防止日志文件无限增长,节省磁盘空间,同时保持日志的可追溯性。以下是详细讲解 logrotate 的用法,涵盖安装、配置、测试、自动化、常见问题及高级功能。


1. 什么是 logrotate

logrotate 是一个系统级工具,用于:

  • 按时间(每天、每周、每月)或大小轮转日志文件。
  • 压缩旧日志文件(如生成 .gz.xz 文件)。
  • 删除过旧的日志文件以释放空间。
  • 在轮转后通知应用程序重新打开新日志文件。
  • 支持自定义脚本执行额外操作(如重启服务)。

它广泛用于管理系统日志(如 /var/log/syslog)和应用日志(如 Nginx、Apache、自定义应用日志)。


2. 安装 logrotate

大多数 Linux 发行版(如 Ubuntu、CentOS、Debian)默认预装 logrotate。若未安装,可手动安装:

  • Ubuntu/Debian
bash 复制代码
sudo apt update
sudo apt install logrotate
  • CentOS/RHEL
bash 复制代码
sudo yum install logrotate
  • 验证安装:
bash 复制代码
logrotate --version

输出类似:

复制代码
logrotate 3.18.0

3. logrotate 的工作机制

  • 配置文件
    • 主配置文件:/etc/logrotate.conf,定义全局轮转规则。
    • 子配置文件:/etc/logrotate.d/ 目录下的文件,定义特定日志的轮转规则。
  • 调度执行
    logrotate 通常通过 cronsystemd 定时任务每天运行,检查并执行轮转。
  • 轮转流程
    1. 检查日志文件是否满足轮转条件(时间或大小)。
    2. 重命名旧日志文件(如 app.log 变为 app.log.1)。
    3. 创建新日志文件。
    4. 压缩旧日志(如生成 app.log.1.gz)。
    5. 删除超出保留周期的日志。
    6. 执行自定义脚本(如通知应用程序)。

4. 配置文件详解

logrotate 的配置由全局配置和子配置组成,格式为纯文本,包含日志文件路径和轮转指令。

4.1 主配置文件

/etc/logrotate.conf 定义全局默认规则,示例:

bash 复制代码
weekly
rotate 4
create
compress
include /etc/logrotate.d
/var/log/wtmp {
    monthly
    create 0664 root utmp
    rotate 1
}
  • weekly:默认每周轮转一次。
  • rotate 4:保留 4 个历史日志文件。
  • create:轮转后创建新日志文件。
  • compress :压缩旧日志文件(默认使用 gzip)。
  • include /etc/logrotate.d :包含 /etc/logrotate.d/ 下的子配置文件。
  • /var/log/wtmp { ... }:为特定日志文件定义轮转规则。

4.2 子配置文件

子配置文件存放在 /etc/logrotate.d/,每个文件针对特定应用或日志。例如,为自定义应用日志 /var/log/myapp.log 创建轮转规则:

bash 复制代码
/var/log/myapp.log {
    daily
    rotate 7
    size 100M
    compress
    delaycompress
    missingok
    notifempty
    create 0640 root root
    postrotate
        /bin/kill -HUP `cat /var/run/myapp.pid 2>/dev/null` 2>/dev/null || true
    endscript
}
配置项说明:
  • /var/log/myapp.log :要轮转的日志文件路径,支持通配符(如 /var/log/myapp/*.log)。
  • daily :每天轮转(其他选项:weeklymonthly)。
  • rotate 7 :保留 7 个历史日志文件(如 myapp.log.1.gzmyapp.log.7.gz)。
  • size 100M :当日志文件超过 100MB 时触发轮转(支持 KMG 单位)。
  • compress:压缩旧日志文件。
  • delaycompress :延迟压缩到下一次轮转(即 myapp.log.1 不压缩,myapp.log.2 开始压缩)。
  • missingok:如果日志文件不存在,不报错。
  • notifempty:如果日志文件为空,不轮转。
  • create 0640 root root :轮转后创建新文件,权限为 0640,属主和属组为 root
  • postrotate ... endscript :轮转后执行脚本,这里发送 HUP 信号通知进程重新打开日志文件。
  • || true :确保脚本即使失败也不会影响 logrotate 继续运行。

4.3 保存子配置文件

创建文件:

bash 复制代码
sudo nano /etc/logrotate.d/myapp

粘贴上述配置,保存并退出。确保文件权限正确:

bash 复制代码
sudo chmod 644 /etc/logrotate.d/myapp

5. 常用配置选项

以下是 logrotate 支持的常用指令:

  • 时间控制
    • daily:每天轮转。
    • weekly:每周轮转。
    • monthly:每月轮转。
  • 大小控制
    • size 100M:文件超过指定大小触发轮转。
    • maxsize 500M:即使未到时间周期,超过此大小也轮转。
  • 文件管理
    • rotate <n>:保留 <n> 个历史日志。
    • create <mode> <owner> <group>:创建新文件的权限、属主、属组。
    • nocreate:不创建新文件。
    • missingok:日志文件缺失不报错。
    • notifempty:空文件不轮转。
  • 压缩
    • compress:启用压缩。
    • nocompress:禁用压缩。
    • delaycompress:延迟压缩。
    • compresscmd /usr/bin/xz:使用 xz 压缩。
    • compressext .xz:压缩文件后缀。
  • 脚本执行
    • prerotate/endscript:轮转前执行脚本。
    • postrotate/endscript:轮转后执行脚本。
    • firstaction/endscript:在处理一组日志前执行一次。
    • lastaction/endscript:在处理一组日志后执行一次。
  • 其他
    • mail user@example.com:将轮转的日志发送到指定邮箱。
    • olddir /path/to/archive:将旧日志移动到指定目录。
    • maxage 30:删除超过 30 天的旧日志。

6. 测试 logrotate 配置

在生产环境操作前,测试配置以确保无误:

  • 调试模式
bash 复制代码
sudo logrotate -d /etc/logrotate.conf
  • -d:模拟轮转过程,显示详细日志但不实际修改文件。

  • 检查输出,确认规则是否按预期应用。

  • 强制执行

bash 复制代码
sudo logrotate -f /etc/logrotate.conf
  • -f:强制执行轮转,立即应用规则。

  • 检查 /var/log/,确认是否生成新日志文件(如 myapp.log)和压缩文件(如 myapp.log.1.gz)。

  • 针对单一配置文件测试

bash 复制代码
sudo logrotate -d /etc/logrotate.d/myapp

7. 自动化轮转

logrotate 通常通过定时任务自动运行:

  • Cron 调度
    默认每天运行 /etc/cron.daily/logrotate。查看脚本:
bash 复制代码
cat /etc/cron.daily/logrotate

示例内容:

bash 复制代码
#!/bin/sh
/usr/sbin/logrotate /etc/logrotate.conf
EXITVALUE=$?
if [ $EXITVALUE != 0 ]; then
    /usr/bin/logger -t logrotate "ALERT exited abnormally with [$EXITVALUE]"
fi
exit 0

确保 cron 服务运行:

bash 复制代码
sudo systemctl status cron
  • Systemd 定时器 (现代系统):
    部分系统使用 systemd 替代 cron。检查定时器:
bash 复制代码
systemctl status logrotate.timer

启用定时器:

bash 复制代码
sudo systemctl enable logrotate.timer
sudo systemctl start logrotate.timer
  • 自定义调度
    如果需要更频繁的轮转,创建自定义 cron 任务:
bash 复制代码
sudo crontab -e

添加(每小时运行):

bash 复制代码
0 * * * * /usr/sbin/logrotate /etc/logrotate.conf

8. 实际应用示例

以下是针对不同场景的配置示例:

8.1 Nginx 日志轮转

为 Nginx 的访问日志和错误日志配置轮转:

bash 复制代码
/var/log/nginx/*.log {
    daily
    rotate 14
    compress
    delaycompress
    missingok
    notifempty
    create 0640 nginx adm
    sharedscripts
    postrotate
        /usr/sbin/nginx -s reopen
    endscript
}
  • sharedscripts:对一组日志只执行一次脚本(避免通配符重复执行)。
  • nginx -s reopen:通知 Nginx 重新打开日志文件。

8.2 按大小轮转大型日志

为快速增长的日志配置大小触发:

bash 复制代码
/var/log/bigapp.log {
    size 500M
    rotate 5
    compress
    create 0640 root root
    postrotate
        /bin/kill -HUP `cat /var/run/bigapp.pid 2>/dev/null` 2>/dev/null || true
    endscript
}

8.3 归档到指定目录

将旧日志移动到归档目录:

bash 复制代码
/var/log/myapp.log {
    daily
    rotate 7
    compress
    olddir /var/log/archive
    create 0640 root root
}

确保 /var/log/archive 存在且有写权限:

bash 复制代码
sudo mkdir -p /var/log/archive
sudo chown root:root /var/log/archive
sudo chmod 755 /var/log/archive

9. 常见问题与解决

  • 日志未轮转
    • 检查配置文件语法:
bash 复制代码
sudo logrotate -d /etc/logrotate.conf
  • 确认定时任务运行:
bash 复制代码
sudo systemctl status cron
  • 检查日志文件权限,确保 logrotate 可读写:
bash 复制代码
ls -l /var/log/myapp.log
  • 确认日志文件非空(若配置了 notifempty)。

  • 进程未重新打开日志文件

    • 验证 postrotate 脚本是否正确。例如,检查进程 PID 文件:
bash 复制代码
cat /var/run/myapp.pid
  • 确认信号(如 HUP)对应用有效,参考应用文档。

  • 压缩文件占用过多空间

    • 减少 rotate 值或启用更高压缩率:
bash 复制代码
compresscmd /usr/bin/xz
compressext .xz
  • 删除旧日志:
bash 复制代码
maxage 30
  • 权限错误

    • 确保 create 指定的用户和组存在。
    • 检查 olddir 目录权限。
  • 调试日志
    logrotate 的运行日志记录在 /var/log/syslog/var/log/messages

bash 复制代码
grep logrotate /var/log/syslog

10. 高级功能

  • 多日志文件分组
    使用通配符处理多个日志:
bash 复制代码
/var/log/myapp/*.log {
    daily
    rotate 7
    compress
    sharedscripts
    postrotate
        /bin/kill -HUP `cat /var/run/myapp.pid 2>/dev/null` 2>/dev/null || true
    endscript
}
  • 条件轮转
    结合 size 和时间:
bash 复制代码
/var/log/myapp.log {
    daily
    size 100M
    rotate 7
    compress
}

日志每天检查,若超过 100MB 或达到时间周期则轮转。

  • 邮件通知
    将轮转的日志发送到邮箱:
bash 复制代码
/var/log/myapp.log {
    daily
    rotate 7
    mail user@example.com
}
  • 状态文件
    logrotate 使用 /var/lib/logrotate/status 记录轮转状态,查看:
bash 复制代码
cat /var/lib/logrotate/status

若状态文件损坏,可删除后重建:

bash 复制代码
sudo rm /var/lib/logrotate/status
sudo logrotate -f /etc/logrotate.conf

11. 最佳实践

  • 测试配置 :始终先用 -d 调试,避免生产环境错误。
  • 权限管理 :设置合理的文件权限(如 0640),防止敏感日志泄露。
  • 日志归档:结合备份工具(如 Restic)定期归档压缩日志。
  • 监控磁盘:定期检查磁盘使用情况:
bash 复制代码
df -h /var/log
  • 文档参考 :查阅 man logrotate官方文档 获取更多细节。

12. 注意事项

  • 进程兼容性:某些应用(如 MySQL)需要特定重启命令,参考其文档。
  • 磁盘空间 :确保 /var/logolddir 有足够空间。
  • 备份策略:轮转后立即备份压缩日志,防止意外删除。
  • 避免重复轮转:同一日志文件不要在多个配置文件中定义。
相关推荐
A小辣椒1 天前
TShark:Wireshark CLI 功能
linux
A小辣椒1 天前
TShark:基础知识
linux
AlfredZhao1 天前
OCI 明明分配了 200G 系统盘,为什么 df 只看到 30G?
linux·oci
AlfredZhao2 天前
vi 删除指定范围的行,不用再反复按 dd
linux·vi
用户9718356334662 天前
银河麒麟 KY10 申威(SW64) 安装 nginx-1.16.1-2.p01.ky10.sw_64.rpm 详细步骤
linux
猪脚踏浪2 天前
linux 拷贝文件或目录到指定的位置
linux
摇滚侠3 天前
Linux CentOS7 rpm 安装 MySQL 5.7
linux·运维·mysql
bush43 天前
嵌入式linux学习记录十四、术语
linux·嵌入式
载数而行5203 天前
Linux 11 动态监控指令top
linux
不会C语言的男孩3 天前
Linux 系统编程 · 第 8 章:进程基础
linux·c语言