线上问题排查:用户反馈分析、日志采集、远程调试
做音频回声消除,最怕什么?
不是算法调不好,而是用户那边出了问题,你这边完全抓瞎。
我记得刚入行那会儿,有个用户反馈通话有回声,我本地怎么测都复现不了。折腾了两周,最后发现是用户手机壳把麦克风堵了一半。嗯,从那以后我就明白——线上问题排查,比写代码难多了。
用户反馈分析:别只听“有回声”三个字
用户说“有回声”,其实信息量很少。你得学会拆解。
我个人习惯把反馈分成三类:
- 场景类反馈:什么情况下出现?免提还是听筒?微信通话还是系统电话?
- 设备类反馈:什么手机?什么系统版本?有没有戴耳机?
- 频率类反馈:每次都有?偶尔出现?重启后消失?
我建议你做一个反馈模板,让用户填这些信息。别指望用户主动说全,他们只会说“卡死了”“有回声”。
日志采集:你的第一道防线
日志是线上问题的“黑匣子”。但日志太多,反而找不到关键信息。
我一般只关注三个时间点:
- 回声出现前5秒:看看音频路由有没有切换?音量有没有突变?
- 回声持续期间:AEC模块的收敛状态、延迟估计值、双端检测标志。
- 回声消失后3秒:有没有触发reset?滤波器有没有重新收敛?
下面是我常用的日志采集配置,放在Android的build.gradle里:
// 开启AEC详细日志
adb shell setprop persist.audio.aec.log 1
adb shell setprop persist.audio.aec.log.level 3
// 采集音频PCM数据(慎用,文件很大)
adb shell setprop persist.audio.aec.dump 1
adb shell setprop persist.audio.aec.dump.path /sdcard/aec_dump/
远程调试:线上问题的“手术刀”
日志不够用怎么办?得上远程调试。
Android系统提供了几个好用的工具:
| 工具 | 适用场景 | 缺点 |
|---|---|---|
| adb logcat + grep | 快速定位日志 | 需要USB连接 |
| Bugreport | 全量系统信息 | 文件太大,解析慢 |
| SysTrace | 性能瓶颈分析 | 需要root或开发版 |
| 远程adb(WiFi) | 无USB场景 | 需要同一网络 |
我个人最常用的是远程adb + 定向日志。先让用户连上WiFi,然后通过IP连接:
adb connect 192.168.1.100:5555
adb logcat -v threadtime | grep -E "AEC|AudioFlinger|audio_hw"
这样只抓AEC相关的日志,不会刷屏。你想想看,如果全量日志一起输出,一秒几百行,根本看不完。
SVG流程图:线上问题排查流程
实战案例:一次典型的线上回声排查
说个真实案例吧。
某天收到反馈,说某款手机在微信免提通话时有回声。我按流程走了一遍:
- 第一步:确认场景。只有微信免提有,系统电话正常。说明不是底层驱动问题。
- 第二步:看日志。发现AEC模块的延迟估计值一直在跳,从20ms到80ms来回变。
- 第三步:远程调试。用SysTrace抓了一下音频线程,发现微信的音频回调线程优先级被降低了。
原因是什么?微信在免提模式下,音频回调线程被放在了后台cgroup里,导致调度延迟不稳定。AEC算法以为延迟变了,反复调整滤波器,反而产生了回声。
解决方案:在AEC算法里加了一个延迟平滑滤波器。如果延迟在短时间内剧烈变化,先保持上一次的值,等稳定了再更新。就这么一个小改动,回声问题就解决了。
避坑指南
我曾经踩过几个坑,分享给你:
- 别信“重启就好了”:用户说重启后正常,不代表问题不存在。可能是某个状态没复位,重启后碰巧好了。一定要拿到重启前的日志。
- 日志别全开:全开日志会让手机变卡,反而影响AEC表现。我一般只开AEC模块的日志,其他模块关掉。
- 注意隐私:PCM dump里包含用户通话内容。采集前一定要告知用户,并且加密传输。别给自己惹麻烦。
线上问题排查,说白了就是“猜原因 → 验证 → 再猜”的循环。你猜得越准,解决问题越快。而猜得准的前提,就是日志和调试工具用得熟。
嗯,今天就聊到这儿。记住:用户反馈是线索,日志是证据,远程调试是工具。三样都拿捏住,线上回声问题就没什么可怕的。
公众号:蓝海资料掘金营,微信deep3321