Use of PatternLayout class's format(LoggingEvent event) method from a newly created Thread to execute custom log masking logic independently

75 views Asked by At

Unable to call PatternLayout class's format(LoggingEvent event) method from a newly created Thread to execute custom log masking logic independently without putting any impact on the actual functionlity. Getting multiple errors like -

  1. Compiler is asking to make the LoggingEvent object final.
  2. Unable to store the masked response into the global variable maskedOutput inside run() method, which we want to return from the format(LoggingEvent event) method.

Below is the actual code:-

public class CardNumberFilteringLayout extends PatternLayout {
    private static final String MASK = "$1++++++++++++";
    private static final Pattern PATTERN = Pattern.compile("([0-9]{4})([0-9]{9,15})");
    @Override
    public String format(LoggingEvent event) {
        if (event.getMessage() instanceof String) {
            String message = event.getRenderedMessage();
            Matcher matcher = PATTERN.matcher(message);
            if (matcher.find()) {
                String maskedMessage = matcher.replaceAll(MASK);
                @SuppressWarnings({ "ThrowableResultOfMethodCallIgnored" })
                Throwable throwable = event.getThrowableInformation() != null ? 
                        event.getThrowableInformation().getThrowable() : null;
                LoggingEvent maskedEvent = new LoggingEvent(event.fqnOfCategoryClass,
                        Logger.getLogger(event.getLoggerName()), event.timeStamp, 
                        event.getLevel(), maskedMessage, throwable);
                return super.format(maskedEvent);
            }
        }
        return super.format(event);
    }
}

As per our requirement, we are trying to change the above piece of code into below:-

@Override
public String format(LoggingEvent event) {
    String maskedOutput = null;
    new Thread(new Runnable() {
        @Override
        public void run() {
            maskedOutput = //Masking Logic(Same As Above)
        } 
    }).start();
    return maskedOutput; 
}
1

There are 1 answers

0
Piotr P. Karwasz On

Log4j 1.2 is unsupported since 2015. All modern replacements have some sort of regex substitution support.

In Log4j 2.x you can use:

<PatternLayout pattern="your_pattern">
  <Replace regex="(\d{4})\d{8}(\d{4})" replacement="$1********$2"/>
</PatternLayout>

or

<PatternLayout pattern="%replace{your_pattern}{(\d{4})\d{8}(\d{4})}{$1********$2}"/>

In Logback you can use:

<encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
  <pattern>
    %replace(your_pattern){"(\d{4})\d{8}(\d{4})", "$1********$2"}
  </pattern>
</encoder>