使用 logback 使用自定义编码器限制消息大小

Limit message size with custom encoder using logback

我正在尝试限制日志消息的大小,我成功地通过错误回溯(使用 ShortenedThrowableConverter)做到了这一点,但我没有设法找到消息本身的解决方案。

我知道一种方法是使用 <pattern/> 但是因为我是自己实现编码器。

我尝试使用布局但遇到以下错误:

no applicable action for [layout], current ElementPath  is [[configuration][appender][encoder][layout]]

这是我的一些代码:

logback.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <appender name="console-json" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="com.test.log.logback.JsonEncoder">
            <throwableConverter class="net.logstash.logback.stacktrace.ShortenedThrowableConverter">
                <maxLength>20</maxLength>
            </throwableConverter>
        </encoder>
    </appender>

    <root level="info">
        <appender-ref ref="console-json" />
    </root>

    <shutdownHook class="ch.qos.logback.core.hook.DelayingShutdownHook"/>

    <contextListener class="ch.qos.logback.classic.jul.LevelChangePropagator">
        <resetJUL>true</resetJUL>
    </contextListener>
</configuration>

编码器:

package com.test.log.logback;

import com.fasterxml.jackson.core.JsonProcessingException;
import com.fasterxml.jackson.databind.ObjectMapper;
import net.logstash.logback.stacktrace.ShortenedThrowableConverter;

import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;


public class JsonEncoder extends net.logstash.logback.encoder.LogstashEncoder {


    private String customFields;
    ShortenedThrowableConverter converter = new ShortenedThrowableConverter();
    public JsonEncoder() {
        converter.setMaxLength(10);
        setThrowableConverter(converter);
        setFieldNames(new FieldNames());
        setTimeZone("UTC");
        setFindAndRegisterJacksonModules(false);
    }   
    
}

要在使用 net.logstash.logback.encoder.LogstashEncoder 时限制 JSON 输出中的 message 字段,您需要:

  1. 禁用默认 message 字段输出
  2. 使用模式提供程序添加自定义 message 字段

例如:

<encoder class="net.logstash.logback.encoder.LogstashEncoder">
    <!-- Disable the default message field -->
    <fieldNames>
        <message>[ignore]</message>
    </fieldNames>
    <!-- Add a new message field that truncates the message to 20 characters -->
    <provider class="net.logstash.logback.composite.loggingevent.LoggingEventPatternJsonProvider">
        <pattern>{"message":"%0.-20message"}</pattern>
    </provider>
</encoder>

或作为自定义编码器:

public class JsonEncoder extends LogstashEncoder {
    @Override
    public void start() {
        // Disable the default message field
        getFieldNames().setMessage("[ignore]");

        // Add a new message field that truncates the message to 20 characters
        LoggingEventPatternJsonProvider patternProvider = new LoggingEventPatternJsonProvider();
        patternProvider.setContext(getContext());
        patternProvider.setPattern("{\"message\":\"%0.-20message\"}");
        addProvider(patternProvider);
        super.start();
    }
}

或者,您可以使用 net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder(它是 LogstashEncoder 的超类),并使用 JSON 提供商完全按照您的喜好构建 JSON 事件。参见 here

例如:

<encoder class="net.logstash.logback.encoder.LoggingEventCompositeJsonEncoder">
    <providers>
        <pattern>
            <pattern>
                {
                "timestamp": "%date{ISO8601}",
                "message":"%0.-20message"
                }
            </pattern>
        </pattern>
        <!--
            To add additional fields to the JSON output, either
            add the fields to the above pattern, or
            add additional JSON providers here.
         -->
    </providers>
</encoder>

或作为自定义编码器:

public class JsonEncoder extends LoggingEventCompositeJsonEncoder {
    @Override
    public void start() {
        getProviders().addProvider(new LoggingEventFormattedTimestampJsonProvider());

        LoggingEventPatternJsonProvider patternProvider = new LoggingEventPatternJsonProvider();
        patternProvider.setContext(getContext());
        patternProvider.setPattern("{\"message\":\"%0.-20message\"}");
        getProviders().addProvider(patternProvider);

        /*
         * To add additional fields to the JSON output, either
         * add the fields to the above pattern, or
         * add additional JSON providers here.
         */
        super.start();
    }
}