日志采集准备:四大工具链配置与选型

ANR 问题排查的起点是完整、准确的现场数据。不同工具采集的数据维度不同,采集窗口稍纵即逝。本章聚焦四种核心日志工具的配置方法与选型策略,确保你在下次 ANR 出现时能一次性拿到足够的信息,避免反复复现。

核心原则:先采集、后分析;多工具互补,单工具不追责。adb logcat 记录应用层事件,ANR trace 冻结系统线程状态,systrace / perfetto 追踪时间片与调度过程。四者组合才能还原完整的 ANR 成因链。

现象识别:哪些信号表明需要采集日志?

ANR 发生时系统会产生明确的日志写入行为。识别以下现象即可触发自动化采集流程:

  • Logcat 出现 "ANR in" 关键字 —— 应用主线程超时,系统弹出 ANR 对话框。
  • 系统生成 /data/anr/traces.txt —— 内核 dump 所有线程堆栈到该文件。
  • Event log 输出 am_anr 事件 —— 记录 ANR 发生时间、进程名、CPU 负载。
  • 用户反馈界面卡死 > 5 秒 —— 即使 logcat 未及时打印,也应主动拉取 trace 和 perfetto 缓冲区。
现象日志来源采集优先级
logcat 出现 "ANR in"adb logcat最高,立即保存
/data/anr/traces.txt 更新ANR trace 文件最高,第一时间 pull
am_anr 事件出现logcat -b events高,辅助确认时间点
UI 线程卡顿无响应systrace / perfetto中,需提前配置守护采集

数据采集:四种工具配置详解

1. adb logcat —— 应用层日志即时采集

最直接的日志通道,用于记录 ANR 发生前后的应用行为、系统广播、Service 超时信息。

# 清空缓冲区并持续输出,按标签过滤
adb logcat -c
adb logcat -s ActivityManager:I WindowManager:I *:S -v threadtime > anr_app.log

# 同时捕获 main、system、events 三个缓冲区
adb logcat -b main -b system -b events -v threadtime | tee anr_full.log

# ANR 发生后立即 dump 历史缓冲区(无等待)
adb logcat -d -b main -b system -b events | grep -E "ANR|am_anr|CPU"
避坑:线上环境建议在应用启动时通过 ProcessBuilder 启动独立进程持续采集 circular buffer(大小 2 MB),避免 ANR 发生时 logcat 缓冲区已被滚动覆盖。

2. 系统 ANR trace 文件 —— 线程堆栈的冻结快照

ANR 发生时系统自动 dump 所有线程堆栈到 /data/anr/traces.txt(Android 10+ 可能分片为 traces_*)。这是定位阻塞线程最直接的数据源。

# 拉取 trace 文件(需要 root 或 debuggable 应用)
adb root
adb wait-for-device
adb pull /data/anr/traces.txt ./anr_traces_$(date +%Y%m%d_%H%M%S).txt

# 若设备无 root,使用 run-as 抓取本应用堆栈
adb shell run-as com.your.package cat /data/anr/traces.txt > app_trace.txt
字段含义关注点
"main" prio=5 tid=1主线程标识tid=1 表示主线程,观察其状态:RUNNABLE / BLOCKED / WAITING
at com.xxx.xxx.method当前执行栈帧最上层为阻塞点,检查锁对象、IPC 调用
Locked ownable synchronizers持有的锁与其它线程的锁等待形成死锁链
CPU usage进程 CPU 占用过高表示计算密集,过低表示等待 I/O 或锁

3. systrace —— 轻量级 UI / 调度追踪

systrace 基于 ftrace,适合追踪 UI 渲染、View 绘制、消息分发等短时间(5~10 秒)场景。Android 10 以下默认使用,以上推荐迁移至 perfetto。

# 通过 Python 脚本启动(需 Android SDK tools 目录)
python systrace.py -t 8 -o anr_trace.html \
  --categories=view,am,rs,hal,app,sched,freq

# 使用 atrace 命令直接输出
adb shell atrace --async_start -c -b 4096 view am app sched
# ... 复现 ANR 操作 ...
adb shell atrace --async_dump > anr_systrace.txt
adb shell atrace --async_stop
适用场景:UI 线程卡顿、布局过度绘制、Binder 调用超时。输出为 HTML,可在 Chrome 中可视化分析。单次采集时长建议 ≤ 10 秒,否则缓冲区溢出。

4. perfetto —— 下一代全平台追踪方案

Perfetto 是 Android 11+ 的官方追踪引擎,支持更长的采集窗口、更丰富的数据源(CPU、GPU、内存、I/O、调度器)。通过 protobuf 配置灵活控制探针。

