排错第一反应:grep 一下
日志排错的肌肉记忆应该长这样:先 grep 关键词,看命中多少,再看上下文。直接 vim 打开几个 G 的日志翻页,是新手最常见也最低效的做法。
$ grep ERROR app.log # 基础:筛出含 ERROR 的行
$ grep -c ERROR app.log # -c 只数个数(先看量级再细看)
$ grep -n ERROR app.log # -n 带行号(配合 vim +行号 跳过去)
$ grep -i error app.log # -i 忽略大小写
$ grep -rn "timeout" /etc/nginx/ # -r 递归整个目录,-n 带行号
# 改配置忘了哪一句写在哪个文件,一条搞定上下文:孤立的报错没有意义
只看 ERROR 那一行往往不知道为什么错,前后几行才是案情经过。三个参数是日志排查的黄金组合:
$ grep -A 3 ERROR app.log # After:匹配行之后 3 行
$ grep -B 3 ERROR app.log # Before:之前 3 行
$ grep -C 3 ERROR app.log # Context:前后各 3 行(最常用)
// 排除干扰:日志里既有 ERROR 又有堆栈里的关键字?
$ grep ERROR app.log | grep -v "Heartbeat" # -v 反向:排除噪声行正则:精准命中
# 基础正则(默认支持)
$ grep "^2026-03" app.log # ^ 行首:只看三月的日志
$ grep "error$" app.log # $ 行尾
$ grep "user[0-9]" access.log # 字符类:user0~user9
# 扩展正则(-E,支持 + ? | {n,m})
$ grep -E "(ERROR|FATAL)" app.log # 两种关键字任一命中
$ grep -E "took [0-9]{4,}ms" app.log # 耗时 4 位数毫秒以上的慢请求
# 引号建议:正则一律用双引号包起来,避免 shell 抢先解释特殊字符实战:三分钟定位一次线上异常
# 第 1 步:量级(几千条还是几条?决定排查策略)
$ grep -c ERROR app.log
# 第 2 步:分布(集中在某个时间段?)
$ grep ERROR app.log | awk '{print $1}' | sort | uniq -c | sort -rn | head
# 第 3 步:取样细看(拿一条完整的上下文)
$ grep -B 2 -A 5 "NullPointerException" app.log | head -30
# 第 4 步:关联(同一请求 ID 的全程日志)
$ grep "reqId=88a3f" app.log第 2 步里 awk 和 sort | uniq -c | sort -rn 还没登场——这正是接下来两篇的主角。grep 负责筛行,awk 负责切列,两者配合才是完整功力。下一篇:awk,按列处理数据的一把好手。
评论 (0)