服务器运行时间一长,日志文件就会不断增长。Nginx、MySQL、PHP、系统服务、应用程序都会持续写入日志,如果不定期清理,轻则占满磁盘空间,重则导致服务异常。Linux 中常用 logrotate 管理日志轮转,它可以按天、按周、按月或按文件大小切分日志,并自动压缩、保留、删除旧日志,也可以在轮转后执行脚本通知服务重新打开日志文件。
一、logrotate 是什么
logrotate 是 Linux/Unix 系统中用于管理日志轮转的工具。它主要解决几个问题:
- 日志文件持续变大,影响磁盘空间。
- 旧日志需要按时间归档。
- 归档日志需要压缩节省空间。
- 只保留最近一段时间的日志。
- 日志轮转后,服务需要重新打开新的日志文件。
- 不同应用需要不同的日志保留策略。
例如,Nginx 访问日志可以每天轮转并保留 14 天,系统日志可以每周轮转并保留 4 份,业务应用日志可以按大小轮转并压缩归档。logrotate 的优势在于规则清晰、自动执行、可针对不同服务单独配置。
二、安装 logrotate
大多数 Linux 发行版默认已经安装 logrotate。如果系统中没有,可以通过包管理器安装。
Debian / Ubuntu 系统:
sudo apt update
sudo apt install -y logrotate
CentOS / RHEL / Rocky Linux / AlmaLinux 系统:
sudo yum install -y logrotate
或使用:
sudo dnf install -y logrotate
安装后可以查看版本:
logrotate --version
也可以确认配置目录是否存在:
ls -l /etc/logrotate.conf
ls -l /etc/logrotate.d/
三、logrotate 的配置文件结构
logrotate 的配置通常分为两层:全局配置文件和子配置文件。
1. 全局配置文件:/etc/logrotate.conf
全局配置文件用于设置服务器统一的默认规则,适合大多数普通日志。常见路径是:
/etc/logrotate.conf
示例配置如下:
# 全局轮转周期
weekly
# 保留最近 4 次归档
rotate 4
# 每次轮转后创建新的日志文件
create
# 使用 gzip 压缩归档日志
compress
# 延迟一轮再压缩
delaycompress
# 日志文件不存在时不报错
missingok
# 日志为空时不轮转
notifempty
# 使用日期作为后缀,例如 .log-20250426.gz
dateext
# 加载单独服务配置
include /etc/logrotate.d
这份配置表示:默认每周轮转一次日志,保留最近 4 份归档,归档日志会压缩,空日志不处理,缺失日志不报错,并加载 /etc/logrotate.d/ 目录中的服务配置。
2. 子配置文件:/etc/logrotate.d/*
子配置文件用于针对具体应用单独设置规则,例如 Nginx、MySQL、Docker、PHP-FPM 或自定义应用。常见目录是:
/etc/logrotate.d/
例如 Nginx 的日志轮转配置可以写成:
/var/log/nginx/*.log {
daily
missingok
rotate 14
compress
delaycompress
notifempty
create 0640 nginx adm
sharedscripts
postrotate
[ -s /run/nginx.pid ] && kill -USR1 $(cat /run/nginx.pid)
endscript
}
这段配置表示:/var/log/nginx/ 目录下所有 .log 文件每天轮转一次,保留 14 份旧日志,归档日志压缩,空文件不轮转,轮转后创建权限为 0640、所属用户为 nginx、所属组为 adm 的新日志文件,并在轮转后通知 Nginx 重新打开日志文件。
四、常用配置参数说明
下面是 logrotate 中最常见的参数。
| 参数 | 作用 |
|---|---|
daily |
每天轮转一次 |
weekly |
每周轮转一次 |
monthly |
每月轮转一次 |
rotate N |
保留 N 个轮转后的旧日志文件 |
compress |
使用 gzip 压缩旧日志 |
delaycompress |
延迟到下一次轮转时再压缩 |
missingok |
日志文件不存在时不报错 |
notifempty |
日志为空时不轮转 |
create MODE OWNER GROUP |
轮转后创建新日志,并设置权限、用户和用户组 |
dateext |
使用日期作为轮转文件后缀 |
size |
日志达到指定大小后轮转 |
sharedscripts |
多个日志匹配时,脚本只执行一次 |
postrotate ... endscript |
日志轮转后执行脚本 |
prerotate ... endscript |
日志轮转前执行脚本 |
常见示例:
daily
rotate 7
compress
missingok
notifempty
create 0644 root root
表示每天轮转,保留 7 份归档,压缩旧日志,日志不存在或为空时不处理,轮转后创建新的日志文件。
五、logrotate 的工作原理
logrotate 通常通过系统定时任务每天自动执行。它不会一直在后台运行,而是由 cron 或 systemd timer 定时触发。
常见执行入口包括:
/etc/cron.daily/logrotate
在部分使用 systemd 的系统中,也可能通过 timer 触发:
systemctl status logrotate.timer
执行流程大致如下:
- 定时任务触发
logrotate。 - 读取
/etc/logrotate.conf全局配置。 - 加载
/etc/logrotate.d/目录中的子配置。 - 检查目标日志文件是否存在、是否为空、是否满足轮转条件。
- 对满足条件的日志执行轮转。
- 重命名旧日志,例如添加日期后缀。
- 按配置压缩归档日志。
- 创建新的日志文件。
- 删除超过保留数量的旧日志。
- 执行
postrotate中定义的脚本。
如果配置正确,整个过程对应用程序基本是透明的。应用继续写日志,旧日志被归档,新日志继续接收内容。
六、为什么轮转后要通知服务
很多服务在启动时会打开日志文件句柄。即使日志文件被 logrotate 重命名,服务进程可能仍然继续向旧文件句柄写入内容。如果不通知服务重新打开日志,新的日志文件可能不会被写入。
Nginx 配置中常见这段脚本:
postrotate
[ -s /run/nginx.pid ] && kill -USR1 $(cat /run/nginx.pid)
endscript
它的作用是:如果 Nginx 的 PID 文件存在,就向 Nginx 主进程发送 USR1 信号,通知 Nginx 重新打开日志文件。
这不是重启 Nginx,而是让它重新打开日志文件,通常不会中断服务。
不同服务的处理方式不同,例如有的服务需要 reload,有的服务支持特定信号,有的服务可以直接继续写新文件。配置前应确认服务的日志重载方式。
七、手动测试 logrotate 配置
修改配置后,不建议等到第二天自动执行再观察。可以先手动测试。
1. 强制执行某个配置
例如测试 Nginx 日志轮转:
sudo logrotate -f /etc/logrotate.d/nginx
-f 表示强制执行,即使当前还没有达到轮转条件,也会尝试轮转。
2. 显示详细执行过程
sudo logrotate -vf /etc/logrotate.d/nginx
参数含义:
-v:显示详细过程。-f:强制执行轮转。
这条命令适合排查配置是否生效、脚本是否执行、日志文件是否被正确创建。
3. 只调试不真正执行
如果只想检查配置,不想真正轮转日志,可以使用调试模式:
sudo logrotate -d /etc/logrotate.d/nginx
-d 会显示 logrotate 将要执行的动作,但不会真正修改日志文件。排查配置时很有用。
八、常见故障排查
1. 日志没有轮转
可以按顺序检查:
sudo logrotate -d /etc/logrotate.d/nginx
重点看:
- 配置文件语法是否正确。
- 日志路径是否匹配。
- 日志是否为空。
- 是否达到
daily、weekly、size等轮转条件。 - 是否存在
notifempty导致空日志不轮转。 - 是否有权限访问日志文件。
如果需要立即测试,可以使用:
sudo logrotate -vf /etc/logrotate.d/nginx
2. 轮转后新日志没有内容
常见原因是服务仍然写入旧文件句柄。检查配置中是否有 postrotate,以及脚本是否正确通知服务重新打开日志。
例如 Nginx 可以使用:
postrotate
[ -s /run/nginx.pid ] && kill -USR1 $(cat /run/nginx.pid)
endscript
如果是其他服务,要使用对应的 reload 或信号方式。
3. 新日志文件权限不正确
检查 create 参数。例如:
create 0640 nginx adm
表示新建日志文件权限为 0640,所有者为 nginx,用户组为 adm。
如果权限设置错误,服务可能无法继续写入日志。
4. 压缩没有立即生效
如果配置了:
delaycompress
归档文件会延迟到下一轮再压缩。这是正常现象,不代表 compress 失效。
如果希望轮转后立即压缩,可以去掉 delaycompress。
5. 配置文件没有被加载
确认全局配置中包含:
include /etc/logrotate.d
如果子配置文件不在该目录,自动执行时可能不会加载。也可以直接手动指定配置文件测试:
sudo logrotate -vf /path/to/custom-logrotate.conf
九、自定义应用日志轮转示例
假设有一个应用日志路径:
/opt/myapp/logs/app.log
可以创建配置文件:
sudo vi /etc/logrotate.d/myapp
写入:
/opt/myapp/logs/app.log {
daily
rotate 7
compress
delaycompress
missingok
notifempty
create 0644 www-data www-data
postrotate
systemctl reload myapp >/dev/null 2>&1 || true
endscript
}
这表示每天轮转一次,保留 7 份旧日志,压缩归档,轮转后重新加载 myapp 服务。
如果应用不支持 reload,可以去掉 postrotate,或者改用应用支持的日志重载方式。
十、使用 logrotate 的注意事项
- 日志路径要写绝对路径。
create的用户和用户组要与服务实际运行用户匹配。- 修改配置后先用
-d或-vf测试。 - 不同服务的日志重载方式不同,不能直接复制其他服务的
postrotate。 - 使用
delaycompress时,上一轮日志不会立即压缩。 - 如果日志为空且配置了
notifempty,不会触发轮转。 - 对重要业务日志,不要设置过短的保留周期。
- 日志轮转不等于日志备份,重要日志仍需单独备份或集中采集。
推荐阅读:
《Linux crontab不执行怎么办?5个常见原因与排查方案》
-
广告合作
-
QQ群号:4114653



