第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 从低到高是:V、D、I、W、E、F(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 断开也不会丢失数据。
/data/local/tmp/ 目录。普通应用目录可能没有写入权限。
2.6 知识体系总览
下面这张图总结了 logcat 的核心知识点。我把它画成了流程图,方便你理解各个参数之间的关系。
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 保存当前日志,然后再慢慢分析。