在 SLF4J/Logback 中使用标记的最佳实践

Posted

技术标签:

【中文标题】在 SLF4J/Logback 中使用标记的最佳实践【英文标题】:Best practices for using Markers in SLF4J/Logback 【发布时间】:2011-05-09 02:39:14 【问题描述】:

我们在项目中使用 SLF4J+Logback 组合已有一段时间了,对此非常满意,但我们的日志记录策略相当简单,使用简单的基于类的记录器,没有像 MDC 或 Markers 这样的花哨的东西。

我想知道社区中是否有人真正使用这些功能以及如何使用它们来改进日志记录/过滤。

我对人们在何处、为什么以及如何使用[1] 标记进行日志记录特别感兴趣。它们让我觉得这是一个非常简洁的功能,可以将语义上下文添加到日志记录中——例如虽然一个类可能处理多个关注点,但可以使用任务/关注点特定标记来区分日志语句。

在日志记录中创建和使用标记的最佳实践、约定或策略可能是什么。

更新:我想,我真正追求的不是为什么要使用标记,而是如何部分——是有一些命名标记的良好做法(例如使用带有空格或破折号/下划线/标点符号分隔的关键字样式名称的纯文本),是否应该有某种“标准名称”池,根据业务功能命名东西。这些问题我或许可以自己弄清楚,但如果我想系统地使用这些功能并将它们介绍给开发人员团队,那么围绕...制定一套正式的指导方针是有意义的。


[1] - 通过询问如何 使用 标记,我并不是真的在询问如何使用 API(这真的很简单) - 我是指更一般的水平如何设置一致地使用标记进行日志记录

【问题讨论】:

【参考方案1】:

MDC 的优点是它们在线程中被通知:让我们以一个方法的情况为例,该方法在最后发送日志。在整个方法和子方法的调用中,您可以将程序期间收集的信息填写在MDC中。 当日志在最后启动时,它包含 MDC 和我们可以放在那里的所有信息 通过适当的模式,我们可以从 MDC 中检索信息。

另一方面,标记直接与日志相关联。

【讨论】:

【参考方案2】:

作为附录,如果您正在使用 logstash 并启用了 json 日志记录,那么 Marker 还有另一个潜在用途 - 用于记录变量以与特定日志消息相关联。这比将其包含在消息正文中更一致且更易于解析。非常有用,如果它适合您的用例。

在此处查看详细信息:

https://github.com/logstash/logstash-logback-encoder#loggingevent_custom_event

【讨论】:

【参考方案3】:

首先,正如@darioo 所说:

MDC 用于将多个事件与少数“实体”相关联 [标记] 用于您希望从常规事件中过滤掉的“特殊”事件

所以你断言你想为此使用 MDC。标记用于突出“特殊”事件——过滤,如果你愿意的话——而不是“切片”。例如,您可以根据特定用户进行切片,但根据任何意外异常进行过滤。在这种情况下,您将创建一个 User MDC 维度和一个 UnexpectedException 标记。


但这显然没有解决您想到的问题。您“而是指的是更一般的级别,即如何始终如一地使用标记来设置日志记录。”所以让我们解决这个问题:

MDC 用于切片和切块,Markers 用于过滤这些活动在测试和生产过程中进行。因此,当测试/生产出现时,您需要确定您期望哪些维度可能对分割日志数据有用,以及在哪些情况下过滤它可能有用。 每个维度都有一个 MDC 维度。每个案例都有一个标记。就是这么简单。

开发人员不需要在这里做出任何决定。一个人或一个团队应该在设计时决定需要什么样的切片、切块和过滤得到支持。应该通过想象他们可能会被要求执行什么样的分析任务来了解这一点。

应该由同一个人或团队决定命名约定。 这完全是任意的。选择美观、自我描述(最重要)且具体到不太可能与以后添加的内容发生冲突的内容。连字符 vs. 下划线非常挑剔,而且令人震惊地跑题了,但请注意,ESL 员工阅读下划线可能不会那么混乱(至少与 CamelCase 相比);与此同时,据报道,这让一些开发人员感到恼火,因为他们很难找到必要的密钥。

就政策的决定而言,这只是意味着定义在哪些情况下需要使用给定的标记或 MDC 维度。保持紧密(集中、深思熟虑),但如果开发人员认为维度和标记集不足以完成手头的任务,请允许他们提供反馈。酌情修改/添加维度和/或属性。

了解此政策几乎必然是针对特定项目的。并非每个项目都需要相同类型的日志分析。想象一些噩梦般的场景。然后想象一下您希望如何分析该场景中的日志。您可能不想编写复杂的脚本来尝试跟踪哪个消息属于哪个上下文,以及哪个状态是哪个时间,对吧?将任何必要的信息编码为尺寸和标记,如果出现问题,可以省去一些麻烦。

【讨论】:

很好的答案。我认为 MDC 是一种基于线程的数据结构,也可以用于过滤。 很好的答案。但什么是ESL 员工 谢谢。英语作为第二语言。【参考方案4】:

标记可用于着色或标记单个日志语句。你用这些颜色做什么,即标记,完全取决于你。但是,标记使用的两种模式似乎很常见(第一种比第二种更常见)。

    触发:可以指示某些附加程序在存在特定标记的情况下执行操作。例如,SMTPAppender 可以配置为在日志事件被标记为NOTIFY_ADMIN 标记时发送电子邮件,无论日志级别如何。请参阅 logback 文档中的 marker-based triggering。您还可以结合日志级别和标记进行触发。

    过滤:例如,您可以使用颜色“DB”对所有与持久性相关的日志(在各种和多个类文件中)进行着色/标记。然后,您可以过滤“DB”:禁用日志记录,但标有 DB 的日志语句除外。有关详细信息,请参阅 logback 文档中的chapter on filters(搜索 MarkerFilter)。

【讨论】:

【参考方案5】:

首先,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 用于将多个事件与少数“实体”相关联 标记用于您希望从常规事件中过滤掉的“特殊”事件

【讨论】:

这是一个很好的答案,但它只涵盖了使用标记的一个可能用例。在我看来,日志框架功能(如 MDC 和标记)的存在是为了为以后的日志切片和切块提供更多元数据(如您提到的管理员电子邮件或单独的日志记录案例)。我想,我所追求的是如何准确地创建标记(是否应该有一个“标准池”标记,是否需要记住一些命名约定等) @Roland:我添加了一些示例,但我不能添加所有示例,因为根据定义,它们是无限的。如果您了解标记的动机和原因,那么使用它们仅受您的想象力和常识的限制。

以上是关于在 SLF4J/Logback 中使用标记的最佳实践的主要内容,如果未能解决你的问题,请参考以下文章

Java# 在项目中使用SLF4J+Logback来记录日志

SLF4J + logback 实现日志输出和记录

Springboot 配置Slf4j + Logback

slf4j+logback搭建超实用的日志管理模块

slf4j+logback 的配置与使用

slf4j+logback 的配置与使用