日志是排查问题的唯一依据,但它也是磁盘的头号杀手。不管理的话,几个月就能把一个 40G 的系统盘写满。
这篇讲:Linux 有哪些日志、怎么看、怎么自动轮转清理、以及出问题时怎么快速定位。
日志和备份是运维的两条命脉。财富云计算 的云服务器支持快照与扩容;内网服务、游戏服务端可选 NAT 型(无独立公网 IP,价格比带独立 IP 机型省一半以上)。
一、Linux 有哪些日志
systemd 系统(现代发行版)
用 journalctl 统一管理:
journalctl # 全部日志
journalctl -b # 本次开机以来
journalctl -b -1 # 上一次开机(排查崩溃原因)
journalctl -f # 实时跟踪
journalctl -u nginx # 某个服务
journalctl -u nginx -f # 实时跟踪某服务
journalctl -u nginx --since today
journalctl --since "2026-10-01" --until "2026-10-02"
journalctl -p err -n 50 # 只看错误级别
journalctl -k # 内核日志(等同 dmesg)
journalctl --disk-usage # 日志占了多少空间
journalctl -o json-pretty # JSON 输出日志级别:emerg(0) alert(1) crit(2) err(3) warning(4) notice(5) info(6) debug(7)
传统文本日志
| 路径 | 内容 |
|---|---|
/var/log/syslog | 系统综合日志(Debian/Ubuntu) |
/var/log/messages | 系统综合日志(CentOS) |
/var/log/auth.log | 登录认证日志(Ubuntu) |
/var/log/secure | 登录认证日志(CentOS) |
/var/log/kern.log | 内核日志 |
/var/log/dmesg | 启动信息 |
/var/log/nginx/access.log | Nginx 访问日志 |
/var/log/nginx/error.log | Nginx 错误日志 |
/var/log/mysql/error.log | MySQL 错误日志 |
/var/log/php8.2-fpm.log | PHP-FPM 日志 |
/var/log/fail2ban.log | fail2ban 日志 |
/var/log/cron | 定时任务日志 |
/var/log/audit/audit.log | 审计日志(SELinux) |
常用查看方式:
tail -f /var/log/syslog # 实时跟踪
tail -n 100 /var/log/nginx/error.log
head -n 50 file.log
less file.log # 分页,可搜索
grep "error" file.log
grep -i "fail" file.log | tail -20
sed -n '10,20p' file.log # 看指定行
awk '{print $1}' access.log | sort | uniq -c | sort -nr | head二、日志为什么会撑爆磁盘
- journald 无限制增长(默认上限是磁盘的 10% 或 4GB)
- Nginx/Apache 访问日志从不轮转
- 程序开 DEBUG 级别,疯狂输出
- 错误循环:服务反复崩溃重启,每次都写一堆日志
- 没有 logrotate 配置
查看谁占了空间:
du -sh /var/log/* | sort -h
journalctl --disk-usage
ncdu /var/log三、logrotate:自动轮转清理
logrotate 是 Linux 标准的日志轮转工具,按天/周/大小切分日志、压缩、保留指定份数、删除过期。
配置位置
/etc/logrotate.conf 主配置
/etc/logrotate.d/* 各软件的配置文件(推荐放这里)配置示例(Nginx)
cat /etc/logrotate.d/nginx/var/log/nginx/*.log {
daily # 每天轮转
missingok # 日志不存在不报错
rotate 14 # 保留 14 份
compress # 压缩旧日志
delaycompress # 延迟一轮再压缩(避免服务还占用)
notifempty # 空文件不轮转
create 0640 www-data adm # 新建文件的权限和所有者
sharedscripts # 多个日志只执行一次脚本
postrotate # 轮转后执行的命令
[ -f /var/run/nginx.pid ] && kill -USR1 `cat /var/run/nginx.pid`
endscript
}kill -USR1 是通知 Nginx 重新打开日志文件。不通知的话,Nginx 会继续往已改名的旧文件里写。常用参数
| 参数 | 说明 |
|---|---|
daily / weekly / monthly | 轮转周期 |
rotate N | 保留 N 份 |
size 100M | 达到指定大小就轮转(可与 daily 同用,满足任一即触发) |
compress | 用 gzip 压缩 |
delaycompress | 延迟一轮压缩 |
nocompress | 不压缩 |
missingok | 文件不存在不报错 |
notifempty | 空文件不轮转 |
create 权限 用户 组 | 轮转后新建文件的属性 |
copytruncate | 复制后清空原文件(适用于不能发信号重开日志的程序) |
dateext | 用日期做后缀,如 access.log-20261013 |
sharedscripts | 所有日志处理完才执行一次脚本 |
postrotate/endscript | 轮转后执行的命令 |
prerotate/endscript | 轮转前执行的命令 |
su 用户 组 | 指定轮转操作的用户 |
maxage 30 | 超过 30 天的删除 |
自己写一个配置
比如给自己的应用 /var/log/myapp/*.log:
nano /etc/logrotate.d/myapp/var/log/myapp/*.log {
daily
rotate 7
size 50M
compress
delaycompress
missingok
notifempty
copytruncate
dateext
}copytruncate 的用法:程序不支持重新打开日志文件(无法发信号)时用它。原理是"复制一份再清空原文件",程序继续写原文件不受影响。缺点是可能丢失复制瞬间的少量日志。
测试与手动执行
# 调试模式(不实际执行,只显示会做什么)
logrotate -d /etc/logrotate.d/myapp
# 强制执行一次
logrotate -f /etc/logrotate.d/myapp
# 执行全部配置
logrotate -f /etc/logrotate.conf
# 查看状态记录
cat /var/lib/logrotate/status先 -d 再 -f,确认无误再让它自动跑。
logrotate 什么时候执行
由 cron 或 systemd timer 触发,通常每天一次:
cat /etc/cron.daily/logrotate
systemctl list-timers | grep logrotate四、journald 日志限制
journald 默认可能占用几个 GB,必须限制:
nano /etc/systemd/journald.conf[Journal]
SystemMaxUse=500M # 日志最多占 500M
SystemKeepFree=1G # 至少保留 1G 给系统
MaxRetentionSec=14day # 最多保留 14 天
Compress=yes # 压缩
RateLimitIntervalSec=30s # 限流(防止日志风暴)
RateLimitBurst=1000systemctl restart systemd-journald立即清理:
journalctl --disk-usage # 看占用
journalctl --vacuum-size=500M # 清理到 500M
journalctl --vacuum-time=7d # 只保留 7 天
journalctl --vacuum-files=5 # 只保留 5 个文件如果不需要持久化日志(省磁盘):
# 改成只存内存
mkdir -p /var/log/journal
# 或编辑 journald.conf:Storage=volatile五、应用日志的规范建议
1)日志写到统一目录
/var/log/myapp/
├── app.log
├── error.log
└── access.log不要把日志写到程序目录或 /tmp。
2)按级别分离
错误日志单独一个文件,方便监控和告警:
tail -f /var/log/myapp/error.log3)控制日志级别
# 生产环境不要开 DEBUG
log_level = infoDEBUG 级别的日志量可能是 INFO 的几十倍。
4)日志格式要结构化
好的日志格式:
2026-10-13 02:50:39 [ERROR] [user=123] [req=a1b2c3] 订单创建失败: 库存不足包含时间、级别、上下文(用户ID、请求ID),排查时能快速串联。
5)每个服务配 logrotate
新装一个服务就顺手加一条 logrotate 配置,别等磁盘满了再补。
六、实用排查技巧
1)统计错误出现次数
grep -c "ERROR" app.log
grep "ERROR" app.log | wc -l2)按时间过滤
sed -n '/2026-10-13 02:00/,/2026-10-13 03:00/p' app.log
awk '$1" "$2 >= "2026-10-13 02:00" && $1" "$2 <= "2026-10-13 03:00"' app.log
grep "13/Oct/2026:02:" access.log3)找访问最多的 IP
awk '{print $1}' /var/log/nginx/access.log | sort | uniq -c | sort -nr | head -204)找最慢的请求
日志格式里加了 $request_time 后:
awk '{print $NF, $7}' access.log | sort -rn | head -205)看某个 IP 的访问记录
grep "1.2.3.4" access.log | tail -506)实时监控关键字
tail -f app.log | grep --color -E "ERROR|WARN|Exception"7)多个日志同时看
tail -f /var/log/nginx/access.log /var/log/nginx/error.log或者用 multitail:
apt install multitail -y
multitail /var/log/nginx/access.log /var/log/nginx/error.log七、集中化日志(进阶)
服务器多了以后,登录每台看日志太低效。方案:
| 方案 | 复杂度 | 适合 |
|---|---|---|
| rsync 汇总到一台 | 低 | 小团队 |
| Loki + Grafana | 中 | 推荐,轻量,与 Grafana 无缝 |
| ELK(Elasticsearch+Logstash+Kibana) | 高 | 大团队,功能强但吃资源 |
| 云厂商日志服务 | 低 | 付费,省事 |
Loki 的优势:只索引标签不索引全文,资源占用远低于 ELK,2 核 4G 就能跑。
八、磁盘满了的应急处理
# 1. 看谁占的多
du -sh /var/log/* | sort -h
# 2. 清 journald
journalctl --vacuum-size=200M
# 3. 删旧的轮转日志
find /var/log -name "*.gz" -delete
find /var/log -name "*.1" -delete
find /var/log -name "*-2026*" -mtime +30 -delete
# 4. 清空当前大日志(不删文件,避免程序写失败)
: > /var/log/nginx/access.log
truncate -s 0 /var/log/huge.log
# 5. 立刻跑一次轮转
logrotate -f /etc/logrotate.conf⚠️ 不要用 rm 直接删正在写入的日志:程序持有句柄,空间不会释放,还会写失败。要用 truncate 或 copytruncate。
# 检查已删除但仍被占用的文件
lsof | grep deleted
# 处理:重启对应服务九、一份标准的日志配置
journald(/etc/systemd/journald.conf):
[Journal]
SystemMaxUse=500M
MaxRetentionSec=14day
Compress=yesNginx(/etc/logrotate.d/nginx):保留 14 天,每天轮转。
自定义应用(/etc/logrotate.d/myapp):
/var/log/myapp/*.log {
daily
rotate 14
size 100M
compress
delaycompress
missingok
notifempty
copytruncate
dateext
maxage 30
}定时巡检(crontab):
0 4 * * 0 /usr/bin/journalctl --vacuum-time=7d
0 4 * * * /usr/bin/find /var/log -name "*.gz" -mtime +30 -delete十、常见问题
| 问题 | 原因 | 解决 |
|---|---|---|
| 轮转后服务不写新日志 | 没发信号通知重开 | 加 postrotate 或改用 copytruncate |
| 日志没被轮转 | 配置路径不对 / 没被 cron 触发 | logrotate -d 调试 |
| 磁盘还是满 | journald 没限制 | 配 SystemMaxUse + --vacuum-size |
权限报错 parent directory has insecure permissions | 目录属主不对 | 加 su 用户 组 或修正目录权限 |
| 日志丢失 | copytruncate 期间的少量丢失 | 改用 postrotate 发信号 |
| 轮转后日志变成空 | 程序没重开文件句柄 | 同上 |
日志管理做好了,排查问题事半功倍。财富云计算 的云服务器提供完整 root 权限,可自由配置日志策略与监控;内网服务、游戏服务端可选 NAT 型(无独立公网 IP,价格比带独立 IP 机型省一半以上),适合长期挂服务。
相关阅读:
- 《crontab 计划任务完全指南》
- 《服务器资源排查:CPU / 内存 / 磁盘 / 带宽》
- 《Linux 磁盘挂载与扩容实战》
延伸阅读
- 网站环境怎么选:LNMP 手动 / 宝塔面板 / Docker / 云开发
- 问卷表单系统搭建:SurveyKing / Formbricks,数据自己收
- 图床搭建:Lsky Pro / Lychee,自托管图片托管方案
- 邮件列表搭建:listmonk 自托管 Newsletter,把读者握在自己手里
- 文档站点搭建:MkDocs / VuePress / Docsify,产品文档与技术手册方案
- RSS 阅读器搭建:FreshRSS 自托管,把信息流拿回自己手里
- 短链接服务搭建:Shlink 自托管,链接数据自己掌握
- 网站状态监控页搭建:Uptime Kuma,服务器挂了第一时间知道

[...]EOF日志管理全景见Linux 日志管理与 logrotate。3.4 小磁盘满导致的 IO 假死磁盘 100% 满时,很多程序会疯狂报错重试,IO 假死。先清理磁盘,再谈优化。四、不花钱的 IO 优化升级磁盘要加钱,这些手段免费:手段命令/做法收益noatime 挂载/etc/fstab 加 noatime消除读文件也写元数据的开销定时任务错峰备份、日志轮转放凌晨避开业务高峰写缓存策略数据库 i[...]
2026-10-15 回复
[...]sudo ausearch -k passwd_changes -i输出示例:type=SYSCALL msg=... arch=c000003e syscall=openat success=yes ... exe="/usr/sbin/useradd" key="passwd_changes"规则持久化写到 /etc/audit/rules.d/audi[...]
2026-10-15 回复
[...]> /proc/<PID>/fd/<FD号> # 向被删文件的句柄写空,瞬间释放根治:日志交给 logrotate 管理,用 create 或 copytruncate 模式,别手动删活动日志。完整配置见Linux 日志管理与 logrotate。四、根治:三层防线4.1 logrotate 管日志sudo tee /etc/logrotate.d/webst[...]
2026-10-15 回复
[...]netsh advfirewall firewall add rule name="GameRange" dir=in action=allow protocol=UDP localport=26901-26903完整的 Windows 环境准备(远程桌面连接、运行库安装、SteamCMD 用法、开机自启、8 个常见坑)见:《Windows 云服务器开服通用前置教程》→ htt[...]
2026-10-18 回复