首页 > 解决方案 > Logback:通过双嵌套字段

问题描述

我有一个在 Spring Boot 2 和 JDK 11 上运行的 Java Web 服务,它通过公共库中的模板文件使用 Logback。我正在使用<nestedField>标签将一些默认的 Logback 属性放置在符合 Elastic Common Schema 的位置,以及我的组织标准指定的其他位置。不幸的是,我没有成功在生成的 JSON 中嵌套多个级别的属性。请允许我举例说明。

公共库中的模板文件如下所示:

    <included>
        <appender name="MACHINE" class="ch.qos.logback.core.ConsoleAppender">

            <encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
                <providers>
                    <timestamp/>
                    <nestedField>
                        <fieldName>log</fieldName>
                        <providers>
                            <loggerName>
                                <fieldName>logger</fieldName>
                            </loggerName>
                            <logLevel>
                                <fieldName>level</fieldName>
                            </logLevel>
                        </providers>
                    </nestedField>

                    <message/>

                    <pattern>
                        <omitEmptyFields>true</omitEmptyFields>
                        <pattern>
                            <!--@formatter:off-->
                            {
                                "lots-of-other-MDC-fields-here": {...}
                            }
                            <!--@formatter:on-->
                        </pattern>
                    </pattern>

                </providers>
            </encoder>
        </appender>
    </included>

生成的 JSON 类似于:

    {
      "log": {
        "logger": "...",
        "level: "INFO"
      },
      "message": "...",
      "lots-of-other-MDC-fields-here": {...}
    }

但是,并非所有字段都仅嵌套一层。在<providers>上面最外面的标签中,我想添加以下内容:

    <nestedField>
        <fieldName>extra</fieldName>
        <providers>
            <nestedField>
            <fieldName>keywords</fieldName>
                <stackHash>
                    <fieldName>stack_hash</fieldName>
                    <exclusions>${STE_EXCLUSIONS}</exclusions>
                </stackHash>
            </nestedField>
        </providers>
    </nestedField>

这应该呈现为:

    {
      "log": {
        "logger": "...",
        "level: "INFO"
      },
      "extra": {
        "keywords": {
          "stack_hash": "something here"
        }
      },
      "message": "...",
      "lots-of-other-MDC-fields-here": {...}
    }

<nestedField>不幸的是,当我嵌套在另一个之下时,我没有做正确的事情,<nestedField>并且我没有找到任何适用的文档或示例来说明如何正确完成。我正在寻找关于如何让我的示例中呈现的配置呈现为上述输出的清晰示例。

上述示例的实际输出为:

Exception in thread "main" java.lang.IllegalStateException: Logback configuration error detected: 
ERROR in ch.qos.logback.core.joran.spi.Interpreter@67:40 - no applicable action for [stackHash], current ElementPath  is [[configuration][appender][encoder][providers][nestedField][providers][nestedField][stackHash]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@69:45 - no applicable action for [exclusions], current ElementPath  is [[configuration][appender][encoder][providers][nestedField][providers][nestedField][stackHash][exclusions]]

对于上下文,这是我的服务如何使用已部署的模板:

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <springProfile name="deployed-mode">
        <include resource="com/.../logging/logback/my-logback-template.xml"/>
        <root level="INFO">
            <appender-ref ref="MACHINE"/>
        </root>
    </springProfile>
</configuration>

标签: javaspring-bootlogback

解决方案


显然上面的格式是有效的,logstash 编码器中一定有一个错误。我一直无法确定该错误在哪里,因为它自行解决了。目前使用 logstash 编码器 6.2。如果有人更准确地知道修复此错误的方法,我将接受该答案。


推荐阅读