第2章:logcat命令详解——参数、过滤、格式化与保存

说实话,logcat 是 Android 调试里最常用的工具,没有之一。我每天打开 Android Studio 第一件事就是看 logcat 输出。但很多人只会用 adb logcat 然后盯着满屏的日志发呆——这其实是在浪费生命。今天我来聊聊怎么用好它。

2.1 基础参数:别只会敲 adb logcat

先说说最常用的几个参数。我个人习惯把它们分成三类:控制输出的、控制缓冲区的、控制格式的。

参数 作用 我常用的场景
-c 清空日志缓冲区 每次开始调试前先清一下,避免被旧日志干扰
-d 打印日志后退出(不持续监听) 写脚本抓取一次日志时用
-s 设置默认过滤级别(如 -s *:E 只想看错误日志时
-v 指定输出格式 后面单独讲
-b 指定缓冲区 调试系统服务时必用
-g 查看缓冲区大小和状态 怀疑日志被截断时

举个例子,我每次开始调试前都会先执行:

adb logcat -c
adb logcat -g

清空日志,然后看看缓冲区还剩多少空间。如果缓冲区快满了,我会考虑调大它——不过这是后话了。

2.2 缓冲区选择:main、system、events、crash

Android 的日志其实分了好几个缓冲区。很多人不知道这一点,结果调试系统服务时死活看不到日志。嗯,这里要注意:

  • main:普通应用日志,也就是 Log.v()Log.d() 这些
  • system:系统服务日志,比如 Slog.i() 输出的
  • events:事件日志,用 EventLog 写入的,格式比较特殊
  • crash:崩溃日志,Android 8.0 以后新增的
  • all:所有缓冲区(Android 10+)

我记得有一次调试 WMS(窗口管理服务),怎么都看不到 Slog.i(TAG, "xxx") 的输出。后来才发现默认只显示 main 缓冲区。加上 -b system 就看到了。

# 只看系统日志
adb logcat -b system

# 同时看 main 和 system
adb logcat -b main -b system

# 看所有缓冲区(Android 10+)
adb logcat -b all
我的习惯:调试应用时用 -b main,调试系统服务时用 -b system,分析 ANR 或崩溃时三个缓冲区一起看。

2.3 过滤语法:精准定位目标日志

过滤是 logcat 最核心的功能。说白了就是告诉系统:我只想看某些 TAG、某些级别的日志。

基本语法是:

adb logcat [TAG:LEVEL ...] [*:LEVEL]

其中 LEVEL 从低到高是:VDIWEF(Verbose、Debug、Info、Warn、Error、Fatal)。

举个例子:

# 只看 MyApp 的 Debug 及以上级别日志
adb logcat MyApp:D *:S

# 同时看 MyApp 和 SystemServer 的日志
adb logcat MyApp:D SystemServer:I *:S

这里 *:S 的意思是「其他所有 TAG 都静默」。这个技巧非常实用——你想想看,如果不加 *:S,系统日志会刷屏,你根本找不到自己的日志。

避坑指南:我曾经在调试一个第三方应用时,怎么过滤都看不到日志。后来发现是应用用了 Log.wtf() 输出——这个方法的级别是 ASSERT(级别值 7),比 F 还高。需要写成 adb logcat *:A 才能看到。

2.4 格式化输出:让日志更易读

默认的 logcat 输出格式是 brief,只显示优先级、TAG 和消息。但有时候我们需要更多信息,比如时间戳、PID、TID 等。

-v 参数可以指定格式:

格式 输出示例 适用场景
brief D/MyApp(1234): hello 默认,简洁
time 02-20 14:30:00.123 D/MyApp(1234): hello 需要时间戳时
threadtime 02-20 14:30:00.123 1234 5678 D MyApp: hello 分析多线程问题时
long 包含所有元数据 需要完整信息时
color 不同级别用不同颜色 终端直接查看时

我个人最常用的是 threadtime 格式。为什么?因为它同时显示了 PID 和 TID。在分析多线程问题时,你能清楚看到哪个线程在输出日志。

adb logcat -v threadtime MyApp:D *:S
小技巧:可以组合使用多个 -v 参数。比如 adb logcat -v color -v threadtime 就能同时获得颜色高亮和线程信息。

2.5 日志保存:别让重要日志溜走

调试时经常需要把日志保存下来慢慢分析。或者发给同事帮忙看。这时候就需要把日志输出到文件。

最直接的方法是用重定向:

adb logcat -v threadtime -d > logcat.txt

但这里有个坑——-d 参数会打印当前缓冲区内容然后退出。如果你想要持续保存,应该用:

adb logcat -v threadtime > logcat.txt

这样日志会持续写入文件,按 Ctrl+C 停止。

还有一个更高级的用法——保存到设备上:

adb logcat -v threadtime -f /data/local/tmp/logcat.txt

为什么要保存到设备上?因为有时候 USB 连接不稳定,或者你需要长时间抓取日志(比如一晚上)。保存到设备上,即使 USB 断开也不会丢失数据。

注意:保存到设备上需要 root 权限,或者写入 /data/local/tmp/ 目录。普通应用目录可能没有写入权限。

2.6 知识体系总览

下面这张图总结了 logcat 的核心知识点。我把它画成了流程图,方便你理解各个参数之间的关系。

adb logcat 基础参数 -c 清空缓冲区 -d 打印后退出 -s 设置过滤级别 -g 查看缓冲区状态 缓冲区选择 -b main (应用日志) -b system (系统日志) -b events (事件日志) -b crash (崩溃日志) 过滤语法 TAG:LEVEL 组合 *:S 静默其他 V/D/I/W/E/F/A 多TAG同时过滤 格式化输出 -v brief (默认) -v time (带时间) -v threadtime (推荐) -v color (颜色高亮) 日志保存 > logcat.txt (重定向) -f 路径 (保存到设备) -d 一次性保存 长时间抓取用 -f 核心思路:先过滤、再格式化、最后保存

2.7 实战组合拳

最后分享几个我常用的组合命令。这些都是在实际项目中打磨出来的:

# 场景1:调试应用崩溃,抓取所有相关日志
adb logcat -c
adb logcat -v threadtime -b main -b crash MyApp:D *:S > crash_log.txt

# 场景2:分析系统服务 ANR
adb logcat -v threadtime -b system -b events *:I > system_log.txt

# 场景3:实时查看带颜色的日志,只关注 Error 级别
adb logcat -v color *:E

# 场景4:查看缓冲区使用情况,判断是否需要清理
adb logcat -g

说实话,这些命令我几乎每天都会用到。刚开始可能觉得参数太多记不住,但用多了就变成肌肉记忆了。你想想看,调试效率提升一倍,是不是很值得花十分钟记住这些?

最后提醒一句:logcat 的日志是循环缓冲的。如果日志量太大,旧的会被覆盖。所以遇到关键问题,第一时间用 -d 保存当前日志,然后再慢慢分析。

专注资料整理