# 1. 创建采集配置 config.pbtx
duration_ms: 30000
buffers: {
  size_kb: 65536
  fill_policy: RING_BUFFER
}
data_sources: {
  config {
    name: "android.logcat"
    target_buffer: 0
    android_logcat_config {
      log_ids: LOG_ID_MAIN
      log_ids: LOG_ID_SYSTEM
      log_ids: LOG_ID_EVENTS
    }
  }
}
data_sources: {
  config {
    name: "linux.ftrace"
    ftrace_config {
      ftrace_events: "sched/sched_switch"
      ftrace_events: "power/cpu_frequency"
      ftrace_events: "binder/*"
    }
  }
}

# 2. 推送配置并启动采集
adb push config.pbtx /data/local/tmp/
adb shell perfetto -c /data/local/tmp/config.pbtx \
  -o /data/local/tmp/trace.perfetto-trace --txt

# 3. 复现 ANR 后停止并拉取
adb pull /data/local/tmp/trace.perfetto-trace ./anr_perfetto.pb
维度systraceperfetto
数据源丰富度仅 ftrace 事件ftrace + logcat + heap + 自定义探针
最大采集时长~10 秒~60 秒(环形缓冲区可更长)
配置灵活性命令行参数固定protobuf 灵活编排
可视化方式Chrome trace viewerui.perfetto.dev 或 Chrome
推荐场景快速验证 UI 问题深度 ANR / 性能回归分析

原因定位:工具选型决策树

面对一次 ANR,不应盲目启动所有工具。根据已有线索选择最小采集集合,既能降低性能开销,又能提高数据信噪比。下图展示了从 ANR 问题到具体工具的选型路径:

日志采集工具选型决策树 ANR 问题待排查 需要应用层日志? 需要系统线程状态? 需要性能调度分析? adb logcat ANR trace 文件 systrace perfetto 综合日志研判 锁定阻塞线程 / 锁竞争 / Binder 等待 → 定位到具体代码路径 ① 优先拉取 ANR trace + logcat events 确认时间线;② 如需调度细节则用 perfetto;③ systrace 仅用于快速验证 UI 线程
判断规则:若 trace 中主线程状态为 BLOCKED 且持有锁,优先分析锁竞争链,此时 perfetto 的 lock_contention 事件能精确显示等待时长;若主线程为 RUNNABLE 且持续执行 CPU 密集型操作,systrace 的 CPU slice 视图可快速定位热点函数。

修复动作:常见配置问题与解决

问题现象根因解决方案
logcat 缓冲区被覆盖,ANR 日志丢失默认缓冲区仅 64 KB使用 adb logcat -G 2M 扩大缓冲区,或在应用内实现环形日志文件
pull /data/anr/traces.txt 权限拒绝非 root 设备,应用不可调试在 AndroidManifest 中设置 android:debuggable="true",或使用 run-as 抓取本应用堆栈
systrace 采集时提示 "no atrace"设备 Android 版本过低或系统镜像裁剪改用 adb shell perfetto 命令,或升级设备至 Android 11+
perfetto 配置不生效,无数据输出protobuf 字段遗漏或缓冲区大小不足在 ui.perfetto.dev 上使用可视化配置器导出 config,验证 buffers.size_kb ≥ 32768

复测:验证采集配置有效性

完成工具配置后,执行以下验证脚本确保每一条采集链路畅通:

# 验证 logcat 环形缓冲区已扩大
adb logcat -g | grep -E "ring buffer"

# 验证 trace 文件可正常拉取(不依赖 ANR 触发)
adb shell "echo 'test' > /data/anr/traces.txt" 2>/dev/null && echo "trace 写入权限 OK"

# 验证 systrace 能启动并输出 HTML
python systrace.py -t 2 -o /dev/null --categories=view,sched

# 验证 perfetto 采集端到端
adb shell perfetto -c - --txt -o /data/local/tmp/verify.pb <<EOF
duration_ms: 3000
buffers: { size_kb: 1024 }
data_sources: { config { name: "linux.ftrace" } }
EOF
adb pull /data/local/tmp/verify.pb /dev/null && echo "perfetto 采集 OK"
复测通过标准:四条命令全部返回 OK 或非空输出。任何一条失败都表示对应工具在目标设备上不可用,需回退到替代方案或修复权限配置。

预防:标准化采集规范

  • 建立采集 checklist:每次 ANR 事件触发后,按 "logcat → trace → perfetto" 顺序自动执行采集脚本,避免人工遗漏。
  • 统一配置模板:将 perfetto config 和 systrace 参数写入项目版本库,随应用版本迭代同步更新探针集合。
  • 预置守护进程:在应用启动时启动一个低优先级服务,循环记录 logcat events 和 CPU 负载,ANR 发生时保留最后 30 秒数据。
  • 定期演练:每周在 CI 中触发一次模拟 ANR(通过主线程 sleep 10 秒),验证采集链路完整性。