使用自定义布局实现时,Logback AsyncAppender不适用于FileAppender

Kar*_*n R 7 java logback asyncappender

AsyncAppender当我们FileAppender使用自定义布局实现将其链接时,Logback 不会记录日志。我用下面FileAppender与自定义实现com.myorg.log.MaskingPatternLayoutLayoutWrappingEncoder

以下是该logback.xml文件的摘要:

//Not Working with AsycnAppender
<appender name="FILE_ASYNC_CUSTOM" class="ch.qos.logback.core.FileAppender">
    <file>log/async.log</file>
    <encoder class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
        <layout class="com.myorg.log.MaskingPatternLayout">
            <patternsProperty>password,dateOfBirth</patternsProperty>
            <pattern>%d %-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
        </layout>
    </encoder>
</appender>
<appender name="ASYNC_FILE" class="ch.qos.logback.classic.AsyncAppender">
    <appender-ref ref="FILE_ASYNC_CUSTOM" />
</appender>

//Working with AsycnAppender
<appender name="FILE_ASYNC_NO_CUSTOM" class="ch.qos.logback.core.FileAppender">
    <file>log/async.log</file>
    <encoder>
        <pattern>%d %-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
    </encoder>
</appender>
<appender name="ASYNC_FILE" class="ch.qos.logback.classic.AsyncAppender">
    <appender-ref ref="FILE_ASYNC_NO_CUSTOM" />
</appender>
Run Code Online (Sandbox Code Playgroud)

以下是的自定义实现PatternLayout

@Slf4j
public class MaskingPatternLayout extends PatternLayout {

    private String patternsProperty;
    private Optional<Pattern> pattern;

    public String getPatternsProperty() {
        return patternsProperty;
    }

    public void setPatternsProperty(String patternsProperty) {
        this.patternsProperty = patternsProperty;
        if (this.patternsProperty != null) {
            this.pattern = Optional.of(Pattern.compile(getPatternToReplace(Arrays.asList(patternsProperty.split(",")))));
        } else {
            this.pattern = Optional.empty();
        }
    }

    @Override
    public String doLayout(ILoggingEvent event) {
        final StringBuilder message = new StringBuilder(super.doLayout(event));
        String maskedBody = message.toString();
        if (pattern.isPresent()) {
            Matcher matcher = pattern.get().matcher(message);
            while (matcher.find()) {
                maskedBody = maskedBody.replaceAll(matcher.group(0)
                    , matcher.group(0)
                        .replace(matcher.group(4)
                            , encode(matcher.group(4))));
            }
        }
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            log.error("Error on thread sleep: {}", e.getMessage());
        }

        return maskedBody;
    }

    private String getPatternToReplace(List<String> listToMask) {
        final StringBuilder sb = new StringBuilder();
        Optional.ofNullable(listToMask)
            .filter(test -> !test.isEmpty())
            .ifPresent((List<String> list) -> {
                sb.append(list.stream().map(String::trim).collect(Collectors.joining("|", "\"(", ")\"")));
                sb.append("(\\s)*:(\\s)*\"(.*?)\"");
            });
        return Optional.of(sb).map(StringBuilder::toString).filter(StringUtils::isNotEmpty).get();
    }

    private String encode(final CharSequence cs) {
        try {
            final byte[] csInUtf8 = Utf8.encode(cs);
            final String csString = Utf8.decode(csInUtf8);
            final String secret = "testing";

            final Integer iteration = 10;

            final Integer keyLength = 512;

            final byte[] result = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA512")
                .generateSecret(new PBEKeySpec(csString.toCharArray(), secret.getBytes(StandardCharsets.UTF_8), iteration, keyLength))
                .getEncoded();

            return Base64.getEncoder().encodeToString(result);
        } catch (final NoSuchAlgorithmException | InvalidKeySpecException ex) {
            log.error("error: {}, value: {}", ex.getMessage(), cs, ex);
            throw new RuntimeException(ex);
        }
    }

}
Run Code Online (Sandbox Code Playgroud)

预期是将事件异步记录在日志文件中,但在“ log / async.log”中未生成任何日志。但是,与此同时,当我尝试不使用FileAppender自定义布局使用时,它就可以正常工作。