使用 Json 模板布局 log4j2 在 json 日志中写入序列号时处理异常堆栈跟踪

问题描述 投票:0回答:1

我正在使用 json 模板布局 通过 kinesis firehose 和 firelens 将我的 ecs 服务的 json 日志写入到 s3。

以下是我正在使用的json模板布局的配置-

{
   "context_map": {
       "$resolver": "mdc"
   },
   "serial_no": {
     "$resolver": "pattern",
     "pattern": "%sn"
   },
   "timestamp": {
     "$resolver": "timestamp",
     "pattern": {
       "format": "yyyy-MM-dd'T'HH:mm:ss.SSS'Z'",
       "timeZone": "UTC"
     }
   },
   "level": {
     "$resolver": "level",
     "field": "name"
   },
   "logger_name": {
     "$resolver": "logger",
     "field": "name"
   },
   "message": {
     "$resolver": "message",
     "stringified": true
   },
   "thread": {
     "$resolver": "thread",
     "field": "name"
   },
   "exception": {
     "exception_class": {
       "$resolver": "exception",
       "field": "className"
     },
     "exception_message": {
       "$resolver": "exception",
       "field": "message",
       "stringified": true
     },
     "stacktrace": {
       "$resolver": "exception",
       "field": "stackTrace",
       "stringified": true
     }
   },
   "class": {
     "$resolver": "source",
     "field": "className"
   }
 }

以下是日志配置的快照 -

     Console:
       - Name: Console
         Target: SYSTEM_OUT
         JsonTemplateLayout:
           eventTemplateUri: "file:/opt/amazon/log-configuration/JsonLayoutTemplate.json"
           prettyPrintEnabled: true
           stackTraceEnabled: true

以下是异常情况下生成的示例日志 -

{
    "container_id": "1f1319d278264d3dwewdeddewdewdewdew-849099158",
    "container_name": "test-container",
    "context_map": {
        "RequestId": "28289758-ab3b-4f8c-b3f1-freferfc"
    },
    "exception": {
        "exception_class ": "com.xyz.exception”,
        "exception_message": "Problem processing the SQS message with body helllo world, exception: Error while deserializing the message from test - message - queue.",
        "stacktrace": "com.xyz.exception: Problem processing the SQS message with body helllo world, exception: Error while deserializing the message from test - message - queue.\n\ .... stackTrace”
    },
    "level": "ERROR”,
    "logger_name": "com.xyz.handler",
    "message": "Seems to be impossible to process message: helllo world",
    "serial_no": "52 com.xyz.handler: Problem processing the SQS message with body helllo world, exception: Error while deserializing the message from test - message - queue.\n\ .... stackTrace",
    "source": "stdout",
    "thread": "test-thread",
    "timestamp": "2021-04-06 T14:30:02.122 Z"
}

根据文档

Pattern Resolver delegates to PatternLayout
和图案布局提供
%sn
用于获取序列号。

我们确实需要序列号,因为我们可以同时获取很多日志,所以为了区分日志,我们在 AWS Athena 中查询日志时将依赖这些 json 日志中的序列号、requestId 参数。

另外,我见过一些序列号为空的日志实例(不是异常日志)

如何防止serial_no在其中包含异常堆栈跟踪? 并确保我始终在日志中获得serial_no字段?

logging log4j log4j2 fluentd fluent-bit
1个回答
2
投票

当您通过

JsonTemplateLayout
解析器将
PatternLayout
委托给
pattern
时,
LogEvent
会按原样传递。一旦
PatternLayout
发现
LogEvent
附加了异常,它会将堆栈跟踪附加到发出的输出,因为创建的
PatternLayout
实例继承了您为
stackTraceEnabled=true
设置的
JsonTemplateLayout
标志。因此,您需要禁用
PatternLayout
的堆栈跟踪,如下所示:

{
  "$resolver": "pattern",
  "pattern": "%sn",
  "stackTraceEnabled": false
}

请注意,这仍然会产生

string
类型的序列号。如果要生成
number
类型的序列号,可以按以下方式使用
timestamp
解析器:

{
  "$resolver": "timestamp",
  "epoch": {
    "unit": "nanos",
    "rounded": true
  }
}

同时,我创建了 LOG4J2-3067 以将序列号解析器添加到

JsonTemplateLayout

© www.soinside.com 2019 - 2024. All rights reserved.