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

时间:2019-07-01 07:00:34

标签: java logback asyncappender

当我们将其与使用自定义布局实现的AsyncAppender链接时,

Logback的FileAppender未记录。我在FileAppender下面使用了com.myorg.log.MaskingPatternLayout下的LayoutWrappingEncoder的自定义实现。

下面是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>

下面是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);
        }
    }

}

预期是将事件异步记录在日志文件中,但“ log / async.log”中没有生成任何日志。但是与此同时,当我尝试使用FileAppender而不使用自定义布局时,效果很好。

0 个答案:

没有答案