日志级别—重新登录—分配日志级别的经验法则

我在当前的项目中使用logback

它提供了六个级别的日志记录:TRACE DEBUG INFO WARN ERROR OFF

我正在寻找一个经验法则来确定常见活动的日志级别。 例如,如果线程被锁定,日志消息应该被设置为调试级别还是信息级别。 或者如果一个套接字正在被使用,它的特定id是否应该记录在调试级别或跟踪级别

对于每个日志级别,我将提供更多的示例。

159046 次浏览

我主要构建大规模、高可用性类型的系统,所以我的回答偏向于从生产支持的角度来看待它;也就是说,我们大致分配如下:

  • 错误:系统处于困境,客户可能正在受到影响(或即将受到影响),修复可能需要人工干预。“凌晨2点规则”适用于此——如果你是随叫随到的人,如果发生这种情况,你想在凌晨2点被叫醒吗?如果是,则将其记录为“错误”。

  • warn:发生意外的技术或业务事件,客户可能受到影响,但可能不需要立即人工干预。你不会马上打电话给随时待命的人员,但是支持人员会希望尽快检查这些问题,以了解影响。基本上,任何需要跟踪但不需要立即干预的问题。

  • info:我们希望在高容量下看到的东西,以防我们需要对问题进行取证分析。系统生命周期事件(系统启动,停止)在这里。“会话”生命周期事件(登录、注销等)在这里。重要的边界事件也应该考虑在内(例如数据库调用,远程API调用)。典型的业务异常可能出现在这里(例如,由于糟糕的凭据而导致登录失败)。你认为在大批量生产中需要看到的任何其他事件都可以在这里看到。

  • debug:几乎所有没有使“信息”削减…任何有助于跟踪系统流程和隔离问题的信息,特别是在开发和QA阶段。我们使用“调试”级别的日志来进入/退出大多数非平凡的方法,并在方法中标记有趣的事件和决策点。

  • trace:我们不经常使用,但这将用于非常详细和潜在的高容量日志,即使在正常的开发过程中,您通常也不希望启用这些日志。例如,转储完整的对象层次结构,在大型循环的每次迭代期间记录某些状态,等等。

与选择正确的日志级别同样重要或更重要的是确保日志是有意义的并且具有所需的上下文。例如,您几乎总是希望在日志中包含线程ID,以便在需要时跟踪单个线程。您可能还想使用一种机制将业务信息(例如用户ID)关联到线程,这样它也会被记录下来。在日志消息中,您需要包含足够的信息,以确保消息是可操作的。像“FileNotFound异常捕获”这样的日志没有多大帮助。更好的消息是“试图打开配置文件:/usr/local/app/somefile.txt时捕获FileNotFound异常”。用户id = 12344。”

还有很多好的日志记录指南……例如,下面是来自JCL(雅加达公共伐木业)的编辑片段:

  • error -其他运行时错误或意外情况。期望这些在状态控制台上立即可见。
  • warn -使用废弃的API,糟糕的API使用,'almost'错误,其他不希望或意外的运行时情况,但不是 一定是“错误的”。期望这些立即可见 地位控制台。李< / >
  • info -有趣的运行时事件(启动/关闭)。希望这些内容能够在主机上立即呈现出来,所以要保持保守 最低。李< / >
  • 调试-关于流经系统的流程的详细信息。期望这些只被写入日志。
  • Trace -更详细的信息。期望这些只被写入日志。

我的方法,我认为更多地是从开发而不是运营的角度来看的,是:

  • 错误表示某些任务的执行无法完成;邮件无法发送,页面无法呈现,数据无法存储到数据库中,诸如此类。肯定出了什么问题。
  • 警告意味着发生了意想不到的事情,但执行可以继续,可能是在降级模式下;一个配置文件丢失了,但使用了默认值,价格被计算为负数,所以它被钳制为零,等等。有些东西是不对的,但它还没有完全出错——警告通常是很快就会出现错误的迹象。
  • 信息表示发生了一些正常但重要的事情;系统启动,系统停止,每日库存更新作业运行,等等。不应该有持续不断的洪流,否则就会有太多的阅读。
  • 调试表示发生了一些正常且无关紧要的事情;一个新用户来到这个站点,一个页面被呈现,一个订单被接受,一个价格被更新。这是被排除在信息之外的东西,因为它太多了。
  • 跟踪是我从来没有实际使用过的东西。

与其他答案没有什么不同,我的框架几乎有相同的层次:

  1. 错误:应用程序上的严重逻辑错误,如数据库连接超时。在不久的将来需要修复的事情
  2. 警告:不是破坏性的问题,但需要注意。比如请求的页面找不到
  3. Info:用于函数/方法的第一行,显示已调用的过程或已执行的步骤,如完成插入查询
  4. 日志:逻辑信息,如if语句的结果
  5. 调试:永久监视相关的变量内容

我从一个基于组件的架构来回答这个问题,在这个架构中,一个组织可能运行许多相互依赖的组件。在传播故障期间,日志级别应该有助于识别哪些组件受到影响,哪些是根本原因。

  • ERROR -该组件有一个失败,原因被认为是内部的(任何内部的,未处理的异常,封装依赖的失败…例如,数据库,REST的例子将是它已经收到一个4xx错误从一个依赖)。让我(这个组件的维护者)起床。

  • WARN -该组件有一个被认为是由依赖组件引起的失败(REST示例将是依赖组件的5xx状态)。让那个组件的维护者起床。

  • INFO -我们想要得到一个运算符的任何其他东西。如果你决定记录快乐的路径,那么我建议限制每个重要操作(例如每个传入的http请求)只记录一条日志消息。

对于所有日志消息,请确保记录有用的上下文(并优先考虑使消息成为人类可读/有用的消息,而不是有大量的“错误代码”)

  • 调试(及以下)——根本不应该使用(当然也不应该在生产环境中使用)。在开发中,我建议使用TDD和调试(必要时)的组合,而不是用日志语句污染代码。在生产环境中,上面的INFO日志记录与其他指标相结合就足够了。

可视化上述日志级别的一个好方法是为每个组件想象一组监视屏幕。当所有运行正常时,它们是绿色的,如果一个组件记录了一个警告,那么它将变成橙色(琥珀色),如果任何组件记录了一个错误,那么它将变成红色。

在发生事故时,您应该让一个(根本原因)组件变成红色,而所有受影响的组件应该变成橙色/琥珀色。

这也可能有一定的帮助,以理解某个级别的日志记录请求(来自代码)是否会导致部署配置的有效的日志记录级别实际被记录。从这里的其他答案中决定你想要配置部署的有效的级别,然后参考这个,看看你代码中的特定日志请求是否真的会被记录,然后…

为例子:

  • “在WARN上记录日志的日志代码行实际上会在配置为ERROR的部署上被记录吗?”桌子说,不。
  • “在WARN上记录日志的日志代码行实际上会在配置了DEBUG的部署上被记录吗?”桌子说,是的。

logback文档:

以更形象的方式,下面是选择规则的工作方式。在下表中,垂直标头显示日志记录请求的级别,由p指定,而水平标头显示记录器的有效级别,由q指定。行(级别请求)和列(有效级别)的交集是由基本选择规则产生的布尔值。 enter image description here < / p >

因此,请求日志记录的代码行只有在其部署的有效的日志级别小于或等于该代码行的要求严重级别时才会实际被记录。