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

时间:2010-11-12 14:22:48

标签: java logging slf4j logback markers

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

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

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

在日志记录中创建和使用标记的最佳做法,约定或策略。

更新:我想,我真正追求的不是为什么使用标记,而是 部分 - 是有一些命名标记的好方法(例如使用带空格的明文或短划线/下划线/标点符号分隔的关键字样式名称),是否存在某种“标准名称”池,根据业务功能命名。我可以为自己解决的问题,但如果我想系统地使用这些功能并将它们介绍给开发人员团队,那么就可以制定一些可以形式化的指导方针......


[1] - 通过询问如何使用标记,我并不是真的在问如何使用API​​(它真的非常直接) - 我宁愿指的是如何使用标记始终设置日志记录的更一般级别

5 个答案:

答案 0 :(得分:87)

首先,正如@darioo所说:

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

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


但这显然没有解决你想到的问题。您“更倾向于指出如何使用标记一致地设置日志记录的更一般级别。”让我们来解决:

MDC用于切片和切块,而标记用于过滤这些活动在测试和生产过程中进行。因此,您需要确定哪些维度可能对切割日志数据有用,以及在测试/生产到来时哪些维度对其进行过滤可能有用。 每个维度都有一个MDC维度。每个案例都有一个标记。就这么简单。

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

同一个人或团队应决定命名惯例。 完全随意。选择美学上令人愉悦的东西,自我描述性(最重要的),并且具体到足以与后来添加的内容冲突。连字符 vs。下划线非常挑剔且令人震惊,但请注意,ESL员工阅读下划线可能不那么令人困惑(至少与CamelCase相比);与此同时,据报道,由于到达必要钥匙的尴尬,这使一些开发人员感到恼火。

就决策而言,这仅仅意味着定义在哪种情况下需要使用给定的Marker或MDC维度。保持这种紧密(集中,慎重),但如果他们认为维度和标记的集合不足以完成手头的任务,则允许开发人员提供反馈。根据需要修改/添加尺寸和/或属性。

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

答案 1 :(得分:65)

首先,MDC。

MDC在您拥有一个与某些行为相关联的“实体”的环境中非常有用。典型示例:用户与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。通过这种方式,您可以轻松地查看一个用户的会话以查看他们一直在做的所有事情。

其次,标记。

标记通常用于“特殊”情况,例如向管理员发送电子邮件以查找严重错误。并非所有错误都属于同一类别;有些必须以适当的方式处理。

或者,当用户退出您的服务时,它通常会转到INFO日志,但如果您希望此类事件放在单独的日志文件中,您也可以对此类实例使用标记,这样您就可以了可以更轻松地监控它,以便用户退出统计数据。

经验法则:

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

答案 2 :(得分:27)

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

  1. 触发:可以指示某些appender在某个标记存在的情况下执行操作。例如,SMTPAppender可以配置为每当使用NOTIFY_ADMIN标记标记日志记录事件时发送电子邮件,而不管日志级别如何。请参阅logback文档中的marker-based triggering。您还可以将日志级别和标记组合起来进行触发。

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

答案 3 :(得分:7)

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

详情请见:

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

答案 4 :(得分:0)

MDC的优点是在线程中通知它们:让我们以在最后发送日志的方法为例。在整个方法和子方法的调用中,您可以使用在程序中收集的信息填充MDC。 当日志在末尾启动时,它包含MDC以及我们本可以放在其中的所有信息 通过适当的模式,我们可以从MDC检索信息。

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