跳到正文
W Winse Blog
dev 1 min read

从“调试万能”到“日志为王”:程序员的自我修养

初出茅庐

刚毕业工作那会,我对日志并没有太多认知。那时候觉得,调试在手,BUG无忧。断点一打,快捷键 F5-8 一按,堆栈一点,变量一查,一顿操作猛如虎问题全靠Debug。相比之下,打日志来排查问题就显得繁琐而且笨拙,看到同学写代码用 print 打印,我甚至觉得老同学都开始土起来了。本地调试、远程调试、浏览器调试,万事皆可调嘛!

那时的我,代码写得少、遇到的问题场景也简单,年少轻狂,调试过了就自以为必然是万无一失的。在我看来,打日志不仅多余,而且只能看到局部的数据值,缺乏灵活性,不像调试器能堆栈前后自由的跟踪定位。

历尽千帆

可随着代码越来越复杂,尤其是涉及多线程、多进程的时刻,断点调试的局限性慢慢地显现出来了。断点能让程序在指定位置停下来,但停下来的那一刻,真实的运行环境也就已经被破坏。很多并发的、时序上的问题,根本无法在“暂停”的状态下重现。

真正让我彻底转变的,是在经历了 Hadoop 生产系统 MapReduce 问题的排查处理后。本地测试已经“完美无缺”的代码,上线后却抛出各种诡异的错误,分布式集群节点多了后,远程调试几乎不可能,而且生产环境的也不允许随便搞远程调试。

此时,日志成了唯一可能的抓手,通过日志把异常数据打印出来,输出运行时的上下文信息,然后再进行本地的复现和修复。

从那以后,我才明白:可靠代码、全面测试只是第一道防线, 生产环境千奇百怪的数据都有,总有预想不到的边界,还需要日志这第二层保障, 记录错误信息,提供前后关联的上下文信息,也是必不可少的一环。

随着系统规模和团队协作的扩大,日志的重要性愈发凸显。应用出了错误,如果没有清晰的日志,运维人员无法定位,开发人员也难以快速排查。日志不仅是开发者的工具,更是连接开发和运维的桥梁,是团队协作的基石。

当然,日志也讲究分寸,不能随便打。如果全是一个级别,要么淹没在海量日志里,要么稀少到毫无参考价值。合理的分级日志至关重要:

  • ERROR: 记录明确的、必须处理的错误。

  • INFO: 记录关键流程和统计类的信息,简洁但必要的。

  • DEBUG: 记录详细的调试信息,大量但可控的。

只有这样,既能支撑本地调试,又能满足线上排查的需求。我跟随运维过一段生产系统,才真正体会到日志的重要性,线上系统没有日志,就等于人失去了双手,没了抓手。运维不能只看到应用前端正常,就觉得万事大吉了;他们必须通过日志来确认是否有异常,并结合异常前后的日志,去完整的、可解释的定位问题,与开发协同解决问题。

返璞归真

回过头看,从最初的抗拒到接受,再到现在依赖,其实也是我对软件复杂性理解的逐步加深,以及在实际项目中不断锤炼的结果。日志不是调试的替代物,而是在真实环境里留下的可靠的、可追溯的物证,是开发和运维之间的桥梁,也是团队协作的保障。

日志是开发的利器,调试器可以缺席,但日志必须在场。它让问题不再无声无息,让应用在乱中有序,有迹可循。

在 GitHub 上讨论

欢迎通过 GitHub Issue 留言或反馈。每条讨论都会关联到对应文章的源文件路径。

2025-09-08-从“调试万能”到“日志为王”:程序员的自我修养.md

Related posts