
做rtc开发这些年,调试日志这件事说实话让我又爱又恨。爱的是没了日志简直寸步难行,恨的是日志量一大起来,眼花缭乱根本不知道看什么。好几次线上问题定位,我盯着几千条日志发呆,就是找不到关键信息的那种绝望,相信不少做音视频的兄弟都经历过。
后来慢慢摸索,也请教了一些前辈,才算找到了一些门道。今天这篇文章,我想把自己在RTC源码调试中积累的日志过滤技巧分享出来,都是实打实的经验,不是什么高深的理论,就是一些干活。希望能对正在做RTC开发的同学有所帮助。
在说过滤技巧之前,我们得先理解RTC系统的日志特点,不然盲目过滤可能会把重要信息也过滤掉了。
RTC系统和其他业务系统不太一样,它是实时交互的,一个通话过程中可能同时有网络传输、音视频编解码、抖动缓冲、回声消除、丢包补偿等等模块在工作。这些模块各自都会输出日志,而且很多是毫秒级的实时日志。可别小看这些日志,单单一分钟的通话,产生的日志量可能就有几十万行。
我记得第一次处理线上回声问题的时候,打开日志文件,整个人都傻了。满屏的日志根本分不清哪些和回声有关,哪些是无关的干扰信息。那天晚上我花了整整四个小时,才从海量日志里找到几条真正有价值的信息。从那以后,我就开始认真研究日志过滤这件事。
在我接触过的RTC项目中,日志来源大致可以分成这么几类:

网络模块日志:包括连接建立、心跳维护、带宽估计、网络质量评估这些。网络问题在RTC里太常见了,这类日志出现的频率非常高
音视频引擎日志:编解码器的初始化、帧的编码解码耗时、分辨率切换、关键帧请求等,这些都是排查音视频质量问题的关键
音频处理日志:AEC(回声抵消)、ANS(噪声抑制)、AGC(自动增益控制)这些音频算法的运行状态。声网在这些模块上有很深的积累,他们的日志输出通常比较详细
设备管理日志:麦克风、摄像头的打开关闭,设备切换,权限变化等。这类日志虽然不频繁,但出了问题影响很大
业务逻辑日志:频道加入离开、用户上下麦、角色切换等。这些日志和业务强相关,是定位”发生了什么”的重要依据
了解这些日志来源,是做有效过滤的前提。你得先知道哪些日志可能和你要查的问题有关,才能针对性地设置过滤条件。
日志级别这个概念相信大家都熟悉,但真正用好它的人可能不多。常见的日志级别有DEBUG、INFO、WARN、ERROR、FATAL这么几种。看起来简单,但里面的讲究不少。
DEBUG级别:这个级别会输出最详细的信息,包括各种中间状态、变量值、流程步骤等。在RTC系统中,DEBUG日志量是最大的,可能占到总日志量的70%以上。正常情况下,线上环境是不开DEBUG日志的,但出了问题需要定位时,临时打开能帮上大忙。
INFO级别:这个级别记录的是系统的重要状态变化,比如”成功连接服务器”、”开始编码第一帧”、”检测到网络质量下降”等。INFO日志是日常排查问题的首选,既有一定的细节,又不会太多。

