讨论一下改 bug 的方式,日志输出为主代替 debug 工具为主的优缺点

2020-03-21 10:54:32 +08:00
 mitiskysean

前段时间和一位字节跳动开发长者,估计 40+,是个真开发长者了。底层计算系统开发负责人,佩服的是依然一线主力开发。当时聊到日常开发时,长者表示他开发过程基本上很少 debug,逻辑异常都是通过运行日志来定位。

大致原因是,通过 debug 工具单步断点调试,是非常低效的开发行为。因为一次 debug 后只解决了当前的 bug,并没有让系统更易于维护,而每次通过完善日志来定位问题,问题定位会逐渐清晰且容易。而且断点对于复杂系统调试是非常麻烦的,首先定位问题出现大致范围就很耗时,完全没有通过日志来得清晰,当然具体细节通过断点 debug 是没有问题,毕竟日志输出是整体逻辑,没有输出太多细节信息,细节处问题还是需要通过 debug 工具。

当时听完蛮惊讶的,不过后来想一下,觉得好像是这么一回事。出现问题-->输出完善清晰的日志-->定位问题-->辅助 debug 工具-->解决问题,同时完善信息-->再次出现问题....的确好像会让整个系统更为清晰。最近试了一下,自觉效果不错,只是过程感觉有点不适,总是不自觉想直接开点 debug 去调。但是从结果上,由于被调试目的驱使,输出的运行信息的确更为高效且清晰,也的确同一模块问题定位因为日志逐渐完善会加速。

不过我觉得这个方法有个使用前提:开发水平较高,bug 多是结构逻辑上的。比方说事务漏提交导致后续的问,改动通过调用某模块方法来解决。而是某个方法细节出了问题,比如某个方法资源没释放,导致另外一处的问题,那这通过 bug 通过日志定位的话,估计输出一大堆信息吧。

老铁们怎么看这个问题,业界是否已有类似的开发模式啊?

7044 次点击
所在节点    Java
74 条回复
mywaiting
2020-03-21 12:58:01 +08:00
debugger 的方式也仅限于本地调试的时候用一下,线上产品,那必须是日志的方式

完善的 log 记录分析跟踪,是个好习惯,即使小项目也是可以接入 sentry 这样的异常记录工具的
guyeu
2020-03-21 12:58:26 +08:00
@ybw #20 事实是,你可以。你总能把问题定位到一个范围,然后在几十行代码里跳转。
ybw
2020-03-21 12:59:52 +08:00
@guyeu 所以你要一行行去停下来啊。
ybw
2020-03-21 13:00:53 +08:00
@guyeu 另一个事实是,比如程序崩溃了,崩溃点和问题所在点,会差的很远。尤其是多线程。
guyeu
2020-03-21 13:01:33 +08:00
@ybw #24 所以没必要一行行停下来啊。。停在你认为可能出问题的代码就行了啊。。。
guyeu
2020-03-21 13:02:10 +08:00
@ybw #24 另一个事实是,如果程序崩溃了,崩溃点和问题所在点也不见得有日志,因为日志系统是程序的一部分。
felixlong
2020-03-21 13:03:45 +08:00
基本上自己熟悉的 code 用 log 比较方便。debugger 主要用来调不熟悉的 code.
mitu9527
2020-03-21 13:04:23 +08:00
生产只能是日志,开发时主要是通过日志定位问题所在的位置,然后再通过 debugger 调试,看看具体发生了什么,才会引发问题。
ybw
2020-03-21 13:04:55 +08:00
@guyeu 真的行吗?要是我猜错了呢?
ybw
2020-03-21 13:06:23 +08:00
@guyeu 我已经不理解你试图表达什么了? 一行行逐行调试,跳进跳出函数,不是常规流程吗?
guyeu
2020-03-21 13:07:24 +08:00
@ybw #29 真的行,用自己的脑子重新思考一下,结合日志,你可以的。
ybw
2020-03-21 13:09:23 +08:00
@guyeu 抱歉了,多年的开发经验告诉我,我没这个能力。你一定是大多数时候就"一猜就准"吧,真羡慕你的调试经历。
also24
2020-03-21 13:13:01 +08:00
@guyeu #26
你可能理解的过于偏激了,楼主的标题其实有个关键词是 “XX 为主”

