服务器日志轮转实战:logrotate配置详解

服务器日志轮转实战:logrotate配置详解

你以为日志切割了就没事了。日志文件按日期切开了,但旧的还在。切了不删,等于没切。早晚会把磁盘撑爆。logrotate默认配置只切不删,或者只保留两份,根本不够用。你看了一眼/var/log,几十GB的旧日志躺在那里,没被清理,也没被压缩。工具给你了,你不会用。

今天把logrotate的配置讲透,让你真正掌控日志的生命周期。


先看一个数据

在排查磁盘空间不足的案例中,约40%的情况是由于日志文件未设置合理的轮转策略导致的。默认配置只保留4周日志,但实际上很多服务会产生大量日志,几周就能撑爆磁盘。不是因为工具不行,是因为你没告诉它该怎么做。


logrotate是什么

logrotate是Linux系统自带的日志管理工具,通过cron每天自动运行。它做的事情就是:旧的日志切出来、压缩、删除过期的。你不用手动去翻/var/log目录手动清理。

配置分两层:/etc/logrotate.conf是全局配置文件,定义默认规则;/etc/logrotate.d/目录下是各个服务的独立配置文件,每个服务自己管自己的日志。建议在/etc/logrotate.d/下为每个服务创建独立配置文件,比如nginxmysql,方便管理和维护。


一个Nginx配置模板

先给一个可以直接用的Nginx日志配置:

text

/var/log/nginx/*.log {
    daily
    rotate 14
    compress
    delaycompress
    missingok
    notifempty
    create 0640 www-data adm
    sharedscripts
    postrotate
        if [ -f /var/run/nginx.pid ]; then
            kill -USR1 `cat /var/run/nginx.pid`
        fi
    endscript
}

逐行解释

  • daily:每天轮转一次。可以换成weeklymonthly
  • rotate 14:保留14份旧日志。14天后自动删除。根据你的磁盘大小调整这个数字。
  • compress:把旧日志压缩成.gz格式。Nginx日志通常能压到原来的20%。
  • delaycompress:延迟压缩。当前轮转产生的日志先不压缩,等下一次轮转再压缩。这样如果Nginx还在往旧文件里写东西,不会写到压缩文件里
  • missingok:如果日志文件不存在,不报错,继续执行
  • notifempty:空文件不轮转。节省磁盘I/O
  • create 0640 www-data adm:轮转后用指定的权限和属主创建新的空日志文件。
  • sharedscripts:如果通配符匹配了多个日志文件,postrotate脚本只执行一次,而不是每个文件执行一次
  • postrotateendscript之间的命令在轮转完成后执行。这里给Nginx发了一个USR1信号,让它重新打开日志文件,停止往旧文件里写日志

USR1是Nginx接收的信号,通知它重新打开日志文件。如果你用其他服务(如Apache),信号或命令可能不同。


按大小轮转

有的服务日志每天产生量不等。有时一天才几MB,有时一天几十GB。按天轮转就不够灵活。

size参数:

text

/var/log/myapp/*.log {
    size 100M
    rotate 10
    compress
    missingok
    notifempty
    copytruncate
}

当日志文件超过100MB时触发轮转,而不是等到天结束。适合日志量不稳定的服务


三个进阶技巧

1. 用dateext给文件名加日期

默认轮转后的文件名是access.log.1access.log.2。加上dateext后变成access.log-20260616。方便按日期查找:

text

dateext
dateformat -%Y%m%d

2. 用olddir把旧日志移走

把旧日志移动到别的目录,保持主目录干净:

text

olddir /var/log/archive

3. 用copytruncate解决“无法发信号”的问题

有些应用不支持重新打开日志文件,或者你没权限发信号。copytruncate先把日志内容复制一份,再把原文件清空。有极小的概率会丢几条日志,但比日志文件无限增长好

text

copytruncate

手动测试

配完配置文件,别等第二天cron运行。先手动测试:

bash

# 调试模式:模拟运行,不实际改动
logrotate -d /etc/logrotate.d/nginx

# 强制轮转:实际执行
logrotate -f /etc/logrotate.d/nginx

# 加verbose输出详细信息
logrotate -vf /etc/logrotate.d/nginx

调试模式能看到会不会出错,强制轮转能验证效果


真实案例

一个公司的Nginx日志配置了rotate 30且每天轮转,保留了30天日志。某天流量突增,单日日志从1GB涨到15GB。30天就是450GB。/var分区直接被写爆,网站502。检查时发现rotate参数被注释掉了,变成了默认的0,日志永远不会删除。

rotate改回14,加了一行size 1G按大小触发轮转,每天定时运行,问题解决。


最后一句

logrotate的配置不难,难的是你一直用默认配置。每天花5分钟把/etc/logrotate.d/目录下的配置文件过一遍,确认rotate数量合理、compress开启、postrotate正确。如果你现在还靠手动删日志,明天把它配好。一次配置,长期受益。

知识库

Ansible vs SaltStack vs Puppet:自动化运维工具怎么选?

2026-6-16 14:52:17

知识库

服务器文件传输的5种方式:scp、rsync、sftp、rz/sz、WebDAV对比

2026-6-17 14:43:23

0 条回复 A文章作者 M管理员
    暂无讨论,说说你的看法吧