记录其他元数据

2月,在锁定之前,我在ConFoo上发表了我的Fast log演讲。 最后,我有一个有趣的问题,由于时间紧迫,我不得不缩短。 这篇博客文章旨在描述演讲的相关要点,问题以及一些可能的答案。

具有更快日志的一项改进

在本演讲中,我重点介绍了提高日志速度的不同方法。 如今,大多数日志都汇总到一个地方,以备后用。 例如,一种广泛的体系结构是基于弹性堆栈的:

天真的示例架构

尽管此设计有效,但它具有许多组件。 特别是,Logstash在这里可以解析JSON格式的原始日志行,以便Elasticsearch可以分别索引每个字段。

sample.log
2020-02-29 13:56:54.906  INFO 1 --- [  main] c.f.f.Main : Informative message
{
 "date": [[ "20-02-29" ]],
 "MONTHDAY": [[ "29" ]],
 "MONTHNUM": [[ "02" ]],
 "YEAR": [[ "20" ]],
 "time": [[ "13:56:54.906" ]],
 "HOUR": [[ "13" ]],
 "MINUTE": [[ "56" ]],
 "SECOND": [[ "54.906" ]],
 "level": [[ "INFO" ]],
 "threadName": [[ "main" ]],
 "class": [[ "c.f.f.Main" ]],
 "message":
   [[ "Informative message" ]]
}

一种改进是使用一种模式配置日志记录框架,以便它直接写入JSON格式的单行日志。 下面显示了如何使用Logback做到这一点:

logback.xml
<configuration>
  <appender name="FILE" class="ch.qos.logback.core.FileAppender">
    <file>/var/log/sample.log</file>
    <encoder>
        <pattern>{ "date": "%d{dd-MM-yy}", "time": "%d{HH:mm:ss.SSS}", "thread": "%thread", "level": "%-5level", "className": "%logger{36}", "message": "%msg" }%n</pattern>
    </encoder>
  </appender>
  <root level="debug">
    <appender-ref ref="FILE" />
  </root>
</configuration>

现在的输出如下:

/var/log/sample.log
{ "date": "29-02-20", "time": "23:13:53.640", "thread": "main", "level": "INFO", "className": "c.f.f.Main", "message": "Informative message" }

这允许将日志直接发送到Elasticsearch,从而通过完全删除Logstash来简化架构:

简化的样本架构

添加其他元数据

现在,假设企业出于日志目的还需要除日志消息之外的其他字段。 使用简单的字符串消息,这就像获取对值的引用并将其添加到字段中一样容易:

ch.frankel.fastlogs.Main
logger.info("Client-Id -> {} | Informative message",client.getId());

在正确的日志级别下执行时,将输出所需的消息:

sample.log
2020-02-29 13:56:54.906  INFO 1 --- [ main] ch.frankel.fastlogs.Main : Client-Id -> XYZ | Informative message

使用Logstash,可以改善groking模式,使其成功解析Client-Id值并将其作为专用字段发送到Elasticsearch。 不幸的是,上面显示的JSON格式的日志选项不允许这样做:

sample.log
{ "date": "29-02-20", "time": "23:13:53.640", "thread": "main", "level": "INFO", "className": "ch.frankel.fastlogs.Main", "message": "Client-Id -> XYZ | Informative message" }

注意, Client-Id与分隔符一起是message一部分。 可以将其发送到Elasticsearch并使用自定义ingester解析消息。 但是,这将对每个索引的消息花费额外的处理时间。 回到第一个方框和Logstash吗?

将诊断上下文进行救援

SLF4J和类似的框架允许通过使用MDC添加其他元数据。 简而言之, MDC是绑定到特定线程的哈希映射上下文持有者

MDC类图

可以利用MDC解决此问题。 这是一个示例代码片段:

ch.frankel.fastlogs.Main
MDC.put("client-id",client.getId());
logger.info("Informative message");
MDC.remove("client-id");

请注意,我们在日志记录语句之前明确设置了它,并在之后删除了它。 根据上下文,使用servlet过滤器自动执行操作以避免错误是有益的。 例如,Logback提供了现成的MDC筛选器来设置与请求相关的数据。

让我们稍微更新一下模式以使用MDC:

logback.xml
<pattern> { "date": "%d{dd-MM-yy}", "time": "%d{HH:mm:ss.SSS}", "thread": "%thread", "level": "%-5level", "className": "%logger{36}", "message": "%msg", "Client-Id": "%X{client-id}" }%n </pattern>

注意%X{key}语法。 这样,我们可以保持我们简单的无Logstash架构,并仍然获得所需的JSON输出:

{ "date": "29-02-20", "time": "23:13:53.640", "thread": "main", "level": "INFO", "className": "ch.frankel.fastlogs.Main", "message": "Informative message", "Client-Id": "XYZ" }

结论

通过消除对日志的解析,可以使日志变得更快。 为此,可以直接输出单行JSON消息。 当需要其他元数据时,只需使用MDC和适合日志记录实现的日志记录模式。

翻译自: https://blog.frankel.ch/logging-additional-metadata/

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值