第三节:Logcat高级过滤语法——组合过滤的艺术
说实话,刚接触Logcat的时候,我也跟大多数人一样,只会用logcat | grep "关键字"这种原始方式。那时候项目还不大,勉强够用。直到有一次接手一个大型App的维护工作——好家伙,日志每秒刷几百行,grep根本扛不住。也就是从那时候起,我开始认真研究Logcat的高级过滤语法。
今天我就把这几年积累的过滤技巧,一次性分享给你。
3.1 tag:级别 组合过滤——最常用的黄金搭档
先说说我最常用的组合:tag:级别。说白了,就是同时按标签和日志级别来过滤。
语法很简单:
adb logcat *:V // 显示所有级别(默认)
adb logcat *:D // 只显示Debug及以上
adb logcat *:I // 只显示Info及以上
adb logcat *:W // 只显示Warning及以上
adb logcat *:E // 只显示Error及以上
adb logcat *:F // 只显示Fatal
但光用通配符*,其实意义不大。真正好用的是指定具体tag:
adb logcat MyTag:D // 只看MyTag的Debug及以上
adb logcat MyTag:W // 只看MyTag的Warning及以上
我在项目中遇到过这样一个场景:某个模块的日志特别多,但大部分都是Verbose级别的调试信息。我只想看Error级别的崩溃日志。这时候:
adb logcat MyModule:E
嗯,整个世界清净了。
核心要点:tag:级别 这个语法,tag部分支持正则表达式,级别部分必须是V/D/I/W/E/F之一。大小写不敏感,但建议统一大写。
3.2 使用package: 过滤——按应用隔离日志
这个功能我特别喜欢。你想想看,系统日志里混杂着几十个App的输出,想找到自己应用的那部分,简直是大海捞针。
从Android 5.0(API 21)开始,Logcat支持按包名过滤:
adb logcat --pid=$(adb shell pidof -s com.example.myapp)
或者更直接的方式:
adb logcat --pid=12345 // 12345是进程ID
但说实话,每次查PID太麻烦了。我个人习惯用这个组合命令:
adb logcat | grep "$(adb shell pidof -s com.example.myapp)"
不过要注意,pidof命令在某些老设备上可能不支持。这时候可以用:
adb shell ps | grep com.example.myapp | awk '{print $2}'
拿到PID后再传给logcat。
小技巧:如果你用的是Android Studio,直接在Logcat面板的搜索框里输入 package:com.example.myapp 就能过滤。Studio的Logcat还支持自动补全,非常方便。
3.3 使用pid: 过滤——精准定位进程
有时候同一个包名可能有多个进程(比如推送进程、WebView进程等)。这时候用包名过滤就不够精确了。我建议直接用PID。
语法:
adb logcat --pid=12345
或者多个PID:
adb logcat --pid=12345 --pid=67890
我曾经遇到过一个诡异的问题:某个服务进程一直在报错,但主进程看起来一切正常。如果用包名过滤,两个进程的日志混在一起,根本看不出问题在哪。后来我用PID分别过滤,才发现是子进程的内存泄漏。
注意:PID是动态的,每次App重启都会变化。所以如果你要长期监控,建议写个脚本自动获取PID。或者直接用包名过滤更省事。
3.4 多个条件组合——真正的进阶玩法
好了,前面都是开胃菜。现在才是真正的核心——多个条件组合过滤。
Logcat支持用AND和OR逻辑组合多个条件:
// 同时满足tag和级别
adb logcat MyTag:W --pid=12345
// 多个tag(用逗号分隔)
adb logcat MyTag1:W,MyTag2:E
// 排除某个tag
adb logcat MyTag:W --pid=12345 | grep -v "忽略的关键字"
我个人最常用的组合是:
adb logcat *:E --pid=$(adb shell pidof -s com.example.myapp)
这条命令的意思是:只看我应用的Error及以上级别的日志。嗯,基本上能覆盖90%的线上问题排查场景。
如果你需要更复杂的逻辑,比如只看某个tag的Error,同时排除某些关键字:
adb logcat MyTag:E --pid=12345 | grep -v "忽略的文本"
实战经验:我在做性能优化时,经常这样组合:adb logcat PerformanceTag:D --pid=12345 | grep -E "(耗时|延迟|慢)"。这样既能控制日志量,又能精准定位性能瓶颈。
3.5 避坑指南
最后分享几个我踩过的坑:
- 大小写问题:tag是区分大小写的,但级别不区分。我习惯tag保持原样,级别用大写。
- 空格问题:如果tag包含空格,记得用引号包起来:
adb logcat "My Tag":W - 正则表达式:tag支持简单的正则,比如
adb logcat My.*:D可以匹配所有以"My"开头的tag。但别写太复杂,否则性能会下降。 - 缓存问题:有时候改了过滤条件但没生效,试试
adb logcat -c清空缓存。
我曾经因为没注意大小写,排查了半天才发现是tag写错了。从那以后,我每次写过滤条件都会先确认一下tag的实际写法。
好了,这一节的内容就到这里。下一节我们会聊聊如何把过滤规则保存成脚本,实现一键切换。到时候你会发现,原来Logcat也可以这么优雅。