Linux 如何查看错误日志?grep、tail 与 journalctl 用法
Linux 服务器入门 · 第 16 篇 / 共 18 篇
日志很长时,先带着问题去读:刚才是哪一步失败、发生在什么时候、能否找到相同任务编号。只搜索 ERROR,可能漏掉报错前真正有用的一行。
以下先用第 09 篇的六行教学日志,在服务器执行 cd ~/linux-practice。路径不同就替换成自己那份日志的位置。
先看末尾,再找上下文
tail -n 50 logs/app.log文件不足 50 行时会显示已有内容,不会补齐行数。接着定位具体消息:
grep -n -C 1 'input file missing' logs/app.log-n 给出原文件行号,-C 1 在匹配前后各保留一行。对原始样例,相关记录是:
2-2026-10-18T09:00:01+08:00 INFO job=demo01 reading /data/input.csv
3:2026-10-18T09:00:02+08:00 ERROR job=demo01 input file missing
4-2026-10-18T09:00:03+08:00 WARN job=demo01 retry scheduled冒号所在行为匹配行,连字符所在行为上下文。前一行告诉我们正在读取什么,后一行说明程序准备重试;只拷出中间一句会丢失线索。
更长的文件可以用 less logs/app.log,输入 /demo01 搜索同一任务,按 n 继续,q 退出。完整异常堆栈要保留开头、异常链和末尾信息,不能只保留包含 ERROR 的一行。
观察一次新操作,产生了什么记录
在第一个 SSH 窗口执行:
tail -f ~/linux-practice/logs/app.log在第二个、登录同一台服务器的 SSH 窗口追加一条教学信息:
printf '%s INFO job=demo02 finished\n' "$(date -Is)" >> ~/linux-practice/logs/app.logdate -Is 产生当前时间,>> 追加,不覆盖原日志。第一窗口应看到新的一行;观察完按 Ctrl+C 结束跟踪。先启动观察、再触发动作,可以减少把旧记录当成刚才报错的机会。
日志轮转时,原文件可能被改名并创建新文件。GNU tail 的 -F 按文件名继续尝试跟踪,适用于这类场景;-f 与 -F 的区别可在服务器运行 tail --help 查看。
查询服务时,带上时间范围
下面仅适用于使用 systemd、已安装 Nginx 的练习机:
date -Is
sudo journalctl -u nginx --since '30 min ago' -n 100 --no-pager先确认服务器时间和时区。--since 限定开始时间,-n 100 再限制最近条数;如果遗漏了更早的相关记录,需要扩大范围。要持续观察可用:
sudo journalctl -u nginx -f按 Ctrl+C 退出。有权限、单元名正确并不保证一定有记录,还要看当时有没有相关事件,以及日志是否被保留。筛选方式见 journalctl 手册。
不把筛选条件当成诊断结论
grep 只做文本匹配,不理解日志时间。跨多天、跨时区或结构化日志,需要依据实际格式选择工具。匹配数也不等于独立事件数。
练习:从原始样例中保留 demo01 的完整六行,再指出两次 ERROR 为什么属于同一次任务。随后记录自己追加的 demo02 时间,确认它没有被错误地算进 ERROR 行数。