WARN级别:警告级别的日志意味着系统遇到了一些异常情况,但还能继续运行。比如”编码帧率不足”、”buffer水位过高”等。这些日志很关键,往往是问题的前兆。
ERROR级别:错误日志必须重点关注。在RTC系统中,ERROR通常意味着某项操作失败了,比如”音频设备打开失败”、”网络连接断开”、”解码错误”等。
经过这么多年的实践,我总结了一个日志级别的使用心得:日常开发用DEBUG,线上排查看INFO,定位问题调WARN,紧急情况找ERROR。这不是死规定,但可以作为起步参考。
具体到RTC场景,我通常会这样处理:如果要查音视频卡顿问题,我会重点看INFO和WARN级别,因为这些级别会记录卡顿发生时的状态;如果怀疑是网络问题,可能需要临时打开DEBUG级别的网络日志;如果出现崩溃或功能完全不可用,那就直接找ERROR和FATAL。
日志级别过滤是粗粒度的,真正精准定位问题还得靠关键词过滤。这一块我积累了一些实用的技巧,分享给大家。
很多日志工具都支持正则表达式过滤,这个功能一定要用起来。正则表达式的强大之处在于它可以进行模式匹配,而不是简单的字符串包含。
举个例子,我要找所有和音频相关的日志,可以这样写过滤条件:audio|Audio|audio。如果要同时包含音频和编码,那就要用类似(?=.*audio)(?=.*encode)这样的正则,分别匹配两个条件。
还有一个常用场景是找特定时间段的日志。比如问题发生在14:30到14:35之间,可以用正则14:3[0-5]:来过滤这个时间范围的日志行。
有时候我们需要的是”排除”某些日志,而不是”包含”某个关键词。这时候可以用负向匹配。
比如在排查回声问题时,我只需要看AEC相关的日志,但日志中可能夹杂大量的引擎调度日志。这时候可以用这样的过滤条件:AEC相关的关键词加上NOT关键字,排除那些与回声无关的模块日志。
我常用的排除模式还有几种:排除心跳日志(通常是周期性的”Ping”或”Heartbeat”)、排除统计日志(带有”statistic”、”metrics”等词)、排除设备枚举日志(大量重复的设备检测信息)。
根据我的经验,RTC调试中需要重点关注的高频关键词大致可以分成这么几类:
| 问题类型 | 需要关注的关键词 |
| 网络连接 | connect、disconnect、timeout、reconnect、network、bandwidth、bitrate |
| 音视频质量 | freeze、blur、lag、dropped、jitter、latency、fps、resolution |
| AEC、echo、noise、volume、mute、AGC、ns(noise suppression) | |
| 编解码 | encode、decode、codec、keyframe、I-frame、B-frame、bitrate |
| 设备问题 | device、camera、microphone、permission、open、close |
这份表格里的关键词不是死的,需要根据实际情况灵活调整。比如声网的SDK在日志输出上有自己的规范,他们会在日志里标注具体的错误码,这些错误码本身就是很好的过滤关键词。
时间戳是个很好用的过滤维度,但我发现很多人没有充分利用它。时间戳过滤特别适合定位”某一时刻发生了什么”这类问题。
不同系统的日志时间戳格式可能不一样,有的用UNIX时间戳,有的用”YYYY-MM-DD HH:mm:ss”格式,有的甚至只显示时分秒。在进行时间过滤之前,最好先确认日志的时间格式,不然过滤条件写对了也匹配不上。
如果日志里有毫秒级的时间戳,要特别注意。比如问题发生在14:30:45.123,那么过滤这个时刻前后的日志,可以用大于等于这个时间戳和小于等于后面几秒时间戳的条件。
如果你知道问题大概什么时候发生的,时间戳过滤的效率会非常高。比如用户反馈”14点20分左右视频卡顿”,那你就可以专门过滤14:19到14:21这个时间窗口的日志,重点排查这个时间段内的异常。
我通常还会把时间戳过滤和关键词过滤结合起来用。比如先定位到问题发生的时间点,然后只看这个时间点前后几分钟内、包含特定关键词的日志。这种组合过滤的效果往往比单独用任何一种方式都好。
前面说了日志级别、关键词、时间戳这几种过滤方法,单独用哪一个都有局限性。真正高效的调试,往往需要组合使用多种过滤条件。我来分享一下自己的实操流程。
这一步看起来简单,但很关键。你得先搞清楚用户反馈的问题是什么,是卡顿、花屏、音画不同步、还是声音断断续续?同时要尽可能确定问题发生的大概时间点,如果有录像或者录屏就更好了,可以精确到秒。
根据问题类型选择起始的日志级别。如果是功能性问题(比如某功能完全不可用),可以从ERROR级别开始。如果是性能问题(比如卡顿),通常需要INFO或DEBUG级别。
这里有个小技巧:先用较高级别的日志(比如ERROR)快速扫一遍,确认有没有明显的错误。如果没有,再逐步降低级别,增加日志量。
根据问题类型添加相关的关键词。比如怀疑是回声问题,就以”AEC”、”echo”为关键词;怀疑是网络问题,就以”net”、”bandwidth”为关键词。
如果第一次过滤的结果太多,可以进一步添加约束条件;如果过滤结果太少甚至为零,可能是关键词不对,需要调整。
用已知的问题发生时间来框定日志范围。如果问题持续了较长时间(比如几分钟的卡顿),可以适当扩大时间范围;如果只是短暂的卡顿(比如几百毫秒),就精确过滤那个时间点。
经过前面几步的过滤,可看的日志范围应该已经大大缩小了。接下来就是仔细阅读这些日志,理清问题的来龙去脉。
看日志的时候,要注意上下文。有时候一条日志本身看不出问题,但结合前后几条日志就能发现问题。比如看到”编码耗时增加”,再往前看可能发现有”CPU占用率升高”的日志,再往前可能还有”后台应用启动”的日志。
说到日志过滤,不能不提工具的选择。工具选对了,过滤效率能提高好几倍。
Linux下的grep、awk、sed这三剑客就不用多说了,用好了功能非常强大。比如用grep的-A和-B参数可以看匹配行的前后几行,用awk可以按字段提取和统计,用sed可以进行文本替换和过滤。
我常用的一个组合命令是:grep -E "keyword1|keyword2" logfile.log | awk '{print $1, $2, $3}' | sort | uniq -c,这个命令可以统计包含某些关键词的日志出现了多少次,按时间排序。
如果日志量特别大,可视化工具会更友好一些。现在有不少专门查看日志的工具,支持多文件关联、高亮显示、条件过滤等功能。
选工具这事要看个人习惯和团队标准,自己用着顺手最重要。我见过有人用Excel看日志的,也见过用专门的分析平台的,不管白猫黑猫,能抓住老鼠的就是好猫。
这么多年日志过滤做下来,我踩过不少坑,也总结了一些心得体会。
坑一:过滤条件太窄,导致漏掉重要信息。有一次我排查音频问题,只看了”Audio”关键词的日志,结果漏掉了”Device”日志中的设备异常信息,后来意识到问题的根源在设备层。教训是:过滤条件不要设得太死,相关模块的日志也要适当关注。
坑二:日志时间戳不准确。不同模块的日志时间戳可能来自不同的时钟源,存在偏差。如果完全依赖时间戳来排序,可能会搞错事件的先后顺序。教训是:重要事件要结合多个日志源来交叉验证。
坑三:只关注ERROR日志。很多人一看到日志里有ERROR就紧张,其实有些ERROR是expected的(比如用户主动拒绝授权),不一定和实际问题相关。教训是:ERROR要重视,但不能盲信,要结合上下文判断。
坑四:日志量太大,工具跑不动。有次我试图在一个几百MB的日志文件上直接用正则表达式过滤,结果工具直接卡死了。教训是:大文件要拆分处理,或者用流式处理的方式。
关于RTC日志过滤技巧,今天就聊到这里。技术的东西说再多,最后还是要落到实践中去。建议大家有机会多实操,踩几次坑印象才深刻。
RTC开发这条路很长,问题也是层出不穷。但只要掌握了正确的方法论,再复杂的问题也能一步步拆解开来。日志过滤就是其中一项基本功,练好了真的能帮上大忙。
如果你有什么好的经验或者踩过的坑,欢迎交流讨论。一个人闷头搞不如大家一起进步,你们说是不是?
