大家好,我是冯哥的缓存。上一篇聊了进程管理——知道系统里在跑什么。今天进一步:系统发生了什么,靠的就是日志。
Linux 几乎把所有发生过的事情都记录下来了:服务启动失败了、有人尝试爆破 SSH、内核检测到了硬盘错误、应用崩溃了……查日志是排查问题的最终武器,很多时候一眼就能看到原因。
💡提示:本文所有命令在 Ubuntu 22.04 / Debian 12 / Fedora 38 / Arch Linux 下验证。
一、Linux 有几套日志系统?
很多人以为Linux 日志就是/var/log里那些文件,其实现代 Linux 有两套并存的日志系统:
日志系统 | 谁在用 | 存储位置 | 查看工具 |
systemd-journald | 现代 Linux(Ubuntu 16+、CentOS 7+、Arch 等) | 二进制文件(默认 /run/log/journal/,持久化后 /var/log/journal/) | journalctl |
传统 syslog | rsyslog / syslog-ng 守护进程 | 文本文件 /var/log/ | cat、less、grep、tail |
两套不冲突,通常同时存在。journald 抓 systemd 管的所有服务日志;rsyslog 把部分日志再写一份到/var/log/的文本文件里。rsyslog 是大多数 Linux 发行版的默认 syslog 实现,syslog-ng 是一个替代方案,在部分企业环境中使用。
二、journalctl查系统日志
2.1 基础用法
# 查看全部日志(按时间倒序,最新在下)
journalctl
# 实时追踪新日志(类似 tail -f)
journalctl -f
# 只看最近 100 行
journalctl -n 100
# 以更紧凑的格式输出
journalctl --no-pager
journalctl不加任何参数会打开交互翻页器(按 q退出,/关键词搜索,G跳到末尾),日志量大的时候翻起来不太方便,加 --no-pager直接输出到终端。如果日志量很大,建议用 journalctl | less 配合 less 的搜索功能,比默认翻页器更顺手。
2.2 按时间过滤
# 今天的日志
journalctl --since today
# 昨天
journalctl --since yesterday
# 指定时间范围
journalctl --since "2026-07-01 08:00:00" --until "2026-07-01 10:00:00"
# 最近 30 分钟
journalctl --since "30 min ago"
# 最近 1 小时
journalctl --since "1 hour ago"
2.3 按服务过滤
这是常用的操作——某个服务有问题,直接看它的日志:
# 查看 nginx 的日志
journalctl -u nginx
# 查看 sshd 的日志
journalctl -u sshd
# 实时追踪 mysql 日志,如果 -u mysql 不生效,试试 -u mysqld
journalctl -u mysql -f
# 结合时间过滤
journalctl -u nginx --since "1 hour ago"
-u后面跟服务名(就是 systemctl status里显示的那个名字,不带 .service后缀也行)。
2.4 按优先级过滤
日志有 8 个优先级(数字越小越严重):
日常排查时,-p warning 是个不错的起点,可以过滤掉 info 噪音,又不会漏掉警告。
# 只看 error 及以上级别(err、crit、alert、emerg)
journalctl -p err
# 只看 warning 及以上
journalctl -p warning
# 今天的所有错误
journalctl -p err --since today
过滤掉info/debug 噪音,只盯着错误看,排查问题效率高很多。
2.5 按进程或关键词过滤
# 按 PID 查
journalctl _PID=1234
# 按可执行文件路径
journalctl _EXE=/usr/bin/python3
# 管道 grep 搜关键词
journalctl -u sshd | grep "Failed"
# 只显示包含某关键词的行
journalctl -g "error"
2.6 启动日志排查
# 查看上次启动的日志(-b 0 表示本次,-b -1 表示上次)
journalctl -b
# 查看上次启动的日志
journalctl -b -1
# 查看这次启动的内核日志
journalctl -b -k
# 列出所有有记录的启动
journalctl --list-boots
电脑开机后某个服务启动失败,用journalctl -b从头找本次启动的错误非常有效。
2.7 日志存储与持久化
Ubuntu 22.04+ 已默认持久化,旧版本默认情况下,journald 的日志存在内存里(/run/log/journal/),重启就没了。要让日志持久保存:
# 创建持久化目录
sudo mkdir -p /var/log/journal
# 让 journald 重新读配置
sudo systemctl restart systemd-journald
# 验证:现在日志会保存到/var/log/journal/
ls /var/log/journal/
也可以直接编辑配置文件/etc/systemd/journald.conf,把 Storage=auto改成 Storage=persistent,然后重启 journald。
2.8 控制日志占用空间
# 查看日志当前占用多少空间
journalctl --disk-usage
# 只保留最近 2 周
journalctl --vacuum-time=2w
# 只保留最多 500MB
journalctl --vacuum-size=500M
# 两个条件都限
journalctl --vacuum-time=2w --vacuum-size=500M
上一篇磁盘清理里提过这个操作,配合 cron 定期跑一下,防止日志把磁盘撑满。
三、/var/log目录结构
传统文本日志住在/var/log/里,每个文件对应一类事件:
ls /var/log/
3.1 重要日志文件速查表
文件/目录 | 记录内容 | 查看方式 |
syslog 或 messages | 系统通用消息(Ubuntu 用 syslog,CentOS 用 messages) | tail -f /var/log/syslog |
auth.log 或 secure | 认证事件:SSH 登录、sudo 使用(Ubuntu/Debian 用 auth.log,CentOS/RHEL 用 secure) | grep "Failed" /var/log/auth.log |
kern.log | 内核消息(硬件错误、驱动问题) | tail /var/log/kern.log |
dmesg 或 dmesg.0 | dmesg 命令查看实时内核缓冲,/var/log/dmesg.0 是上次启动的存档 | dmesg 命令或直接 cat |
dpkg.log | apt/dpkg 软件包安装记录 | grep "install" /var/log/dpkg.log |
apt/history.log | apt 命令执行历史 | cat /var/log/apt/history.log |
nginx/access.log | Nginx 访问日志 | tail -f /var/log/nginx/access.log |
nginx/error.log | Nginx 错误日志 | tail -f /var/log/nginx/error.log |
mysql/error.log | MySQL 启动和错误记录 | tail /var/log/mysql/error.log |
cron.log 或 syslog(含 CRON) | cron 任务执行记录 | grep CRON /var/log/syslog |
boot.log | 系统启动各服务启停记录 | cat /var/log/boot.log |
faillog | 登录失败记录(二进制) | faillog -a 命令查看 |
wtmp | 用户登录/注销记录(二进制) | last 命令查看 |
btmp | 失败的登录尝试(二进制) | lastb 命令查看 |
lastlog | 每个用户最后登录时间(二进制) | lastlog 命令查看 |
⚠️注意: Ubuntu/Debian 和 CentOS/RHEL 的日志文件名有差异,主要区别在 syslog vs messages、auth.log vs secure。/var/log/syslog 是 rsyslog 从 journald 里捞出一部分写的,并不是所有日志都落在这里。
3.2 dmesg——内核消息
dmesg不是一个文件,而是一个命令,读取内核的环形缓冲区(Ring Buffer):
# 查看所有内核消息
dmesg
# 实时追踪(需要 root)
dmesg -w
# 只看错误和警告
dmesg -l err,warn
# 加时间戳(人类可读格式)
dmesg -T
# 查最新的 20 条
dmesg | tail -20
# 查和 USB 相关的消息
dmesg | grep -i usb
# 查和硬盘相关的
dmesg | grep -i "error\|fail\|sda\|nvme"
插了 U 盘识别不了、硬盘有坏扇区、驱动加载失败——第一个要看的就是dmesg。
四、logrotate——日志自动轮转
如果日志文件不加管理,syslog 一个文件可能会长到几 GB。logrotate是Linux 标准的日志轮转工具,自动压缩、归档、删除旧日志。
4.1 配置文件在哪
# 主配置文件
/etc/logrotate.conf
# 各服务的独立配置(在这个目录里)
/etc/logrotate.d/
ls /etc/logrotate.d/
每个应用在/etc/logrotate.d/里放一个配置文件,告诉 logrotate 怎么处理它的日志。
4.2 配置示例解读
以/etc/logrotate.d/nginx为例:
/var/log/nginx/*.log {
daily# 每天轮转
missingok# 日志文件不存在时不报错
rotate 14# 保留 14 份旧日志
compress# 压缩旧日志(gzip)
delaycompress# 最新的旧日志不压缩(方便排查昨天的问题)
notifempty# 日志为空时不轮转
create 640 www-data adm# 新日志文件的权限和所有者
sharedscripts
postrotate
# 轮转后让 nginx 重新打开日志文件
/bin/kill -USR1 `cat /var/run/nginx.pid 2>/dev/null` 2>/dev/null
endscript
}
常用指令速查:
指令 | 含义 |
daily / weekly / monthly | 轮转频率 |
rotate N | 保留 N 份旧日志 |
compress | 压缩旧日志(.gz) |
delaycompress | 最新一份旧日志不压缩 |
maxsize 100M | 超过 100MB 就轮转,不管时间 |
minsize 10M | 小于 10MB 不轮转 |
missingok | 文件不存在不报错 |
notifempty | 空文件不轮转 |
create 644 user group | 新建日志文件的权限 |
postrotate ... endscript | 轮转后执行的命令 |
# 如果改了配置,立即生效测试
sudo logrotate -f /etc/logrotate.d/服务名
4.3 手动测试 logrotate
# 测试运行(不实际执行,只看会怎么做)
sudo logrotate -d /etc/logrotate.conf
# 强制轮转(不管是否到时间)
sudo logrotate -f /etc/logrotate.d/nginx
# 查看上次运行状态
cat /var/lib/logrotate/status
五、实战排错场景
场景一:服务启动失败,找原因
# 先看服务状态
sudo systemctl status nginx
# 看到错误,再深挖日志
journalctl -u nginx -n 50 --no-pager
# 看本次启动里 nginx 相关的所有日志
journalctl -b -u nginx
实际案例:nginx启动失败,systemctl status显示 "failed",journalctl -u nginx一看,报 "Address already in use"——端口被占用了。
场景二:SSH 爆破检测
# 看有多少次 SSH 登录失败
grep "Failed password" /var/log/auth.log | wc -l
# 看是哪些 IP 在攻击
grep "Failed password" /var/log/auth.log | grep -oP "from \K[\d.]+" | sort | uniq -c | sort -rn | head -20
# 如果 -P 不生效,用 sed 或 awk 替代。
# 看成功登录的记录
grep "Accepted password\|Accepted publickey" /var/log/auth.log
# 用 last 看最近登录列表
last -n 20
# 用 lastb 看失败尝试
sudo lastb -n 20
如果发现某个IP 失败次数几千次,可以考虑用ufw deny from [IP]封掉它,或者装 fail2ban 自动处理。
场景三:系统突然重启/崩溃,查原因
# 看上次关机时间
last reboot | head -5
# 查看上次启动之前的日志(-b -1 = 上次启动)
journalctl -b -1 -p err
# 看有没有 OOM(内存不足强制杀进程)记录
journalctl -b -1 | grep -i "out of memory\|oom"
# 看内核崩溃记录
journalctl -b -1 -k | grep -i "bug\|oops\|panic\|error"
# 也可以看 /var/log/kern.log
grep -i "error\|warn\|fail" /var/log/kern.log | tail -50
场景四:硬盘/硬件故障预排查
# 看内核有没有记录硬盘错误
dmesg -T | grep -i "error\|fail\|reset\|ata\|nvme" | tail -30
# 看最近的硬件相关日志
journalctl -k -p err --since "1 week ago"
# 查 SMART 硬盘健康状态(需要安装 smartmontools)
sudo apt install smartmontools
sudo smartctl -a /dev/sda
# smartctl 需要先安装 smartmontools,且部分云服务器(如 AWS)可能不支持此命令。
dmesg里出现 I/O error、read error、sector、ECC error这类关键词,硬盘可能快坏了,赶紧备份。
场景五:找出谁用了 sudo
# 查 sudo 使用记录
grep "sudo:" /var/log/auth.log
# 更直接
grep "sudo:" /var/log/auth.log | grep "COMMAND"
六、常用日志排查命令速查表
journalctl 常用参数
命令 | 用途 |
journalctl -f | 实时追踪 |
journalctl -n 50 | 最近 50 行 |
journalctl -u 服务名 | 某服务的日志 |
journalctl -p err | 只看错误 |
journalctl -b | 本次启动的日志 |
journalctl -b -1 | 上次启动的日志 |
journalctl --since today | 今天的日志 |
journalctl --since "1 hour ago" | 最近 1 小时 |
journalctl --disk-usage | 日志占用空间 |
journalctl --vacuum-time=2w | 删除 2 周前的日志 |
如果想把日志导入脚本分析,用 journalctl -o json 输出 JSON 格式。
/var/log 常用操作
命令 | 用途 |
tail -f /var/log/syslog | 实时追踪系统日志 |
grep "Failed" /var/log/auth.log | 查登录失败 |
grep CRON /var/log/syslog | 查 cron 执行记录 |
dmesg -T | grep -i error | 查内核错误 |
last -n 20 | 最近登录记录 |
lastb -n 20 | 最近登录失败记录 |
快速排查流程
症状 | 先看哪里 |
服务启动失败 | journalctl -u 服务名 -n 50 |
系统突然重启 | journalctl -b -1 -p err |
SSH 连不上 | journalctl -u sshd、/var/log/auth.log |
硬盘有异响/变慢 | dmesg -T | grep -i error |
内存不够/OOM | journalctl | grep -i "out of memory" |
cron 没跑 | grep CRON /var/log/syslog |
软件包装失败 | /var/log/dpkg.log、/var/log/apt/ |
七、小结
日志是Linux 的"黑匣子",几乎所有问题都能在里面找到线索:
·journalctl是现代 Linux 的首选——-u按服务、-p按级别、-b按启动、-f实时追踪,四个参数就够解决大多数问题
·/var/log/里的文本日志是传统方案,auth.log看登录、syslog看系统消息、dmesg查硬件
·logrotate默默管理日志文件,防止磁盘被撑满
·学会看日志之后,大部分"莫名其妙"的问题都会有答案——不再是盲猜,而是有依据地排查
💡提示:如果觉得每次手敲命令太麻烦,可以把常用的日志查看命令做成别名(Shell 配置里讲过),比如 alias jlog='journalctl -p err --since today --no-pager',一键看今天的错误。 ⚠️注意:查看 /var/log/auth.log、/var/log/btmp等敏感日志需要 sudo 权限,这些文件记录了认证信息,普通用户不能随意访问。
下篇预告:《Linux 网络诊断工具》,从日志往外看,摸清网络连接状态和流量,从 ping 到 tcpdump,把网络层面的问题也纳入排查体系。