使用SLF4J进行JSON日志记录时,如何包含多个JSON字段?

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

我正在使用Dropwizard 1.3.2,它通过Logback使用SLF4J进行日志记录。我正在编写日志,以便摄取到ElasticSearch中,所以我想使用JSON日志,并制作一些Kibana仪表盘。但我真的希望每条日志消息不止一个JSON项--如果我记录一个有十个字段的状态更新,我理想的情况是记录对象,并让JSON字段在JSON日志中显示为顶层条目。我确实让MDC工作了,但那是非常笨拙的,而且不能使对象扁平化。

这原来是很困难的! 我怎么才能做到这一点呢?我让它用JSON记录,但我不能很好地记录多个JSON字段!

我做过的事情。

我的Dropwizard配置有这个appender。

  appenders:
    - type: console
      target: stdout
      layout:
        type: json
        timestampFormat: "ISO_INSTANT"
        prettyPrint: false
        appendLineSeparator: true
        additionalFields:
          keyOne: "value one"
          keyTwo: "value two"
        flattenMdc: true

额外的字段出现了,但这些值似乎在配置文件中是固定的,不会改变。有一个 "customFieldNames",但没有关于如何使用它的文档,无论我在那里放什么,我都得到一个 "没有String-argument constructorfactory方法从String值反序列化 "的错误。(文档中有一个"@timestamp "的示例值,但没有解释,甚至连这个都会产生错误。他们也有像"(requestTime:request_time, userAgent:user_agent) "这样的例子,但同样没有文档,我也不能让类似的东西工作,我试过的所有东西都会产生上述错误。

我确实让MDC工作了,但是把每个项目都插入MDC中,然后再清除它,这似乎很愚蠢。

而且我可以反序列化一个对象,并将其记录为嵌套的JSON,但这看起来也很奇怪。

我看到的关于这个问题的所有答案都是旧的--有人有什么建议可以告诉我如何在Dropwizard里面很好地完成这个任务吗?

logback slf4j dropwizard structured-logging
1个回答
0
投票

你可以在Dropwizard中明确地使用logback,并使用 定制记录仪工厂,然后将其设置为 logstash-logback-encoder并将其配置为向JSON应用器写入。

JSON编码器可能是这样的。

<included>

    <encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
        <providers>
            <pattern>
                <pattern>
                    {
                      "id": "%uniqueId",
                      "relative_ns": "#asLong{%nanoTime}",
                      "tse_ms": "#asLong{%tse}",
                      "start_ms": "#asLong{%startTime}",
                      "cpu": "%cpu",
                      "mem": "%mem",
                      "load": "%loadavg"
                    }
                </pattern>
            </pattern>
            <timestamp>
                <!-- UTC is the best server consistent timezone -->
                <timeZone>${encoders.json.timeZone}</timeZone>
                <pattern>${encoders.json.timestampPattern}</pattern>
            </timestamp>
            <version/>
            <message/>
            <loggerName/>
            <threadName/>
            <logLevel/>
            <logLevelValue/><!-- numeric value is useful for filtering >= -->
            <stackHash/>
            <mdc/>
            <logstashMarkers/>
            <arguments/>
            <provider class="com.tersesystems.logback.exceptionmapping.json.ExceptionArgumentsProvider">
                <fieldName>exception</fieldName>
            </provider>

            <stackTrace>
                <!--
                  https://github.com/logstash/logstash-logback-encoder#customizing-stack-traces
                -->
                <throwableConverter class="net.logstash.logback.stacktrace.ShortenedThrowableConverter">
                    <rootCauseFirst>${encoders.json.shortenedThrowableConverter.rootCauseFirst}</rootCauseFirst>
                    <inlineHash>${encoders.json.shortenedThrowableConverter.inlineHash}</inlineHash>
                </throwableConverter>
            </stackTrace>
        </providers>
    </encoder>
</included>

Github上的文件

并产生这样的输出。

{"id":"FfwJtsNHYSw6O0Qbm7EAAA","relative_ns":20921024,"tse_ms":1584163814965,"start_ms":null,"@timestamp":"2020-03-14T05:30:14.965Z","@version":"1","message":"Creating Pool for datasource 'logging'","logger_name":"play.api.db.HikariCPConnectionPool","thread_name":"play-dev-mode-akka.actor.default-dispatcher-7","level":"INFO","level_value":20000}
© www.soinside.com 2019 - 2024. All rights reserved.