Linux 系统诊断与日志
Linux 系统诊断与日志
目录
- 日志体系概览:systemd journal 与 rsyslog
- 系统日志:journalctl 查询(journalctl -u)
- 内核日志:dmesg 查看启动与硬件信息
- 负载与登录:uptime / w / who / last / lastb
- 资源查看:free / df / top
- 日志轮转:logrotate(防止日志撑满磁盘)
- 实战排障:系统变慢了怎么排查(踩坑文)
- 总结与练习
一、日志体系概览:systemd journal 与 rsyslog
现代 Linux(Rocky/RHEL、Ubuntu 等)的日志由两套系统协作:
- systemd journal:systemd 自带的日志系统,把各服务的输出集中采集到二进制日志中,用
journalctl查看。日志默认存内存(/run/log/journal),可配置为持久化(/var/log/journal)。 - rsyslog:传统的文本日志系统,把日志写到
/var/log/下的文本文件(如/var/log/messages、/var/log/secure)。
服务输出 → systemd-journald → journalctl(二进制)
↘ rsyslog → /var/log/messages 等文本日志
实际使用:现代排障优先用 journalctl(信息更全、方便过滤);传统文本日志(如 /var/log/messages)仍在 Red Hat 系存在,适合用 tail -f、grep 直接看。
参考:Red Hat - 使用 journalctl、DigitalOcean - systemd Journal 与 journalctl
二、系统日志:journalctl 查询(journalctl -u)
journalctl 是查看 systemd journal 日志的命令,功能强大。
2.1 基本查看
journalctl # 查看全部日志(量大,建议配合过滤)
sudo journalctl -f # 实时跟踪新日志(类似 tail -f)
sudo journalctl -n 50 # 只看最后 50 行(-n lines)
sudo journalctl -b # 本次启动的日志(-b boot)
sudo journalctl -b -1 # 上一次启动的日志
2.2 按服务过滤(journalctl -u)
-u 指定 unit(服务),是排障最常用的过滤方式:
sudo journalctl -u httpd # 查看 httpd 服务的日志
sudo journalctl -u httpd -f # 实时跟踪 httpd 日志
sudo journalctl -u httpd -n 100 # 只看 httpd 最后 100 行
sudo journalctl -u sshd -u crond # 同时查看多个服务
sudo journalctl -u httpd --since "1 hour ago" # 最近 1 小时
2.3 按时间过滤(--since / --until)
sudo journalctl --since "2026-01-01 10:00:00"
sudo journalctl --since "30 min ago"
sudo journalctl --since yesterday --until today
sudo journalctl --since "2026-01-01" --until "2026-01-02"
sudo journalctl -u httpd --since today # 服务 + 时间组合
2.4 按级别过滤(-p priority)
日志有 8 个优先级(从高到低):
| 级别 | 数字 | 含义 |
|---|---|---|
| emerg | 0 | 系统不可用 |
| alert | 1 | 必须立即处理 |
| crit | 2 | 严重错误 |
| err | 3 | 错误 |
| warning | 4 | 警告 |
| notice | 5 | 正常但重要 |
| info | 6 | 信息(默认) |
| debug | 7 | 调试 |
sudo journalctl -p err # 只看 err 及以上(更严重)的日志
sudo journalctl -p warning -u httpd # 服务的 warning 及以上
sudo journalctl -p 3 # 数字写法等价(3=err)
2.5 其他常用过滤
sudo journalctl -u httpd --since today -p warning # 组合过滤
sudo journalctl -k # 只显示内核日志(等价 dmesg)
sudo journalctl --no-pager # 不分页直接输出(便于管道)
sudo journalctl -o json-pretty # JSON 格式输出
sudo journalctl --disk-usage # 查看 journal 占用磁盘大小
sudo journalctl --vacuum-size=200M # 清理 journal 到 200M 以内
排障技巧:先
journalctl -u 服务 --since today -p warning快速定位问题,再展开到-p info看细节。
参考:
man 1 journalctl、菜鸟教程 - Linux journalctl
三、内核日志:dmesg 查看启动与硬件信息
dmesg 读取内核环形缓冲区(kernel ring buffer),显示内核启动过程和硬件相关的消息,排障时用于查看硬件识别、驱动、磁盘、内存等。
3.1 基本用法
dmesg # 输出内核日志(量大)
sudo dmesg -H # 人类可读、分页显示(-H human)
sudo dmesg -T # 显示可读时间戳(-T time,否则是秒数)
sudo dmesg -l err # 只显示 err 级别
sudo dmesg -l err,warn # 只看错误和警告
sudo dmesg | tail -50 # 看最后 50 行(最近的硬件/驱动信息)
3.2 常用排障场景
# 查看磁盘设备识别
sudo dmesg | grep -i sd
sudo dmesg | grep -i "disk\|sda"
# 查看内存信息
sudo dmesg | grep -i memory
sudo dmesg | grep -i "out of memory" # 找 OOM 内存不足
# 查看 USB 设备
sudo dmesg | grep -i usb | tail -20
# 查看网卡
sudo dmesg | grep -i "eth\|nic\|link"
# 查看是否有硬件/驱动错误
sudo dmesg | grep -iE "error|fail|fault" | tail -30
dmesg主要用于查看硬件识别、驱动加载、I/O 错误、OOM等信息。- 开机后的 dmesg 会滚动更新,
-T显示时间便于定位。 - 等价命令:
journalctl -k也能看内核日志。
参考:
man 1 dmesg、菜鸟教程 - Linux dmesg
四、负载与登录:uptime / w / who / last / lastb
4.1 uptime —— 系统运行时间与负载
uptime
# 输出: 10:20:30 up 3 days, 2:15, 3 users, load average: 0.30, 0.45, 0.52
up 3 days, 2:15:系统已运行时长。load average: 0.30, 0.45, 0.52:过去 1/5/15 分钟的平均负载(排队等待 CPU 的进程数)。- 判断:负载接近或超过 CPU 核数说明 CPU 繁忙;持续过高需排查(见第七章)。
4.2 w —— 谁在登录、在做什么
w
w -h
- 显示当前登录用户、登录时间、所在终端、以及每条命令的 CPU/负载。
- 排障时用
w看"谁在跑什么占资源"很有用。
4.3 who —— 当前登录用户
who # 当前谁登录了
who -b # 上次开机时间
who -r # 当前运行级别
whoami # 我是谁
4.4 last / lastb —— 登录历史
last # 查看成功登录的历史(读取 /var/log/wtmp)
last -n 20 # 只看最近 20 条
last root # 查看某用户的登录记录
sudo lastb # 查看失败的登录尝试(读取 /var/log/btmp,需 root)
sudo lastb -n 20 # 最近失败的登录
last显示成功登录记录(含重启记录 reboot)。lastb显示失败登录,可用于排查暴力破解(大量失败尝试 = 被扫描/攻击)。- 对应文件:成功登录
/var/log/wtmp,失败登录/var/log/btmp。
参考:
man 1 uptime、man 1 w、man 1 who、man 1 last、man 1 lastb、菜鸟教程 - Linux 用户登录命令
五、资源查看:free / df / top
5.1 free —— 内存
free -h # 人类可读显示内存和 swap
free -h -s 2 # 每 2 秒刷新一次
输出关键项:
| 列 | 含义 |
|---|---|
| total | 总内存 |
| used | 已用内存 |
| free | 完全空闲内存 |
| buff/cache | 缓存(可被回收) |
| available | 真正可用内存(≈ free + 可回收缓存) |
| swap used | 交换分区使用 |
判断内存是否不足:看
available(不是 used)。Linux 会用空闲内存做缓存,所以used高是正常的;available很低且swap used持续增长才说明内存紧张。
5.2 df —— 磁盘
df -h # 查看所有挂载的文件系统使用率
df -h / # 查看根分区
df -i # 查看 inode 使用率
df -hT # 显示文件系统类型
df -h看磁盘空间是否被占满(Use% 接近 100% 会导致系统异常)。df -i看 inode 是否耗尽(inode 满会导致无法创建文件,即使有空间)。
5.3 top —— 综合负载
top
top -o %MEM # 按内存排序
top -o %CPU # 按 CPU 排序
- 上半部分看系统负载、CPU、内存;下半部分看进程占用。
- 排障时按
P看 CPU 最高、M看内存最高的进程,快速定位"谁在吃资源"。 - 详细解读见《进程管理》文档的 top 章节。
参考:
man 1 free、man 1 df、man 1 top、菜鸟教程 - Linux free/df/top
六、日志轮转:logrotate(防止日志撑满磁盘)
日志会持续增长,若不处理会撑满磁盘导致系统异常。logrotate 定期对日志进行轮转(rotate):把旧日志改名、压缩、删除,只保留一定数量。
6.1 配置位置
- 主配置:
/etc/logrotate.conf。 - 各软件自己的配置:
/etc/logrotate.d/下的独立文件(每服务一个)。
ls /etc/logrotate.d/ # 查看各服务的日志轮转配置
cat /etc/logrotate.d/httpd
6.2 配置文件常用指令
/var/log/messages {
weekly # 每周轮转(也可 daily/monthly)
rotate 4 # 保留 4 份旧日志
compress # 压缩旧日志(gzip)
missingok # 日志不存在也不报错
notifempty # 日志为空则不轮转
create 0600 root root # 轮转后新建日志文件的权限
}
常用指令:
| 指令 | 作用 |
|---|---|
| daily / weekly / monthly | 轮转周期 |
| rotate N | 保留 N 份旧日志 |
| compress | 压缩旧日志(.gz) |
| missingok | 日志缺失不报错 |
| notifempty | 空日志不轮转 |
| size 100M | 超过 100M 就轮转(与周期二选一) |
| maxsize 100M | 超过 100M 或到周期就轮转 |
| create mode user group | 轮转后重建新日志 |
| copytruncate | 复制后清空原日志(用于无法重启的服务) |
| postrotate / endscript | 轮转后执行命令(如重载服务) |
6.3 手动触发与查看
sudo logrotate -f /etc/logrotate.conf # 强制执行轮转(-f force)
sudo logrotate -d /etc/logrotate.conf # 调试模式(只显示会做什么,不实际执行)
sudo logrotate -v /etc/logrotate.conf # 显示执行过程
cat /var/lib/logrotate/logrotate.status # 查看上次轮转状态
注意:logrotate 由 cron(或 systemd timer)定时触发,默认每日运行。修改配置后可用
-f立即验证。
- journal 本身的轮转/清理:journald 也需管理,防止
/var/log/journal无限增长。
sudo journalctl --disk-usage # 查看 journal 占用
sudo journalctl --vacuum-size=200M # 清理到 200M 以内
sudo journalctl --vacuum-time=7d # 只保留最近 7 天
参考:
man 8 logrotate、man 5 logrotate.conf、Red Hat - logrotate
七、实战排障:系统变慢了怎么排查(踩坑文)
这是一篇"系统变慢"的真实排障思路,串起日志 + 负载 + 资源查看。按下面顺序排查,能覆盖大多数"慢"的问题。
7.1 第一步:先看整体概况
uptime # 看负载:1/5/15 分钟是否持续很高
top # 按 P 看 CPU 最高进程,按 M 看内存最高进程
free -h # 看内存 available 是否紧张、swap 是否被大量使用
df -h # 看磁盘是否被占满(Use% 高)
df -i # 看 inode 是否耗尽
这一步能快速定位大概方向:CPU 高 / 内存不足 / 磁盘满,三者排障路径不同。
7.2 第二步:看是不是 CPU 被占满
top # %Cpu 里 id 很低说明 CPU 忙
uptime # 负载 > CPU 核数说明 CPU 过载
top -o %CPU | head # 看哪个进程吃 CPU
- 若某个进程 CPU 长期 100%,可能被写死循环或挖矿;若整体 CPU 忙但无单进程高,可能是进程数过多或负载超卖。
7.3 第三步:看是不是内存不足
free -h # available 很低、swap 持续增长 = 内存不足
sudo dmesg | grep -i "out of memory" # 查是否有 OOM 被杀
sudo journalctl -k | grep -i "oom\|killed" # 内核 OOM 记录
top -o %MEM | head # 看哪个进程吃内存
- 内存不足时系统会频繁换页(swap),表现就是"很卡"。
- 大量进程被 OOM Killer 杀掉,说明内存严重不足。
7.4 第四步:看是不是磁盘/IO 慢
df -h # 磁盘满会导致写入卡顿
df -i # inode 满无法创建文件
top # wa(iowait)高说明磁盘 IO 慢
sudo dmesg | grep -i "error\|i/o" | tail # 看磁盘 I/O 错误
top里 wa(iowait) 持续很高,说明 CPU 在等磁盘 I/O,通常是磁盘慢、磁盘故障或日志刷盘频繁。
7.5 第五步:查日志找"事故现场"
# 看最近错误日志
sudo journalctl -p warning --since today
sudo journalctl -p err -u httpd --since today
# 看内核错误
sudo journalctl -k -p err --since today
# 看系统主日志尾部
sudo tail -f /var/log/messages
7.6 第六步:查登录与安全(排除被入侵/挖矿)
sudo lastb | head # 看是否有大量失败登录(暴力破解)
w # 看是否有可疑用户在跑任务
top # 看是否有陌生高占用进程
ps aux | sort -k3 -r | head # 按 CPU 排序看进程
- 若发现陌生进程占用极高,可能是被入侵挖矿,需检查可疑进程、定时任务、登录。
7.7 踩坑小结:常见"慢"的原因
| 现象 | 可能原因 | 排查命令 |
|---|---|---|
| 负载高、CPU 满 | 死循环进程 / 挖矿 / 进程过多 | top、uptime |
| available 低、swap 增长 | 内存不足 | free -h、dmesg 查 OOM |
| wa 高、操作卡 | 磁盘慢/故障/日志刷盘 | top、df -h、dmesg |
| Use% 100% | 磁盘满 | df -h |
| inode 满 | 小文件过多 | df -i |
| 频繁重启、登录异常 | 被入侵/挖矿 | lastb、w、top |
一句话:系统变慢,先 top 看 CPU/内存/wa,再 df/free 看资源,最后用 journalctl/dmesg 查日志定位根因。
八、总结与练习
8.1 核心速查
| 需求 | 命令 |
|---|---|
| 查看某服务日志 | journalctl -u 服务 |
| 按时间过滤 | journalctl --since "1 hour ago" |
| 按级别过滤 | journalctl -p err |
| 实时看日志 | journalctl -f |
| 内核日志 | dmesg -T / journalctl -k |
| 系统负载 | uptime |
| 谁在登录/在干嘛 | w、who |
| 成功/失败登录 | last、lastb |
| 内存 | free -h |
| 磁盘/inode | df -h、df -i |
| 综合负载 | top |
| 手动轮转日志 | logrotate -f /etc/logrotate.conf |
| 清理 journal | journalctl --vacuum-size=200M |
8.2 动手练习建议
# 1. 查看当前系统概况
uptime; free -h; df -h; top
# 2. 看服务日志
sudo journalctl -u sshd --since today
sudo journalctl -u sshd -p warning --since today
# 3. 看内核与硬件
sudo dmesg -T | tail -30
sudo dmesg | grep -i "disk\|sda" | tail
# 4. 登录情况
last -n 10
sudo lastb -n 10
# 5. 日志轮转
cat /etc/logrotate.d/sshd
sudo logrotate -d /etc/logrotate.conf # 调试看看会做什么
# 6. 排障演练:模拟高 CPU
yes > /dev/null & # 一个占满 CPU 的进程
top # 看它排在第一位
kill %1 # 结束它
提示:排障练习请在虚拟机中进行。
journalctl、lastb、dmesg部分命令需要sudo权限。
参考资料
- man 手册:
man 1 journalctl、man 1 dmesg、man 1 uptime、man 1 w、man 1 who、man 1 last、man 1 free、man 1 df、man 1 top、man 8 logrotate、man 5 logrotate.conf - Red Hat 官方文档:https://docs.redhat.com/
- Rocky Linux 官方文档:https://docs.rockylinux.org/
- DigitalOcean - journalctl 使用:https://www.digitalocean.com/community/tutorials/how-to-use-journalctl-to-view-and-manipulate-systemd-logs
- 菜鸟教程 - Linux 命令大全:https://www.runoob.com/linux/linux-command-manual.html
