我们在我们的项目中使用 SLF4J+Logback 组合有一段时间了,并且对它非常满意,但是我们的日志记录策略相当简单,使用简单的基于类的记录器,没有像 MDC 或标记这样的花哨的东西。
我想知道的是社区中是否有人真正使用这些功能以及如何使用它们来改进日志记录/过滤。
我对在哪里、为什么以及如何使用[1] 标记进行日志记录特别感兴趣。它们给我留下了深刻的印象,可以将语义上下文添加到日志记录中 - 例如,虽然一个类可能处理多个关注点,但可以使用任务/关注点特定标记来区分日志语句。
在日志记录中创建和使用标记的最佳实践、约定或策略可能是什么。
更新:我想,我真正追求的不是为什么要使用标记,而是如何使用部分 - 是否有一些命名标记的良好做法(例如,使用带有空格或破折号/下划线/标点分隔的关键字样式名称的纯文本),是否应该有某种“标准名称”池,根据业务功能命名东西。我可能自己可以弄清楚这些问题,但是如果我想系统地使用这些功能并将它们介绍给开发人员团队,那么围绕...制定一些正式的指导方针是有意义的。
[1] - 通过询问如何使用标记,我并不是真的在询问如何使用 API(这真的很简单) - 我更倾向于指的是更一般的级别,即如何始终如一地使用标记来设置日志记录
首先,正如@darioo 所说:
MDC 用于将多个事件与少数“实体”相关联
[标记] 用于您希望从常规事件中过滤掉的“特殊”事件
所以你断言你想为此使用 MDC。标记用于突出“特殊”事件——过滤,如果你愿意的话——而不是“切片”。例如,您可以根据特定用户进行切片,但根据任何意外异常进行过滤。在这种情况下,您将创建一个用户 MDC 维度和一个 UnexpectedException 标记。
但这显然没有解决您想到的问题。您“而是指的是更一般的级别,即如何始终使用标记来设置日志记录。”所以让我们解决这个问题:
MDC 用于切片和切块,Markers 用于过滤。这些活动在测试和生产期间进行。因此,当测试/生产出现时,您需要确定您期望哪些维度可以用于对日志数据进行切片,以及在哪些情况下过滤它可能有用。每个维度都有一个 MDC 维度。每个案例都有一个标记。就这么简单。
开发人员不需要在这里做出任何决定。一个人或一个团队应该在设计时决定需要支持哪种切片、切块和过滤。这应该通过想象他们可能会被要求执行什么样的分析任务来了解。
同一个人或团队应决定命名约定。这完全是任意的。选择美观的、自我描述的(最重要的)和足够具体的东西,不太可能与后来的添加冲突。连字符与下划线非常挑剔,而且令人震惊地跑题了,但请注意,ESL 员工阅读下划线可能不会那么混乱(至少与 CamelCase 相比);与此同时,据报道,这让一些开发人员感到恼火,因为他们很难找到必要的密钥。
就决定策略而言,这仅意味着定义在哪些情况下需要使用给定的标记或 MDC 维度。保持紧密(集中、深思熟虑),但如果开发人员认为一组维度和标记不足以完成手头的任务,请允许他们提供反馈。酌情修改/添加维度和/或属性。
了解这项政策几乎必然是针对特定项目的。并非每个项目都需要相同类型的日志分析。想象一些噩梦般的场景。然后想象一下您希望如何分析该场景中的日志。您可能不想编写复杂的脚本来尝试跟踪哪个消息属于哪个上下文,以及哪个状态是哪个时间,对吧?将任何必要的信息编码为尺寸和标记,如果出现问题,可以为自己省去一些麻烦。
首先,MDC。
MDC 在您拥有一个与某些行为相关联的“实体”的环境中非常有用。一个典型的例子:用户与 Web 应用程序交互。因此,假设您有很多用户在使用您的 Web 应用程序。使用 MDC,您可以轻松地跟踪它们而无需太多麻烦。简化示例:
...[Sandy][abcd] clicked on "change profile"
...[Joe][1234] clicked on "weather reports"
...[Joe][1234] clicked on "Europe"
...[Sandy][abcd] clicked on "logout"
...[Joe][1234] clicked on "logout"
...[Sandy][efgh] logged in
在这里,您在两个地方使用 MDC:用于用户名和会话 ID。这样,您可以轻松地 grep 一个用户的会话以查看他们所做的一切。
第二,标记。
标记通常用于“特殊”情况,例如针对某些严重的严重错误向管理员发送电子邮件。并非所有错误都属于同一类别;有些必须以适当的方式处理。
或者,当用户退出您的服务时,它通常会转到 INFO 日志,但您也可以为此类实例使用标记,如果您希望此类事件进入单独的日志文件,以便您可以监控它更容易对用户退出统计进行统计。
经验法则:
MDC 用于将多个事件与少数“实体”相关联
标记用于您希望从通常事件中过滤掉的“特殊”事件
标记可用于为单个日志语句着色或标记。您如何处理这些颜色(即标记)完全取决于您。然而,对于标记的使用,两种模式似乎很常见(第一种比第二种更常见)。
触发:可以指示某些附加程序在存在某个标记的情况下执行操作。例如,可以将 SMTPAppender 配置为在日志事件被标记为 NOTIFY_ADMIN 标记时发送电子邮件,而不管日志级别如何。请参阅 logback 文档中的基于标记的触发。您还可以组合日志级别和标记以进行触发。过滤:例如,您可以使用颜色“DB”对所有与持久性相关的日志(在各种和多个类文件中)进行颜色/标记。然后,您可以过滤“DB”:禁用日志记录,但标有 DB 的日志语句除外。有关更多信息,请参阅 logback 文档中有关过滤器的章节(搜索 MarkerFilter)。
就像附录一样,如果您正在使用 logstash 并启用了 json 日志记录,那么 Marker 还有另一个潜在用途 - 用于记录变量以与特定日志消息相关联。这比将其包含在消息正文中更一致且更易于解析。非常有用,如果它适合您的用例。
在此处查看详细信息:
https://github.com/logstash/logstash-logback-encoder#loggingevent_custom_event
MDC 的优点是它们在线程中被通知:让我们以一个方法的情况为例,该方法在最后发送日志。在整个方法和子方法的调用中,您可以将程序期间收集的信息填写在MDC中。最后启动日志时,它包含 MDC 和我们可以放在那里的所有信息 使用适当的模式,我们可以从 MDC 检索信息。
另一方面,标记直接与日志相关联。