很多 Linux 服务器并不是因为业务突然暴涨才出问题,而是被日志一点点拖慢:磁盘空间被占满、单个日志文件过大、排障时翻不到关键时间段,甚至因为服务一直写旧文件,明明执行了轮转,空间却没有释放。logrotate 就是用来解决这类问题的基础工具,但它并不是“装上就万事大吉”。配置路径、执行周期、权限、压缩策略和服务重载方式,任何一个细节不对,都可能让日志轮转看起来正常、实际失效。

logrotate 负责什么
logrotate 的核心工作很简单:把持续增长的日志文件按时间或大小切分成多个历史文件,并按照保留策略压缩、删除或归档。比如 Nginx 的 access.log 每天增长几百 MB,轮转后可以变成 access.log、access.log.1、access.log.2.gz 这类结构,当前服务继续写新的 access.log,旧日志则用于回溯问题。
它解决的是“日志生命周期管理”,不是应用日志本身的格式问题,也不是磁盘扩容工具。日志轮转做得好,服务器不会因为某个日志文件无限膨胀而突然 100% 占满;日志轮转做得差,监控看到磁盘告警时,往往已经影响写入、缓存、数据库临时文件甚至业务上传。
在生产环境里,logrotate 通常由 cron 或 systemd timer 定时触发。它会读取全局配置文件和目录下的应用配置,然后判断每个日志是否满足轮转条件。理解这一点很重要:配置写好了,不代表立刻会执行;执行了,也不代表每个文件都满足轮转条件。
先确认配置有没有被读取
排查 logrotate 失效,第一步不是改参数,而是确认配置文件是否真的被加载。常见主配置在 /etc/logrotate.conf,应用级配置通常放在 /etc/logrotate.d/。如果你把文件放错目录、文件名带了不合适的后缀,或者配置语法有误,logrotate 可能直接跳过。
可以用调试模式先看它会做什么:logrotate -d /etc/logrotate.conf。这个命令只模拟执行,不会真正改动日志文件,适合在线上先验证规则。输出里会显示哪些配置被读取、哪些日志被检查、为什么没有轮转。比如“log does not need rotating”通常表示没满足时间或大小条件,而不是工具没运行。
如果只想测试某个应用的配置,可以单独指定文件:logrotate -d /etc/logrotate.d/nginx。这样能减少无关输出,更快定位问题。修改前先跑调试模式,是避免误删日志、误压缩当前文件的安全习惯。
时间条件和大小条件别混用错
logrotate 最常见的触发条件有 daily、weekly、monthly 和 size、minsize、maxsize。很多失效都来自对这些条件的误解。daily 不是“每次执行都轮转”,而是结合状态文件判断上次轮转时间;size 也不是“超过一点就随时触发”,它仍然依赖 logrotate 被调度执行。
如果配置了 daily,但系统的定时任务一天只执行一次,那么日志在两次执行之间暴涨到几十 GB,也不会马上被处理。对增长很快的日志,可以考虑配合 size 500M 或 maxsize 1G,并提高调度频率。但这类调整要结合磁盘容量和压缩开销,不能只看单个文件大小。
另一个常见坑是状态文件。logrotate 会在 /var/lib/logrotate/status 里记录上次轮转时间。如果状态文件损坏、权限异常,或者手动测试时用了不同的 state 文件,实际执行结果就可能和预期不一致。强制测试可以用 logrotate -f,但线上使用前要确认配置和服务重载命令没有风险。
服务还在写旧文件怎么办
日志文件被重命名或压缩后,应用进程未必自动切换到新文件。Linux 里进程写日志依赖文件描述符,只要文件描述符还指向旧 inode,哪怕路径上的 access.log 已经变成新文件,进程仍可能继续往旧文件写。你会看到磁盘空间没释放、旧日志继续增长,这就是很多人误以为“轮转失败”的原因。
解决办法通常有两类:一种是在 logrotate 配置里使用 postrotate 通知服务重新打开日志,比如对 Nginx 执行 nginx -s reopen 或 reload;另一种是使用 copytruncate,先复制原日志再把原文件截断,让进程继续写同一个文件。前者更规范,后者兼容性强,但在高并发写入时可能丢少量日志。
选择哪种方式,要看服务是否支持平滑重开日志。Nginx、Apache、rsyslog 这类常见服务一般都有成熟方案;自研程序或老旧服务如果没有信号处理能力,copytruncate 可能更现实。无论哪种方式,都要在低峰期测试一次,确认轮转后新日志能正常生成。
权限和属主经常被忽略
logrotate 需要有权限读取、重命名、创建和压缩日志文件。如果日志目录属主、组权限或 SELinux/AppArmor 策略不匹配,轮转就可能失败。典型现象是手动执行时报 permission denied,或者轮转后新文件创建了,但服务无法继续写入,导致业务日志中断。
配置里的 create 0640 www-data adm 这类写法很关键。它决定轮转后新日志文件的权限、属主和属组。对 Nginx、PHP-FPM、应用程序日志来说,新文件权限不对,比旧文件没压缩更麻烦,因为服务可能从此写不进日志,后续排障反而失去依据。
如果日志目录由应用自动创建,也要确认目录权限稳定。容器、部署脚本、面板程序有时会在更新时重建目录,把权限改回默认值。遇到轮转偶发失败,不妨同时检查部署流程,而不是只盯 logrotate 配置。
压缩策略要看业务窗口
日志压缩能节省空间,但压缩本身会消耗 CPU 和 I/O。访问量较高的网站,如果在业务高峰压缩几十 GB 日志,可能造成磁盘抖动,影响接口响应。常见做法是开启 compress,同时用 delaycompress 延迟压缩最近一份日志,减少服务仍在写旧文件时的冲突。
保留周期也要按排障需求设置。rotate 7 表示保留 7 份历史文件,不等于保留 7 天,具体还要看 daily 还是 weekly。对合规、安全审计或业务复盘要求较高的系统,本地保留可能不够,还需要把历史日志同步到对象存储或集中日志平台。
如果只是普通网站服务器,本地保留 7 到 30 天通常够用;如果是订单、支付、登录、安全审计相关日志,建议结合备份策略单独处理。速维云的 服务器 适合承载网站和业务系统,但无论配置多高,日志保留与清理策略都应该在上线前规划好,不能等磁盘告警后再临时补救。
推荐的排查顺序
线上遇到 logrotate 不生效,可以按固定顺序检查:先用 logrotate -d 看配置是否被读取;再看 /var/lib/logrotate/status 判断上次轮转时间;然后确认系统定时任务是否正常运行;接着检查日志路径、权限、属主和目录是否存在;最后再看 postrotate 或 copytruncate 是否让服务正确切换日志。
如果磁盘已经快满,不要一上来删除大日志。更安全的处理方式是先确认哪个进程正在占用文件,必要时用 lsof | grep deleted 查看已删除但仍被进程占用的日志。直接 rm 可能让路径消失,却不释放空间;重载或重启相关服务后,空间才会真正回收。
排查完成后,建议做一次完整演练:准备测试日志,强制轮转,确认新日志生成、旧日志压缩、服务继续写入、监控恢复正常。把这套动作写进运维文档,后续遇到磁盘告警时,就不会临时凭感觉操作。
把日志轮转纳入日常运维
logrotate 不是一次性配置,而是服务器上线清单的一部分。新部署一个网站、一个 API 服务、一个后台任务,都应该确认日志路径、增长速度、保留周期、压缩策略和异常告警。否则服务越多,日志越分散,真正出问题时越难定位。
对中小团队来说,最实用的做法是把日志分为三类:访问日志按天轮转并压缩,错误日志保留更长时间,业务关键日志同步到集中平台。这样既能控制服务器磁盘,又能保留排障证据。日志轮转做得稳,服务器维护成本会明显下降。
归根到底,logrotate 失效很少是单一原因。它往往牵涉调度、权限、服务信号、状态文件和磁盘容量。按顺序排查、按业务窗口调整策略,比盲目扩大磁盘或删除日志更可靠。














