方法一:使用 logrotate(首选、最标准的方法)
logrotate
是 Linux 系统自带的日志管理工具,也是处理大多数应用程序日志的首选和标准方法。它支持自动轮转、压缩、删除旧日志以及通知应用程序重新打开日志文件。
1. 理解 logrotate 工作原理
logrotate
通常通过 cron
任务每天自动运行。它会根据 /etc/logrotate.conf
主配置文件和 /etc/logrotate.d/
目录下的自定义配置文件来执行轮转操作。
2. 查看现有配置
ls /etc/logrotate.d/
你会看到很多已安装软件包(如 nginx, mysql, syslog)自带的配置文件。
3. 创建自定义配置文件(示例)
假设你的应用日志存储在 /var/log/myapp/app.log
,需要每天轮转,保留最近 30 天的日志。
创建配置文件:
bash
sudo vim /etc/logrotate.d/myapp
写入以下内容:
bash
/var/log/myapp/app.log { daily # 每天轮转一次。可选:weekly, monthly, size-based (e.g. size 100M) missingok # 如果日志文件丢失,不报错,继续处理下一个 rotate 30 # 保留30个轮转后的归档日志 compress # 使用gzip压缩旧日志(生成 .gz 文件) delaycompress # 延迟压缩,下一次轮转时再压缩上一个文件(方便排查最新问题) notifempty # 如果日志文件是空的,则不进行轮转 copytruncate # 复制原日志文件后将其截断,而不是移动并重建。兼容性更好,但有一瞬间可能丢失日志 # 如果应用程序支持接收信号重新打开日志文件(如nginx),推荐使用以下方式而非 copytruncate # postrotate # invoke-rc.d nginx rotate > /dev/null # endscript }
copytruncate
vspostrotate
脚本:copytruncate
:更通用,适用于所有程序。其过程是cp app.log app.log.1 && > app.log
。在复制和截断之间有极小的数据丢失风险。postrotate
脚本:更优雅和安全。其过程是mv app.log app.log.1 && touch app.log && signal app
。需要应用程序支持通过信号(如SIGUSR1
)重新打开日志文件。
4. 手动测试配置
测试配置文件语法是否正确,并强制运行一次:
bash
sudo logrotate -d /etc/logrotate.d/myapp # -d 调试模式,干跑,不实际执行 sudo logrotate -vf /etc/logrotate.d/myapp # -v 详细模式,-f 强制运行
检查 /var/log/myapp/
目录下是否生成了 app.log.1.gz
之类的文件,并且原 app.log
被清空。
5. 它是自动的
logrotate
通过 cron.daily
自动运行,你无需再操心。可以通过 cat /etc/cron.daily/logrotate
查看它的cron配置。
方法二:使用 systemd journal(针对 systemd 系统的日志)
现代 Linux 发行版使用 systemd
的 journald
来管理系统和服务的日志,它们存储在 /var/log/journal/
或 /run/log/journal/
中。
1. 查看当前磁盘占用
bash
journalctl --disk-usage
2. 手动清理旧日志
bash
# 保留最近 500M 的日志 sudo journalctl --vacuum-size=500M # 保留最近 7 天的日志 sudo journalctl --vacuum-time=7d
3. 配置自动清理(永久生效)
编辑 /etc/systemd/journald.conf
文件:
ini
[Journal] # 限制单个日志文件大小 SystemMaxUse=1G # 限制整个日志系统占用的最大磁盘空间 SystemMaxFileSize=100M # 保留日志的时间 MaxRetentionSec=7day # 或者使用以下方式(优先级更高) #SystemMaxFiles=100
修改后重启 journald
服务:
bash
sudo systemctl restart systemd-journald
方法三:编写自定义 Shell 脚本 + cron(用于更复杂的场景)
如果你有非常特殊的清理需求(比如清理特定名称的临时文件、缓存文件等),logrotate
无法满足时,可以考虑此方法。
1. 创建清理脚本
例如,清理 /var/log/nginx/
下超过 30 天的旧压缩日志文件。
bash
#!/bin/bash # cleanup_old_logs.sh - 清理超过指定天数的日志文件 LOG_DIR="/var/log/nginx" FIND_PATTERN="*.log.*.gz" # 要匹配的文件模式 DAYS_TO_KEEP=30 # 查找并删除文件 find "$LOG_DIR" -type f -name "$FIND_PATTERN" -mtime +$DAYS_TO_KEEP -delete -print # 也可以使用 exec 更高效的处理(如需要额外操作) # find "$LOG_DIR" -type f -name "$FIND_PATTERN" -mtime +$DAYS_TO_KEEP -exec rm -f {} \;
2. 给脚本添加执行权限
bash
sudo chmod +x /path/to/cleanup_old_logs.sh
3. 添加 cron 任务实现自动化
使用 crontab -e
添加定时任务,例如每天凌晨 3 点运行:
bash
# 编辑 root 的 cron 任务 sudo crontab -e # 添加一行 0 3 * * * /path/to/cleanup_old_logs.sh >> /var/log/cleanup.log 2>&1
方法四:使用 tmpwatch/tmpreaper(专清理临时目录)
tmpwatch
(RHEL/CentOS)或 tmpreaper
(Debian/Ubuntu)是专门设计来自动清理 /tmp
、 /var/tmp
等临时目录的工具。
安装:
bash
# On Ubuntu/Debian sudo apt install tmpreaper # On RHEL/CentOS sudo yum install tmpwatch
配置:
主配置文件通常在/etc/tmpreaper.conf
或/etc/cron.daily/tmpwatch
。
你可以编辑它,设置受保护的目录(SHOWWARNING=true
)和清理时间(TMPREAPER_TIME=7d
)。
总结与最佳实践
方法 | 适用场景 | 优点 | 缺点 |
---|---|---|---|
logrotate | 应用程序日志、服务日志 | 系统标准、功能强大、安全可靠、与cron集成 | 配置稍复杂 |
journalctl | systemd 系统和服务的日志 | 原生系统支持、统一管理 | 只管理 journald 日志 |
自定义脚本 | 特殊文件、非标准日志、缓存 | 灵活性极高 | 需要自行实现所有功能,易出错 |
tmpwatch | /tmp , /var/tmp 等临时目录 |
专精于临时文件清理 | 功能单一 |
行动建议:
优先使用
logrotate
:为你部署的所有应用程序配置logrotate
规则。这是最规范、最不容易出错的方法。配置
journald
:统一管理系统日志的保留策略。慎用自定义脚本:只有在上述方法都无法满足需求时,才考虑编写脚本,并务必充分测试。
设置监控告警:即使有自动化清理,也应为磁盘空间设置监控告警(例如,使用
Prometheus
、Zabbix
或简单的cron
脚本检查df -h
),作为最后的防线。