适用:systemd 系统 耗时:约 30 分钟 前置:E2(认识服务)
D7 教过你"日志在 /var/log,用 journalctl 看"。这一篇教**“看懂了之后怎么办”**。
核心方法只有一句:从最后一条错误往前读,找到"第一次出现异常"的那一行。
一、先建立正确的心态
报错不是给你看的,是给程序看的
日志里 90% 的行是噪音。你的任务不是读完,是找到那一条关键的。
关键行一般有这些特征:
- 含
error/fail/cannot/unable/denied/refused/timeout - 是某个正常序列被打断的第一条
- 出现得比其它错误早(后面的错误往往是它引起的连锁反应)
“最后一行"通常是错的定位点
新手习惯看最后一行。但最后一行往往是结果,不是原因。
举例:
12:00:01 INFO Connecting to database...
12:00:01 ERROR Connection refused
12:00:02 ERROR Failed to initialize app
12:00:02 FATAL Shutting down
最后一行是 “Shutting down”——毫无信息。真正的答案是第一行 ERROR:Connection refused。
二、journalctl 的正确用法
定位服务的日志
journalctl -u nginx # 全部
journalctl -u nginx -n 50 # 最近 50 行
journalctl -u nginx -f # 实时跟踪(Ctrl+C 退出)
journalctl -u nginx --since "10 min ago"
journalctl -u nginx --since today
journalctl -u nginx -p err # 只要 error 级别以上
组合起来用(最实用的一条)
journalctl -u 服务名 -n 100 --no-pager | grep -iE "error|fail|cannot|unable|denied|refused|timeout"
先过滤出关键行,再上下看上下文。
看本次启动的所有错误
journalctl -b -p err
journalctl -b -1 -p err # 上一次启动的(排查"上次怎么挂的")
journalctl --list-boots # 列出所有启动记录
看某个时间段的
journalctl --since "2026-10-20 12:00" --until "2026-10-20 13:00"
三、/var/log/ 里有什么
ls -lh /var/log/
| 文件 | 内容 | 什么时候看 |
|---|---|---|
syslog 或 messages | 系统综合 | 什么都查不到时 |
auth.log 或 secure | 登录、sudo | 密码错、账号被锁、SSH 被爆破 |
dpkg.log | 装软件历史 | 装完就坏了 |
Xorg.0.log | 图形界面 | 黑屏、花屏、进不去桌面 |
kern.log | 内核 | 硬件、驱动、磁盘报错 |
nginx/ | nginx 自己的 | 网站 502 / 404 |
mysql/ postgresql/ | 数据库 | 连不上数据库 |
注意:用 journalctl 的系统和用 /var/log 的系统可能同时存在。journalctl 优先,查不到再去 /var/log。
四、五个真实案例:从日志到答案
这一节是全篇最有用的部分。看懂这五个,你就能处理大部分情况。
案例 1:服务起不来 —— 端口被占
systemctl status myapp
Active: failed (Result: exit-code)
myapp[1234]: Error: listen EADDRINUSE: address already in use :::8080
日志说得很清楚:8080 被占了。
sudo ss -ltnp | grep 8080
找到占用的进程 → 停掉它,或者改 myapp 的端口。
答案:端口冲突。
案例 2:网站 502 Bad Gateway
nginx 的 502 意思是"我把请求转给后端了,但后端没理我”。
sudo tail -n 50 /var/log/nginx/error.log
connect() failed (111: Connection refused) while connecting to upstream
翻译:nginx 去连后端的 8000 端口,被拒绝(说明后端根本没在跑)。
sudo ss -ltnp | grep 8000 # 确认后端不在
sudo systemctl start 后端服务 # 起来就好了
答案:后端服务挂了,不是 nginx 的问题。
502 的排查顺序:① 后端在跑吗 ② 后端端口对吗 ③ 后端能否本机访问(
curl 127.0.0.1:8000)④ 防火墙
案例 3:SSH 登不上
sudo tail -n 30 /var/log/auth.log # Debian 系
sudo tail -n 30 /var/log/secure # RPM 系
三种典型输出,对应三种原因:
Failed password for root from 1.2.3.4 → 密码错(或被爆破)
Invalid user admin from 1.2.3.4 → 用户在系统里根本不存在
Connection closed by authenticating user → 密钥不对 / 权限问题
第三种最常见:私钥文件权限太宽:
ls -l ~/.ssh/id_rsa
# 应该是 -rw-------(600)
chmod 600 ~/.ssh/id_rsa
SSH 拒绝使用权限过宽的私钥——这是安全设计,不是 bug。
案例 4:磁盘莫名满了
df -h
/ 显示 100%。然后:
sudo du -sh /var/log/* | sort -h | tail -5
sudo du -sh /var/* | sort -h | tail -5
常见元凶:
# 1. 日志爆炸(某个服务在疯狂写日志)
sudo journalctl --disk-usage
sudo journalctl --vacuum-size=500M
# 2. 已删除但被进程占用的文件(df 说满,du 找不到)
sudo lsof +L1 # 找 deleted 但仍被打开的文件
# 重启那个进程就会释放
# 3. docker 镜像
docker system df
docker system prune -a
第 2 条最容易让人抓狂:
df说 100%,du加起来只有 30%。因为有个 5GB 的日志文件被rm了,但写它的进程还开着 → 空间没释放。lsof +L1就是专门找这个的。
案例 5:开机进不去桌面
# Ctrl+Alt+F3 进文字终端,登录后
journalctl -b -p err -n 50
# 图形界面专门的日志
cat ~/.local/share/xorg/Xorg.0.log | grep -iE "error|fail" | tail -20
# 或者
grep -iE "\(EE\)" /var/log/Xorg.0.log
(EE) 是 Xorg 里错误级别的标记。如果 Xorg 日志里全是 (EE) 关于 GPU,就是显卡驱动问题:
sudo apt remove --purge nvidia-* # 卸掉有问题的驱动
reboot
如果日志里说 No space left on device → 磁盘满了,见案例 4。
五、日志分析的通用四步法
不管什么场景,按这个走:
第 1 步:确定哪个组件出问题
(是系统?某个服务?还是某个应用?)
↓
第 2 步:找到对应的日志
(journalctl -u 服务名 / /var/log/xxx.log)
↓
第 3 步:过滤 + 看上下文
(grep 关键词,然后看它前后各 5 行)
↓
第 4 步:把报错翻译成人话
("Connection refused" = 对面没在听;
"Permission denied" = 权限不够;
"No such file" = 路径错;
"No space left" = 磁盘满)
常见报错的"人话翻译表"
| 英文 | 人话 | 先查什么 |
|---|---|---|
Connection refused | 对面端口没开 | 服务在跑吗、端口对吗 |
Connection timed out | 网络不通 / 被防火墙拦 | ping、nc -zv host port |
Permission denied | 权限不够 | ls -l、namei -l |
No such file or directory | 路径错 | 文件真的在那吗 |
No space left on device | 磁盘满 | df -h |
Address already in use | 端口被占 | ss -ltnp |
Too many open files | 打开文件数超限 | ulimit -n |
Cannot allocate memory | 内存不够 | free -h |
Operation not permitted | 权限/属性锁 | sudo、lsattr |
Could not resolve host | DNS 解析不了 | cat /etc/resolv.conf、nslookup |
这张表建议存下来。 90% 的报错都能对上一个。
六、让日志更好用的三个技巧
1. 看上下文,不是只看一行
grep -A 5 -B 5 "error" 日志文件 # 前后各 5 行
-A = after,-B = before。报错前后往往有导致它发生的关键信息。
2. 数一下出现次数
grep -c "error" 日志文件 # 总共几次
grep "error" 日志文件 | sort | uniq -c | sort -rn | head # 哪类错最多
“同一个错误出现 3000 次"和"出现 1 次"是完全不同的问题。
3. 时间对齐
出问题的时间点你往往知道(“我刚才点了一下就崩了”)。用时间过滤,能砍掉 95% 的噪音:
journalctl --since "12:30" --until "12:35" -p err
七、验证:你过关了吗
- 会用
journalctl -u 服务名 -n 50查服务日志 - 会用
grep -A/-B看上下文 - 知道"最后一行往往不是原因”
- 能看懂
Connection refused/Permission denied/No space left分别该查什么 - 知道 502 该按什么顺序排查
- 知道
df满了但du找不到时用lsof +L1
八、不行怎么办
Q1:journalctl 报 No journal files were found
系统用的是传统 syslog:
tail -n 100 /var/log/syslog # Debian 系
tail -n 100 /var/log/messages # RPM 系
Q2:日志文件太大,打不开
别用 cat。 用:
less 大文件.log # 分页
tail -n 500 大文件.log # 只看最后
grep 关键词 大文件.log # 直接过滤
Q3:/var/log 里没有我要的日志
有些服务自己管日志,在别处:
# 找这个服务的配置里 log 相关设置
systemctl cat 服务名 | grep -i log
ls /var/log/服务名/
ls ~/.config/软件名/logs/
Q4:日志里全是时间戳,看不出哪行重要
用 -p err 只留错误级别:
journalctl -p err -n 50
Q5:查了半天还是不知道啥问题 用 D7 的"信息收集脚本"把 8 项备齐,然后把日志原文贴出去问(贴原文,别转述)。
九、一句话总结
日志不是用来读完的,是用来找到那一行的。
从第一条错误往前找原因,别盯着最后一行看结果。
← 上一篇 E2|进程与服务 下一篇 → E4|网络排查:网不通到底不通在哪