以 debugger 为主的处理思路,更多的适用于 “一次性” 故障,是为了解决 bug 而做的。

以日志为主的思路是一整套动作,要掌握好日志的输出粒度,以及日志的格式化方便查找等。
之所以推荐日志为主的处理思路,则是因为它具有更好的 “整体性”,能在解决 bug 之外带来更多额外的收益。


至于是否一定能够 “快速” 定位问题,其实影响因素很多:
对代码熟悉的人,也许能够更精确的下断点;但也许遇到多线程的问题就会比较难受。
日志写的详细的人,也许能够只看日志就确定问题;但也许遇到日志盲区就不得不走调试。

这其实并不矛盾,以 xx 方法为主只是一种倾向,而不是完全摒弃另一方。
Mohanson
2020-03-21 13:27:36 +08:00
大部分 CPU 在设计的时候都有个 debug 模块,它允许用户态程序完全接管 CPU 的运行,甚至允许运行过程中修改寄存器内的值,也就是全部 debug 工具的能力来源。

但是 CPU 中 debug 模块的复杂程度甚至超过了 CPU 本身,非常不划算。

所以后来提出了 tracing 模式,也可以理解为 CPU 层面下的 Log 模块,只负责记录。不过这东西造价高昂,cpu 每秒能产生海量数据,要能全部记录,压缩和存储。

不过从大趋势上来讲,tracing 与 debug 两方的角逐我认为 tracing 未来可能会占优,现有的 debugger 工具也将逐渐退出(前提成立的情况下)
taowen
2020-03-21 13:45:15 +08:00
业内比较先进的有 firefox 的 rr https://github.com/mozilla/rr/wiki/Recording-Firefox 和微软的 time travel debugging https://docs.microsoft.com/en-us/windows-hardware/drivers/debugger/time-travel-debugging-overview 之前在滴滴做过一个业务上用的简单的工具 https://github.com/didi/rdebug

难点还是比较多的,不仅仅是数据量和性能问题,还包括什么叫一个完整因果链的 session 的问题。React 有一个叫 Interaction 的概念 https://gist.github.com/bvaughn/8de925562903afd2e7a12554adcdda16 做 tracing 的时候都需要这样的东西。这种上下文关联的事情不是纯技术手段能底层解决的,要侵入到业务代码的编写方式里。
vindurriel
2020-03-21 14:12:48 +08:00
能打断点的 debugger 侵入性太大 日志则可以控制输出级别和粒度 一种方案同时应对开发 测试 生产环境的需要 对正常逻辑的影响更可控
holdmybeer
2020-03-21 14:21:54 +08:00
@wuhx #4

哈哈哈,看到了那句 'To me, it's not a bug, it's a feature.'
winterfell30
2020-03-21 14:30:10 +08:00
我有另一个疑问,我从大学开始我找 bug 就是二分法打日志来找的,一直感觉用 debug 的更专业,但是因为我 debug 效率一直不如打日志高所以一直也没有动力学怎么更高效的 debug,有什么打日志做不了但是很适合用 debug 的例子可以说说吗
also24
2020-03-21 14:51:22 +08:00
@winterfell30 #38
你用二分法打日志的过程,就不如直接使用 debugger, 用 debugger 大概率只需要跑一次……
以及,你的二分法的日志点,其实就是你心目中使用 debugger 的断点位置。

在我的理解,你这样其实是在使用打日志的方式来进行 debugger 的工作。

如我前面所说,日志查 bug 是一个系统化的工程,不是在遇到 bug 的时候才开始的,而是从开发阶段就已经 “留一手”。
也正是因此,断点只能用一次,日志点可以保留,后续查用。
fancy2020
2020-03-21 15:04:12 +08:00
基本没太用过调试工具,都是加日志查问题。
现在做前端了,还是靠 log

这是一个专为移动设备优化的页面(即为了让你能够在 Google 搜索结果里秒开这个页面),如果你希望参与 V2EX 社区的讨论,你可以继续到 V2EX 上打开本讨论主题的完整版本。

https://www.v2ex.com/t/654798

V2EX 是创意工作者们的社区,是一个分享自己正在做的有趣事物、交流想法,可以遇见新朋友甚至新机会的地方。

V2EX is a community of developers, designers and creative people.

© 2021 V2EX