译|Optimal Logging


找到系统故障的根本原因,需要多长时间?5分钟?还是5天?如果你的答案接近5分钟,那么你的生产系统和测试很大可能有非常好的日志记录。更常见的情况是,诸如日志、异常处理、甚至测试这类非核心的工作,被当作一种出现问题后的补救方式。同异常处理和测试一样,在系统和测试中都需要日志记录的策略。永远不要低估日志的作用。最佳的日志记录,甚至可以替代调试器。以下是这些年来对我有用的一些指导原则。

保持适度

切勿记录过多。日志占用大量的磁盘空间说明你没有想过应该记录什么。如果记录太多,则需要设计复杂的方法以减少磁盘访问、保留日志历史记录、归档大量数据以及查询大型日志数据集。更重要的是,很难在啰嗦的数据中找出有价值的信息。

记录太少比记录太多更糟糕,记录的过少。日志记录通常有两个主要目标:帮助进行错误调查和事件确认。如果您的日志无法解释错误的原因或某个事务是否发生,则说明日志记录太少。

要记录的:

  • 重要启动配置
  • 错误
  • 警告
  • 对持久化数据的更改
  • 主要系统组件间的请求和响应
  • 重要的状态变化
  • 用户交互
  • 具有已知失败风险的调用
  • 可能需要一定时间才能满足条件的等待
  • 长时间运行任务的定期进度
  • 逻辑的重要分支点和导致分支的条件
  • 高层级函数的”处理步骤”和”事件”的摘要——避免在低层级函数中记录复杂过程的每个步骤。

不适合记录的:

  • 函数入口——不要记录函数入口,除非重要或者以调试级别记录日志。
  • 循环中的数据——避免在循环的多次迭代中记录日志。在小循环的迭代或大循环中定期记录日志是可以的。
  • 大型消息或文件的内容——以对调试有用的方式截断或汇总数据。
  • 良性错误——那些不是真正错误的错误会让阅读日志的人感到困惑。当异常处理是成功的执行流程的一部分,有时会发生。
  • 重复的错误——不要重复的记录相同或相似的错误。这样会快速的填满日志,并且隐藏掉真正的问题。错误类型的频率最好通过监控来处理。日志只需要捕获部分错误的详细信息

多个日志级别

不要以同一日志级别记录所有内容。大多数日志库都提供几种日志级别,可以在系统启动时启用某些级别。这样可以方便的控制日志详细程度。

典型的级别有:

  • Debug:详细,只有在开发或调试时有用。
  • Info:最常见的级别。
  • Warning:奇怪或意外但可接受的状态。
  • Error:有错误发生,但进程可以恢复。
  • Critical:进程无法恢复,系统将关闭或者重启。

实际上,只需要两种日志配置:

  • 生产:除调试级别外,所有级别都已启用。如果生产中出了问题,日志应该能揭示原因。
  • 开发、调试:编写新代码或是尝试复现问题时,打开全部级别。

测试日志同样重要

测试和生产代码的日志质量同样重要。当测试失败时,日志应当明确的显示失败是来自测试还是生产系统。如果做不到,那么测试的日志是有问题的。

测试日志应该包括:

  • 测试执行环境
  • 初始状态
  • 设置步骤
  • 测试用例步骤
  • 与系统的交互
  • 期望的结果
  • 实际的结果
  • 清理步骤

利用临时日志队列实现基于条件的详细程度控制

当发生错误时,日志应该包含很多细节。不幸的是,一旦遇到错误,导致错误发生的详细信息可能已经无法获得了。另外,如果遵从“不要过多记录日志”的建议,在错误记录之前的日志记录可能无法提供足够的细节。一个解决这个问题的好方法是,在内存中创建临时的日志队列。在事务处理的整个过程中,将每一步的详尽信息追加到队列中。如果事务成功完成,则丢弃队列记录摘要。如果遇到错误,请记录整个队列的内容和错误。该技术对于系统交互的测试日志记录特别有用。

失败和不可靠都是机遇

当生产问题出现时,你会专注于寻找和修复问题,但你还应该想到日志。如果你费了很大力气才找到错误的原因,这将是个非常好的机会来改善你的日志。在解决问题之前,先修复日志,以便日志清楚地显示原因。如果该问题再发生,就更容易识别了。

如果无法复现问题,或者有一个不可靠的测试。增强日志,以便在问题再次发生时跟踪问题。

在整个开发过程中,应该使用失败来改进日志记录。在编写新代码时,尽量避免使用调试器,只使用日志。日志能够显示发生了什么吗?如果不能,日志记录就不充分。

最好记录性能数据

记录的计时数据可以帮助调试性能问题。例如,在大型系统中确定超时的原因可能非常困难,除非您可以跟踪每个重要处理步骤所花费的时间。这可以通过记录调用的开始和结束时间来轻松完成,可能会比较耗时的调用包括:

  • 重要的系统调用
  • 网络请求
  • CPU密集运算
  • 连接设备的交互
  • 事务

在多线程/进程中追踪痕迹

为涉及跨多个线程和/或进程处理的事务创建唯一标识符。事务的发起方应该创建ID,并且将它传递给为事务执行工作的每个组件。在记录有关事务的信息时,每个组件都应该记录这个ID。在并发处理多个事务时,跟踪特定事务更加容易。

监控和日志相辅相成

生产服务应该同时具有日志记录和监控功能。监控提供系统状态的实时统计摘要。在某些请求类型出现一定比例失败、遇到异常流量模式、性能下降或者其他异常情况发生时,向你发出警报。在某些情况下,仅此信息就可以显示问题的原因。但是,在大多数情况下,监控警报只是启动调查的触发器。监控显示问题的症状;日志提供单个事务的详细信息和状态,据此您可以完全理解问题的原因。

原文: Optimal Logging

本文作者:cyningsun
本文地址https://www.cyningsun.com/12-27-2020/optimal-logging-cn.html
版权声明:本博客所有文章除特别声明外,均采用 CC BY-NC-ND 3.0 CN 许可协议。转载请注明出处!