正式教学
核心的工具其实还是 grep
命令,下面我将分场景给你讲讲我的实战经验,保证你能直接套用!
场景一:查异常堆栈,不能只看一行!
Java 异常堆栈通常都是多行的,仅仅用 grep "NullPointerException"
只能看到最上面那一行,问题根源在哪你压根找不到。
这时候使用 grep
的 -A
(After) 参数来显示匹配行之后的 N 行。
# 查找 NullPointerException,并显示后面 50 行
grep -A 50 "java.lang.NullPointerException" a.log
如果你发现异常太多,屏幕一闪而过,也可以用 less
加上分页查看:
grep -A 50 "java.lang.NullPointerException" a.log | less
在 less
视图中,你可以:
使用 箭头↑↓ 或 Page Up/Down 键来上下滚动
输入
G
直接翻到末尾,方便快速查看最新的日志输入
/Exception
继续搜索按
q
键退出
这样你就能 第一时间拿到完整异常上下文信息,告别反复 vi
+ /
的低效操作!
场景二:实时看新日志怎么打出来的
如果你的应用正在运行,并且你怀疑它会随时抛出异常,你可以实时监控日志文件的增长。
使用 tail -f
结合 grep
:
# 实时监控 a.log 文件的新增内容,并只显示包含 "java.lang.NullPointerException" 的行及其后50行
tail -f a.log | grep -A 50 "java.lang.NullPointerException"
只要异常一出现,它就会自动打出来,堆栈信息也一并送到你面前!
想停下?
Ctrl + C
想更准确?加
-i
忽略大小写,防止大小写拼错找不到
场景三:翻历史日志 or 查压缩日志
服务器上的日志一般都会按天或按大小分割并压缩,变成 .log.2025-07-02.gz
这种格式,查找这些文件的异常信息怎么办?
查找当前目录所有 .log
文件:
# 在当前目录下查找所有以 .log 结尾的文件,-H 参数可以顺便打印出文件名
grep -H -A 50 "java.lang.NullPointerException" *.log
其中 -H
会帮你打印出 是哪个文件 中出现的问题,防止你找完还不知道是哪天的事。
查找 .gz
文件(压缩日志):
zgrep -H -A 50 "java.lang.NullPointerException" *.gz
zgrep
是专门处理 .gz
的 grep
,它的功能和 grep
完全一样,无需手动解压,直接开整!
场景四:统计异常数量(快速判断异常是否频繁)
有时候你需要知道某个异常到底出现了多少次,是偶发还是成灾,使用 grep -c
(count):
grep -c "java.lang.NullPointerException" a.log
如果你要统计所有日志里的数量:
grep -c "java.lang.NullPointerException" *.log
其他常用的 grep 参数
参数 | 作用 |
---|---|
-B N |
匹配行之前的 N 行(Before) |
-A N |
匹配行之后的 N 行(After) |
-C N |
匹配行上下共 N 行(Context) |
-i |
忽略大小写 |
-H |
显示匹配的文件名 |
-r |
递归搜索目录下所有文件 |
比如:
grep -C 25 "java.lang.NullPointerException" a.log
这个命令就能让你一眼看到异常前后的上下文,帮助定位代码逻辑是不是哪里先出问题了。
「人生在世,留句话给我吧」