在 SLF4J/Logback 中使用标记的最佳实践
我们在项目中使用 SLF4J+Logback 组合已经有一段时间了,对此非常满意,但我们的日志记录策略相当简单,使用简单的基于类的记录器,没有像 MDC 或标记这样花哨的东西。
我想知道的是社区中是否有人真正使用这些功能以及如何使用它们来改进日志记录/过滤。
我对人们在哪里、为什么以及如何使用[1]标记进行日志记录特别感兴趣。它们给我的印象是一个非常简洁的功能,用于将语义上下文添加到日志记录中 - 例如,当一个类可能处理多个关注点时,可以使用任务/关注点特定标记来区分日志语句。
在测井中创建和使用标记的最佳实践、惯例或策略是什么?
更新:我想,我真正追求的并不是为什么使用标记,而是如何部分 - 有一些好的东西吗?命名标记的做法(例如使用带有空格的纯文本或破折号/下划线/标点符号分隔的关键字样式名称),是否应该有某种“标准名称”池,根据业务功能命名内容。我可能可以自己解决这些问题,但如果我想系统地使用这些功能并将它们介绍给开发团队,那么围绕...
[1] - 通过询问如何使用标记,我并不是真的在问如何使用API(它确实非常简单) - 我而是指如何设置日志记录的更一般级别始终如一地使用标记
We are using SLF4J+Logback combination at our project for a while now and are quite happy with it, but our logging strategy is fairly simple, using straightforward class based loggers and no fancy stuff like MDC or Markers.
What I want to know is if anybody in the community actually uses these features and how they are used to improve logging/filtering.
I am specially interested in where, why and how would one use[1] Markers for logging. They strike me as a pretty neat feature for adding semantic context into the logging - e.g. while a class may be handling multiple concerns, one may use task/concern specific markers to discriminate log statements.
What may be the best practices, conventions or strategies for creating and using markers in logging.
Update: I guess, what I am really after is not so much why to use markers, but rather the how part — is there some good practices of naming markers (e.g. using plain text with spaces or dash/underscore/punctuation delimited keyword style names), should there be some sort of pool of "standard names", naming stuff based on the business functions. The questions I can probably figure out for myself, but if I want to use these features systematically and introduce them to a team of developers, it makes sense to have some formalizeable set of guidelines around...
[1] - By asking how to use markers I am not really asking how to use API (it is really quite straight forward) - I am rather referring to the more general level of how would one set up logging around using markers consistently
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
首先,正如 @darioo 所说:
因此您断言您想为此使用 MDC。标记用于突出显示“特殊”事件(如果您愿意的话,可以进行过滤),而不是“切片”。例如,您可以根据特定用户进行切片,但根据任何意外异常进行过滤。在这种情况下,您将创建一个User MDC 维度和一个UnexpectedException 标记。
但这显然没有解决您想到的问题。您“更倾向于指的是如何一致地使用标记来设置日志记录的更一般级别。”因此,让我们解决这个问题:
MDC 用于切片和切块,标记用于过滤。 这些活动在测试和生产过程中进行。因此,您需要决定在测试/生产到来时,您期望哪些维度可能有助于对日志数据进行切片,以及哪些情况可能有助于对其进行过滤。 每个维度都有一个 MDC 维度。每个案例都有一个标记。就这么简单。
开发人员不需要在这里做出任何决定。单个人或团队应该在设计时决定需要支持哪种切片、切块和过滤。这应该通过想象人们期望他们可能被要求执行的分析任务类型来了解。
命名约定应由同一个人或团队决定。 这完全是任意的。选择美观、自我描述(最重要)且足够具体且不会与后续添加发生冲突的内容。连字符 与 下划线是极其挑剔的,而且离题得惊人,但请注意,对于 ESL 员工来说,阅读下划线可能不会那么混乱(至少与 CamelCase 相比);与此同时,据报道,由于难以获取必要的密钥,这让一些开发人员感到恼火。
就决定策略而言,这仅意味着定义在哪些情况下需要使用给定的标记或 MDC 维度。保持紧密(集中、深思熟虑),但如果开发人员认为尺寸和标记集不足以完成手头的任务,则允许他们提供反馈。根据需要修改/添加维度和/或属性。
了解该政策几乎必然是针对特定项目的。并非每个项目都需要相同类型的日志分析。想象一些噩梦般的场景。然后想象一下您希望如何分析该场景中的日志。您可能不想编写一个复杂的脚本来尝试跟踪哪条消息属于哪个上下文,以及在哪个时间处于哪个状态,对吧?将任何必要的信息编码为尺寸和标记,并在出现问题时为自己省去一些麻烦。
First, as @darioo said:
So your assertion that You want to use MDC for this. Markers are for highlighting "special" events--filtering, if you will--rather than "slicing". For example, you might slice based on a particular user, but filter based on any unexpected exceptions. In this case, you would create a User MDC dimension and an UnexpectedException Marker.
But this apparently doesn't address the question you had in mind. You are "rather referring to the more general level of how would one set up logging around using markers consistently." So let's address that:
MDC is for slicing and dicing, and Markers are for filtering. These activities are carried out during testing and in production. As such, you need to decide which dimensions you expect may be useful to slice the log data by, and which cases it might be useful to filter it against, when testing/production comes around. Each dimension gets an MDC dimension. Each case gets a Marker. It's as simple as that.
The developers don't need to make any decisions here. A single person or team should decide, at design time, what sort of slicing, dicing and filtering needs to be supported. This should be informed by imagining what sort of analysis tasks one expects they may be asked to perform.
This same person or team should decide on the naming convention. It's entirely arbitrary. Choose something that's aesthetically pleasing, self-descriptive (most important), and specific enough to be unlikely to conflict with later additions. Hyphens vs. underscores is exceedingly nitpicky and alarmingly beside the point, but note it may be less confusing for ESL employees to read underscores (at least compared to CamelCase); at the same time, this reportedly annoys some developers due to the awkwardness of reaching the requisite keys.
As far as deciding on a policy, this just means defining in which cases a given Marker or MDC dimension needs to be employed. Keep this tight (centralized, deliberate), but allow for feedback from developers if they feel the set of dimensions and markers are insufficient for the task at hand. Revise/add dimensions and/or attributes as appropriate.
Understand this policy will almost necessarily be project-specific. Not every project needs the same sort of logging analysis. Picture some nightmare scenarios. Then imagine how you would like to be able to analyze the logs in that scenario. You probably don't want to have to write a complicated script to try and track which message belongs to which context, and which state is which at which time, right? Encode whatever such information is necessary as dimensions and Markers, and save yourself some of the hassle if something does go wrong.
首先,MDC。
MDC 在拥有一个与某些行为相关联的“实体”的环境中确实非常有用。一个典型的例子:用户与 Web 应用程序交互。因此,假设您有很多用户在使用您的网络应用程序。使用 MDC,您可以轻松跟踪它们,而无需太多麻烦。简化示例:
在这里,您在两个地方使用 MDC:用于用户名和会话 ID。通过这种方式,您可以轻松地 grep 一个用户的会话来查看他们所做的一切。
第二,标记。
标记通常用于“特殊”情况,例如向管理员发送电子邮件以解决某些严重错误。并非所有错误都属于同一类别;有些必须以适当的方式处理。
或者,当用户退出您的服务时,它通常会转到 INFO 日志,但如果您希望此类事件放入单独的日志文件中,您也可以对此类实例使用标记,以便您可以监视它更容易统计收集用户退出情况。
经验法则:
First, MDC.
MDC is really useful in an environment where you have one "entity" that is associated with some behaviour. A typical example: user interacting with a web application. So, let's say you have many users messing around with your web app. Using MDC, you can easily track them without too much hassle. Simplified example:
Here, you're using MDC in two places: for username and for session ID. This way, you can easily grep one user's session to see everything they've been doing.
Second, markers.
Markers are usually used for "special" circumstances, such as sending an email to an administrator for some seriously critical errors. Not all errors always fall in the same category; some have to be dealt in an appropriate way.
Or, when a user quits from your service, it usually goes to an INFO log, but you can also use a marker for such instances, if you want events such as this one to go in a separate log file, so you can monitor it more easily for statistical gathering of users quitting.
Rule of thumb:
标记可用于着色或标记单个日志语句。您如何使用这些颜色(即标记)完全取决于您。然而,对于标记的使用,两种模式似乎很常见(第一种比第二种更常见)。
触发:可以指示某些附加程序在存在特定标记时采取操作。例如,可以将
SMTPAppender
配置为每当使用NOTIFY_ADMIN
标记标记日志记录事件时发送电子邮件,无论日志级别如何。请参阅 logback 文档中的基于标记的触发。您还可以组合日志级别和标记来触发。过滤:例如,您可以使用颜色“DB”对所有持久性相关日志(在各种和多个类文件中)进行颜色/标记。然后,您可以过滤“DB”:禁用日志记录,但标有 DB 的日志语句除外。有关详细信息,请参阅 logback 文档中的有关过滤器的章节(搜索 MarkerFilter)。
Markers can be used to color or mark a single log statement. What you do with these colors, i.e. markers, is entirely up to you. However, two patterns seem to be common (the first more common than the second) for marker usage.
Triggering: Some appender could be instructed to take an action in the presence of a certain marker. For example,
SMTPAppender
can be configured to send an email whenever a logging event is marked with theNOTIFY_ADMIN
marker regardless of the log level. See marker-based triggering in the logback documentation. You may also combine log levels and markers for triggering.Filtering: You could for example color/mark all your persistence related logs (in various and multiple class files) with the color "DB". You could then filter for "DB": disable logging except for log statements marked with DB. See the chapter on filters in the logback documentation for more information (search for MarkerFilter).
作为附录,如果您使用的是 Logstash 并启用了 json 日志记录,那么 Marker 还有另一个潜在用途 - 用于记录与特定日志消息关联的变量。这比将其包含在消息正文中更一致且更易于解析。非常有用,如果它适合您的用例。
请参阅此处的详细信息:
https://github.com/logstash/logstash-logback-encoder#loggingevent_custom_event
Just as an addendum, if you are using logstash and have json logging enabled, there's another potential use of Marker - for logging variables to associate with a specific log message. This is more consistent and easier to parse than including it in the message body. Very useful, if it suits your use-case.
See details here:
https://github.com/logstash/logstash-logback-encoder#loggingevent_custom_event
MDC 的优点是它们在线程中得到通知:让我们以最后发送日志的方法为例。在整个方法和子方法的调用中,您可以将程序期间收集的信息填充到MDC中。
当日志最后启动时,它包含 MDC 以及我们可以放在那里的所有信息
通过适当的模式,我们可以从 MDC 检索信息。
另一方面,标记与日志直接关联。
The advantage of MDCs is that they are informed in the thread: let's take the case of a method for which a log is sent at the end. Throughout the method and the call of the sub-methods, you can fill in the MDC with information collected during the program.
When the log is launched at the end, it contains the MDC and all the information that we could have put there
With the appropriate pattern, we can retrieve the information from the MDC.
On the other hand, the marker is directly associated with the log.