第三节: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支持用ANDOR逻辑组合多个条件:

// 同时满足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也可以这么优雅。