调试/日志记录代码确实可能会有干扰性。在我们的C++项目中,我们使用宏包装常见的调试/日志代码 - 就像断言一样。我经常发现,在较低级别的组件中记录日志最有用,这样就不必到处都加。
其他答案中有很多可以同意和不同意的地方 :) 调试/日志记录代码可以是解决问题的非常有价值的工具。在Windows中,有许多技术 - 两个主要的技术是:
- 广泛使用已检查(DBG)构建断言以及对DBG构建进行大量测试。
- 在我们所谓的“fre”或“retail”构建中使用ETW。
已检查的构建(大多数人称为DEBUG构建)对我们也非常有帮助。我们在“fre”和“chk”构建上运行所有测试(在x86和AMD64上运行所有服务器内容也在Itanium上运行...)。有些人甚至在已检查的构建上自我托管(dogfood)。这做了两件事情:
- 找到许多否则不会被发现的错误。
- 快速消除嘈杂或不必要的断言。
在Windows中,我们广泛使用
Windows事件跟踪(ETW)。ETW是一种高效的静态日志记录机制。NT内核和许多组件都非常好地被仪器化了。ETW有很多优点:
- 任何ETW事件提供程序都可以在运行时动态启用/禁用-无需重新启动或进程重启。大多数ETW提供程序提供对单个事件或事件组的细粒度控制。
- 来自任何提供程序(最重要的是内核)的事件都可以合并到单个跟踪中,以便所有事件都可以相关联。
- 合并的跟踪可以从计算机上复制并完全处理-带符号。
- NT内核样本pofile中断可以生成ETW事件-这产生了一个非常轻量级的样本分析器,可以在任何时候使用。
- 在Vista和Windows Server 2008上,记录事件是无锁的,并且完全支持多核-每个处理器上的线程可以独立记录事件,它们之间不需要同步。
这对我们来说非常有价值,同样适用于你的Windows代码-ETW可被任何组件使用,包括用户模式、驱动程序和其他内核组件。
我们经常做的一件事是编写流式ETW消费者。 我不在代码中放置printf,而是在有趣的地方放置ETW事件。当我的组件运行时,我随时可以运行我的ETW监视器-监视器接收事件并显示它们、计数它们或以其他有趣的方式处理它们。
我非常尊重地不同意tvanfosson的观点。即使最好的代码也可以从良好实施的日志记录中受益。良好实施的静态运行时日志记录可以使查找许多问题变得简单-如果没有它,您对组件中正在发生的情况没有任何可见性。您可以查看输入、输出和猜测-仅此而已。
关键在于术语“良好实施”。仪器必须放置在正确的位置。像任何其他事物一样,这需要一些思考和计划。如果不放置在有用/有趣的位置,则它将无法帮助您在开发、测试或部署场景中找到问题。您还可以过多地进行测试,导致性能问题-甚至在关闭时也会出现问题!
当然,不同的软件产品或组件将有不同的需求。有些东西可能只需要很少的仪器设备。但是广泛部署或关键组件可以从精心设计的仪器设备中获得巨大的好处。
这里有一个场景供您参考(请注意,这可能并不适用于您... :))。假设您在公司的每台桌面上都部署了一款业务应用程序 - 数百或数千个用户。当有人遇到问题时,您会怎么做?您会去他们的办公室并连接调试器吗?如果是这样,您如何知道他们使用的版本?您从哪里获取正确的符号?您如何在他们的系统上安装调试器?如果问题每隔几个小时或几天才发生一次,您会让系统一直连接着调试器运行吗?
正如您所想象的那样,在这种情况下连接调试器是具有破坏性的。
如果您的组件已经使用ETW进行了仪表化,那么您可以要求用户在问题发生时简单地打开跟踪功能,然后继续工作,最后点击"WTF"按钮。更好的是,您的应用程序可能能够自行记录日志-在运行时检测问题并自动打开日志记录。它甚至可以在出现问题时向您发送ETW文件。
这些只是简单的示例-记录可以以许多不同的方式处理。我在这里的主要建议是考虑如何通过记录来帮助您在开发时间、测试时间和部署后找到、调试和修复组件中的问题。