当前位置: 首页 > 知识库问答 >
问题:

在使用带有SLF4J的JSON日志记录时,如何包含多个JSON字段?

段干开宇
2023-03-14

原来那很难!我怎么能那样做?我将它记录在JSON中,但我不能很好地记录多个JSON字段!

我做过的事:

我的Dropwizard配置具有以下附加程序:

  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”,但没有关于如何使用它的文档,而且无论我在其中放了什么,我都会得到一个“没有字符串参数构造函数/工厂方法从字符串值反序列化”错误。(这些文档有一个“@timestamp”的示例值,但没有解释,甚至会产生错误。它们也有类似“(requesttime:request_time,useragent:user_agent)”的示例,但同样,没有文档,我无法使任何类似的工作,我所尝试的一切都会产生上面的错误。

我确实让MDC工作了,但将每个项插入MDC然后清除它似乎很愚蠢。

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

我看到的所有答案都是老生常谈的--有没有人对如何在DropWizard内部很好地完成这个任务有什么建议呢?

共有1个答案

华振
2023-03-14

您可以使用自定义记录器工厂在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}
 类似资料:
  • 在我的Java应用程序中,我使用SLF4J+Logback进行日志记录。我在开发环境中使用调试级日志记录,在生产环境中使用错误级日志记录。但是有一些消息我无论如何都想要记录下来,无论日志级别如何(类似于,但使用的是logger)。 有什么切实可行的方法可以实现这一点吗?我可以使用error或更低的级别,但我想做的是给出一些信息,所以在语义上是错误的,它不是错误。 我可以在我的中为我的类定义另一个记

  • SLF4J:类路径包含多个SLF4J绑定。 SLF4J:在[jar:file:/c:/myproject/gradle-2.3-all/gradle-2.3/lib/logback-classic-1.0.13.jar!/org/slf4j/impl/statloggerbinder.class]中找到绑定 SLF4J:在[jar:file:/c:/myproject/myproject/buil

  • 问题内容: 这是一个第三方应用程序,在我们的应用程序服务器上生成大量的登录信息。像这样: 如何关闭slf4j的输出?我已经在.war文件中查找了slf4j的一些配置,但没有找到任何配置。他们的网站也没有帮助 问题答案: slf4j只是实际日志后端(此处是覆盖jakarta commons日志记录)的一个漏斗,这是您必须配置的摆脱某种消息的程序。对于登录,这是适当的配置代码段: 对于log4j,它非

  • 问题内容: 许多人不确定如何将Liquibase的日志记录修复到控制台或文件中。 是否可以将liquibase日志记录到slf4j? 问题答案: 有,但是有点模糊。使用SLF4J和Log4J引用修复的liquibase日志记录: 有 简单的方法 ,通过在依赖下降: 现在,前两个是您的日常日志记录框架(slf4j api和log4j实现)。这些是您对标准log4j依赖项的补充,因为它们所做的只是路由

  • 因此,我正在部署一个使用Hibernate4.3.6的web应用程序。和Tomcat 7。我正在尝试使用SLF4J作为日志抽象层来日志。但是,我有很多问题和疑问。首先,Hibernate和Tomcat都有不同的日志框架,分别是jboss-logging和juli(即使我在库中找不到juli),所以我认为我必须安装从这些框架到SLF4J的桥梁。对于Hibernate,根据这个答案,一个解决方案可以是

  • 我有以下代码: 在日志中,我只能看到来自BClass而不是AClass的字段: 17:52:28.151[main]INFO Main-Main. BClass(金额=12) 但是我想查看所有BClass字段,包括父类中的字段(标题字段)。我该怎么做?