Log4j2 Demos(基础/时间&大小回滚/定期删除/日志脱敏)「建议收藏」

2022-08-23 21:01:57 浏览数 (1)

大家好,又见面了,我是你们的朋友全栈君。

前言

本章主要介绍Log4j2的几个例子与使用场景。

  • Log4j2 基础样例
  • Log4j2 文件时间&文件大小 Appender设置
  • Log4j2 日志脱敏 (重写Layout实现)
  • Log4j2 日志脱敏 (Layout Replace表达式实现)

本文所用的Demo皆可在我的git项目 https://github.com/SeanYanxml/log4j-demos 内找到。(如果觉得项目写的不错,不妨给我一个star)

Log4j2 Demos

Log4j2 Demos(普通设置)

代码语言:javascript复制
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="debug">

    <Appenders>
        <Console name="Console">
            <PatternLayout pattern="%d [%t] %-5p [%c] - %m%n" />
        </Console>

        <RollingFile name="RollingAppender" fileName="logs/hello.log" filePattern="logs/hello-{yyyy-MM-dd}-%i.log">
            <!-- logs/hello-{yyyy-MM-dd HH:mm:ss}-%i.log -->
            <ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY" />
            <PatternLayout pattern="%d [%t] %-5p [%c] - %m%n" />
            <Policies>
                <TimeBasedTriggeringPolicy interval="1" modulate="true" />
                <SizeBasedTriggeringPolicy size="100KB" />
            </Policies>
            <DefaultRolloverStrategy max="99999">
                <Delete basePath="logs" maxDepth="2">
                    <IfFileName glob="hello*.log" />
                    <!-- <IfLastModified age="2m" /> -->
                    <IfLastModified age="30d" />
                </Delete>
             </DefaultRolloverStrategy>
        </RollingFile>

    </Appenders>

    <Loggers>
        <Logger name="com.yanxml" level="DEBUG" additivity="false">
            <AppenderRef ref="Console" />
            <AppenderRef ref="RollingAppender" />
        </Logger>

        <Root level="INFO">
            <AppenderRef ref="Console" />
<!-- <AppenderRef ref="RollingAppender" /> -->        </Root>
    </Loggers>

</Configuration>
  1. 其中<DefaultRolloverStrategy max="99999">表示目录可以生成的最大文件个数为99999,默认为7.
  2. <delete/>表示删除文件的策略,上述例子表示保留30天数据.
  3. <TimeBasedTriggeringPolicy interval="1" modulate="true" />表示新日志生成间隔时间。
  4. <SizeBasedTriggeringPolicy size="100KB" />表示文件到达多大生成新日志文件或回滚。
代码语言:javascript复制
#HelloWroldLog4j2
package com.yanxml.log4j2.demos.origin;

import org.apache.logging.log4j.LogManager;

//import java.util.logging.LogManager;
import org.apache.logging.log4j.Logger;
//import org.apache.logging.log4j.LogManager;
//import org.apache.logging.log4j.Logger;

/** * The first demo to show the log4j2. * Author Sean * Date 20180529 * */

public class HelloWroldLog4j2 {
    public static Logger logger = LogManager.getLogger(HelloWroldLog4j2.class);

//  Logger logger = LogManager.getLogger(this.getClass().getName());
    public static void main(String[] args) {
        System.out.println("System Out: HelloWorld!");

//      logger.trace("Logger Level: TRACE"); 
//      logger.debug("Logger Level: DEBUG");
//      logger.info("Logger Level: INFO");
//      logger.warn("Logger Level: WARN");
        logger.error("Error1 , error2, Error3");
//      logger.error("Logger Level: ERROR 123");
//      logger.fatal("Logger Level: FATAL");

    }

}

  • Log4jTimer
代码语言:javascript复制
package com.yanxml.log4j2.demos.timer;

import java.util.TimerTask;

import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.Logger;

public class Log4jTimer extends TimerTask{ 
   

    static Logger logger = LogManager.getLogger(Log4jTimer.class);
    @Override
    public void run() {
        logger.info("Info Log ,Time:" System.currentTimeMillis() ".");
    }


}
  • Log4jOutTimerDemo
代码语言:javascript复制
package com.yanxml.log4j2.demos.timer;

import java.util.Timer;

/** * Set the timer to uptdae the xx.log . * * */
public class Log4jOutTimerDemo { 
   
    public static void main(String[] args) {
        Timer timer = new Timer();
        timer.scheduleAtFixedRate(new Log4jTimer(),1,1);
    }

}
  • log4j.xml
代码语言:javascript复制
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="debug">

    <Appenders>
        <Console name="Console">
            <PatternLayout pattern="%d [%t] %-5p [%c] - %m%n" />
        </Console>

        <RollingFile name="RollingAppender" fileName="logs/hello.log" filePattern="logs/hello-%d{yyyy-MM-dd HH:mm:ss}-%i.log">
            <!-- logs/hello-{yyyy-MM-dd HH:mm:ss}-%i.log -->
            <ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY" />
            <PatternLayout pattern="%d [%t] %-5p [%c] - %m%n" />
            <Policies>
            <!-- interval的单位 与filePattern内的最小参数有关 -->
                <TimeBasedTriggeringPolicy interval="1" modulate="true" />
<!-- <SizeBasedTriggeringPolicy size="1KB" /> -->            </Policies>
            <DefaultRolloverStrategy max="99999">
                <Delete basePath="logs" maxDepth="2">
                    <IfFileName glob="hello*.log" />
                    <!-- <IfLastModified age="2m" /> -->
                    <IfLastModified age="30d" />
                </Delete>
             </DefaultRolloverStrategy>
        </RollingFile>

    </Appenders>

    <Loggers>
        <Logger name="com.yanxml" level="DEBUG" additivity="false">
            <AppenderRef ref="Console" />
            <AppenderRef ref="RollingAppender" />
        </Logger>

        <Root level="INFO">
            <AppenderRef ref="Console" />
<!-- <AppenderRef ref="RollingAppender" /> -->        </Root>
    </Loggers>

</Configuration>

PS: 日志生成后会每秒生成一个新的日志文件。(interval根据需要进行设置)


Log4j2 Demos(敏感日志设置)

通过查看log4j2的文档,发现Layout支持Replace功能。 需要注意的是 1. 这Replace只支持内容,不支持e(即catch捕获的eroor直接输出). 2. %replace{%msg}{error|ERROR|Error}{Err**} %n就不能再设置为%msg %replace{%msg}{error|ERROR|Error}{Err**} %n,即%msg不能设置两次,否则替换失效。 3. 此法不能涵盖复杂处理的情况。

代码语言:javascript复制
    <Appenders>
        <Console name="Console">
            <PatternLayout pattern="%d [%t] %-5p [%c] - %replace{%msg}{error|ERROR|Error}{Err**} %n" />
        </Console>

        <RollingFile name="RollingAppender" fileName="logs/hello.log" filePattern="logs/hello-{yyyy-MM-dd}-%i.log">
            <ThresholdFilter level="DEBUG" onMatch="ACCEPT" onMismatch="DENY" />
            <PatternLayout pattern="%d [%t] %-5p [%c] - %replace{%msg}{error|ERROR|Error}{Err**} %n" />
            <Policies>
                <TimeBasedTriggeringPolicy interval="1" modulate="true" />
                <SizeBasedTriggeringPolicy size="100KB" />
            </Policies>
            <DefaultRolloverStrategy max="99999">
                <Delete basePath="logs" maxDepth="2">
                    <IfFileName glob="hello*.log" />
                    <!-- <IfLastModified age="2m" /> -->
                    <IfLastModified age="30d" />
                </Delete>
             </DefaultRolloverStrategy>
        </RollingFile>

    </Appenders>

### Log4j2 Demos(敏感日志设置2 自定义Layout)

  • CustomPatternLayout
代码语言:javascript复制
package com.yanxml.log4j2.demos.sensitive;

import java.nio.charset.Charset;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import org.apache.logging.log4j.core.Layout;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.config.Configuration;
import org.apache.logging.log4j.core.config.DefaultConfiguration;
import org.apache.logging.log4j.core.config.Node;
import org.apache.logging.log4j.core.config.plugins.Plugin;
import org.apache.logging.log4j.core.config.plugins.PluginAttribute;
import org.apache.logging.log4j.core.config.plugins.PluginBuilderAttribute;
import org.apache.logging.log4j.core.config.plugins.PluginBuilderFactory;
import org.apache.logging.log4j.core.config.plugins.PluginConfiguration;
import org.apache.logging.log4j.core.config.plugins.PluginElement;
import org.apache.logging.log4j.core.config.plugins.PluginFactory;
import org.apache.logging.log4j.core.layout.AbstractStringLayout;
import org.apache.logging.log4j.core.layout.ByteBufferDestination;
import org.apache.logging.log4j.core.layout.Encoder;
import org.apache.logging.log4j.core.layout.PatternSelector;
import org.apache.logging.log4j.core.pattern.LogEventPatternConverter;
import org.apache.logging.log4j.core.pattern.PatternFormatter;
import org.apache.logging.log4j.core.pattern.PatternParser;
import org.apache.logging.log4j.core.pattern.RegexReplacement;
import org.apache.logging.log4j.util.Strings;

/** * 定制的输出层,可自由组织要输出的text文本 * */
@Plugin(name = "CustomPatternLayout", category = Node.CATEGORY, elementType = Layout.ELEMENT_TYPE, printObject = true)
public class CustomPatternLayout extends AbstractStringLayout { 
   

    /** * 定制输出文本 * * @param text * @return */
    public static String customize(String text) {
        return LogUtil.customize(text);
    }

    /** * Default pattern string for log output. Currently set to the string * <b>"%m%n"</b> which just prints the application supplied message. */
    public static final String DEFAULT_CONVERSION_PATTERN = "%m%n";

    /** * A conversion pattern equivalent to the TTCCLayout. Current value is <b>%r * [%t] %p %c %notEmpty{%x }- %m%n</b>. */
    public static final String TTCC_CONVERSION_PATTERN = "%r [%t] %p %c %notEmpty{%x }- %m%n";

    /** * A simple pattern. Current value is <b>%d [%t] %p %c - %m%n</b>. */
    public static final String SIMPLE_CONVERSION_PATTERN = "%d [%t] %p %c - %m%n";

    /** Key to identify pattern converters. */
    public static final String KEY = "Converter";

    /** * Conversion pattern. */
    private final String conversionPattern;
    private final PatternSelector patternSelector;
    private final Serializer eventSerializer;

    /** * Constructs a LayoutTest using the supplied conversion pattern. * * @param config * The Configuration. * @param replace * The regular expression to match. * @param eventPattern * conversion pattern. * @param patternSelector * The PatternSelector. * @param charset * The character set. * @param alwaysWriteExceptions * Whether or not exceptions should always be handled in this * pattern (if { 
   @code true}, exceptions will be written even if * the pattern does not specify so). * @param noConsoleNoAnsi * If { 
   @code "true"} (default) and { 
   @link System#console()} is * null, do not output ANSI escape codes * @param headerPattern * header conversion pattern. * @param footerPattern * footer conversion pattern. */
    private CustomPatternLayout(final Configuration config, final RegexReplacement replace,
            final String eventPattern, final PatternSelector patternSelector, final Charset charset,
            final boolean alwaysWriteExceptions, final boolean noConsoleNoAnsi,
            final String headerPattern, final String footerPattern) {
        super(config, charset,
                createSerializer(config, replace, headerPattern, null, patternSelector,
                        alwaysWriteExceptions, noConsoleNoAnsi),
                createSerializer(config, replace, footerPattern, null, patternSelector,
                        alwaysWriteExceptions, noConsoleNoAnsi));
        this.conversionPattern = eventPattern;
        this.patternSelector = patternSelector;
        this.eventSerializer = createSerializer(config, replace, eventPattern,
                DEFAULT_CONVERSION_PATTERN, patternSelector, alwaysWriteExceptions,
                noConsoleNoAnsi);
    }

    public static Serializer createSerializer(final Configuration configuration,
            final RegexReplacement replace, final String pattern, final String defaultPattern,
            final PatternSelector patternSelector, final boolean alwaysWriteExceptions,
            final boolean noConsoleNoAnsi) {
        if (Strings.isEmpty(pattern) && Strings.isEmpty(defaultPattern)) {
            return null;
        }
        if (patternSelector == null) {
            try {
                final PatternParser parser = createPatternParser(configuration);
                final List<PatternFormatter> list = parser.parse(
                        pattern == null ? defaultPattern : pattern, alwaysWriteExceptions,
                        noConsoleNoAnsi);
                final PatternFormatter[] formatters = list.toArray(new PatternFormatter[0]);
                return new PatternSerializer(formatters, replace);
            } catch (final RuntimeException ex) {
                throw new IllegalArgumentException("Cannot parse pattern '"   pattern   "'", ex);
            }
        }
        return new PatternSelectorSerializer(patternSelector, replace);
    }

    /** * Gets the conversion pattern. * * @return the conversion pattern. */
    public String getConversionPattern() {
        return conversionPattern;
    }

    /** * Gets this LayoutTest's content format. Specified by: * <ul> * <li>Key: "structured" Value: "false"</li> * <li>Key: "formatType" Value: "conversion" (format uses the keywords * supported by OptionConverter)</li> * <li>Key: "format" Value: provided "conversionPattern" param</li> * </ul> * * @return Map of content format keys supporting LayoutTest */
    @Override
    public Map<String, String> getContentFormat() {
        final Map<String, String> result = new HashMap<>();
        result.put("structured", "false");
        result.put("formatType", "conversion");
        result.put("format", conversionPattern);
        return result;
    }

    /** * Formats a logging event to a writer. * * @param event * logging event to be formatted. * @return The event formatted as a String. */
    @Override
    public String toSerializable(final LogEvent event) {
        return eventSerializer.toSerializable(event);
    }

    @Override
    public void encode(final LogEvent event, final ByteBufferDestination destination) {
        if (!(eventSerializer instanceof Serializer2)) {
            super.encode(event, destination);
            return;
        }
        final StringBuilder text = toText((Serializer2) eventSerializer, event, getStringBuilder());

        final Encoder<StringBuilder> encoder = getStringBuilderEncoder();
        encoder.encode(text, destination);
        trimToMaxSize(text);
    }

    /** * Creates a text representation of the specified log event and writes it * into the specified StringBuilder. * <p> * Implementations are free to return a new StringBuilder if they can detect * in advance that the specified StringBuilder is too small. */
    private StringBuilder toText(final Serializer2 serializer, final LogEvent event,
            final StringBuilder destination) {
        return serializer.toSerializable(event, destination);
    }

    /** * Creates a PatternParser. * * @param config * The Configuration. * @return The PatternParser. */
    public static PatternParser createPatternParser(final Configuration config) {
        if (config == null) {
            return new PatternParser(config, KEY, LogEventPatternConverter.class);
        }
        PatternParser parser = config.getComponent(KEY);
        if (parser == null) {
            parser = new PatternParser(config, KEY, LogEventPatternConverter.class);
            config.addComponent(KEY, parser);
            parser = config.getComponent(KEY);
        }
        return parser;
    }

    @Override
    public String toString() {
        return patternSelector == null ? conversionPattern : patternSelector.toString();
    }

    /** * Creates a pattern layout. * * @param pattern * The pattern. If not specified, defaults to * DEFAULT_CONVERSION_PATTERN. * @param patternSelector * Allows different patterns to be used based on some selection * criteria. * @param config * The Configuration. Some Converters require access to the * Interpolator. * @param replace * A Regex replacement String. * @param charset * The character set. The platform default is used if not * specified. * @param alwaysWriteExceptions * If { 
   @code "true"} (default) exceptions are always written even * if the pattern contains no exception tokens. * @param noConsoleNoAnsi * If { 
   @code "true"} (default is false) and * { 
   @link System#console()} is null, do not output ANSI escape * codes * @param headerPattern * The footer to place at the top of the document, once. * @param footerPattern * The footer to place at the bottom of the document, once. * @return The LayoutTest. */
    @PluginFactory
    public static CustomPatternLayout createLayout(
            @PluginAttribute(value = "pattern", defaultString = DEFAULT_CONVERSION_PATTERN) final String pattern,
            @PluginElement("PatternSelector") final PatternSelector patternSelector,
            @PluginConfiguration final Configuration config,
            @PluginElement("Replace") final RegexReplacement replace,
            // LOG4J2-783 use platform default by default, so do not specify
            // defaultString for charset
            @PluginAttribute(value = "charset") final Charset charset,
            @PluginAttribute(value = "alwaysWriteExceptions", defaultBoolean = true) final boolean alwaysWriteExceptions,
            @PluginAttribute(value = "noConsoleNoAnsi", defaultBoolean = false) final boolean noConsoleNoAnsi,
            @PluginAttribute("header") final String headerPattern,
            @PluginAttribute("footer") final String footerPattern) {
        return newBuilder().withPattern(pattern).withPatternSelector(patternSelector)
                .withConfiguration(config).withRegexReplacement(replace).withCharset(charset)
                .withAlwaysWriteExceptions(alwaysWriteExceptions)
                .withNoConsoleNoAnsi(noConsoleNoAnsi).withHeader(headerPattern)
                .withFooter(footerPattern).build();
    }

    private static class PatternSerializer implements Serializer, Serializer2 { 
   

        private final PatternFormatter[] formatters;
        private final RegexReplacement replace;

        private PatternSerializer(final PatternFormatter[] formatters,
                final RegexReplacement replace) {
            super();
            this.formatters = formatters;
            this.replace = replace;
        }

        @Override
        public String toSerializable(final LogEvent event) {
            final StringBuilder sb = getStringBuilder();
            try {
                return toSerializable(event, sb).toString();
            } finally {
                trimToMaxSize(sb);
            }
        }

        @Override
        public StringBuilder toSerializable(final LogEvent event, final StringBuilder buffer) {
            final int len = formatters.length;
            for (int i = 0; i < len; i  ) {
                formatters[i].format(event, buffer);
            }

            // 对数据进行脱敏处理
            String strCustomize = customize(buffer.toString());
            buffer.setLength(0);
            buffer.append(strCustomize);

            if (replace != null) { // creates temporary objects
                String str = buffer.toString();
                str = replace.format(str);
                buffer.setLength(0);
                buffer.append(str);
            }
            return buffer;
        }

        @Override
        public String toString() {
            final StringBuilder builder = new StringBuilder();
            builder.append(super.toString());
            builder.append("[formatters=");
            builder.append(Arrays.toString(formatters));
            builder.append(", replace=");
            builder.append(replace);
            builder.append("]");
            return builder.toString();
        }
    }

    private static class PatternSelectorSerializer implements Serializer, Serializer2 { 
   

        private final PatternSelector patternSelector;
        private final RegexReplacement replace;

        private PatternSelectorSerializer(final PatternSelector patternSelector,
                final RegexReplacement replace) {
            super();
            this.patternSelector = patternSelector;
            this.replace = replace;
        }

        public String toSerializable(final LogEvent event) {
            final StringBuilder sb = getStringBuilder();
            try {
                return toSerializable(event, sb).toString();
            } finally {
                trimToMaxSize(sb);
            }
        }

        @Override
        public StringBuilder toSerializable(final LogEvent event, final StringBuilder buffer) {
            final PatternFormatter[] formatters = patternSelector.getFormatters(event);
            final int len = formatters.length;
            for (int i = 0; i < len; i  ) {
                formatters[i].format(event, buffer);
            }
            if (replace != null) { // creates temporary objects
                String str = buffer.toString();
                str = replace.format(str);
                buffer.setLength(0);
                buffer.append(str);
            }
            return buffer;
        }

        @Override
        public String toString() {
            final StringBuilder builder = new StringBuilder();
            builder.append(super.toString());
            builder.append("[patternSelector=");
            builder.append(patternSelector);
            builder.append(", replace=");
            builder.append(replace);
            builder.append("]");
            return builder.toString();
        }
    }

    /** * Creates a LayoutTest using the default options. These options include * using UTF-8, the default conversion pattern, exceptions being written, * and with ANSI escape codes. * * @return the LayoutTest. * @see #DEFAULT_CONVERSION_PATTERN Default conversion pattern */
    public static CustomPatternLayout createDefaultLayout() {
        return newBuilder().build();
    }

    /** * Creates a LayoutTest using the default options and the given * configuration. These options include using UTF-8, the default conversion * pattern, exceptions being written, and with ANSI escape codes. * * @param configuration * The Configuration. * * @return the LayoutTest. * @see #DEFAULT_CONVERSION_PATTERN Default conversion pattern */
    public static CustomPatternLayout createDefaultLayout(final Configuration configuration) {
        return newBuilder().withConfiguration(configuration).build();
    }

    /** * Creates a builder for a custom LayoutTest. * * @return a LayoutTest builder. */
    @PluginBuilderFactory
    public static Builder newBuilder() {
        return new Builder();
    }

    /** * Custom LayoutTest builder. Use the * { 
   @link CustomPatternLayout#newBuilder() builder factory method} to create * this. */
    public static class Builder
            implements org.apache.logging.log4j.core.util.Builder<CustomPatternLayout> {

        @PluginBuilderAttribute
        private String pattern = CustomPatternLayout.DEFAULT_CONVERSION_PATTERN;

        @PluginElement("PatternSelector")
        private PatternSelector patternSelector;

        @PluginConfiguration
        private Configuration configuration;

        @PluginElement("Replace")
        private RegexReplacement regexReplacement;

        // LOG4J2-783 use platform default by default
        @PluginBuilderAttribute
        private Charset charset = Charset.defaultCharset();

        @PluginBuilderAttribute
        private boolean alwaysWriteExceptions = true;

        @PluginBuilderAttribute
        private boolean noConsoleNoAnsi;

        @PluginBuilderAttribute
        private String header;

        @PluginBuilderAttribute
        private String footer;

        private Builder() {
        }

        // TODO: move javadocs from PluginFactory to here

        public Builder withPattern(final String pattern) {
            this.pattern = pattern;
            return this;
        }

        public Builder withPatternSelector(final PatternSelector patternSelector) {
            this.patternSelector = patternSelector;
            return this;
        }

        public Builder withConfiguration(final Configuration configuration) {
            this.configuration = configuration;
            return this;
        }

        public Builder withRegexReplacement(final RegexReplacement regexReplacement) {
            this.regexReplacement = regexReplacement;
            return this;
        }

        public Builder withCharset(final Charset charset) {
            // LOG4J2-783 if null, use platform default by default
            if (charset != null) {
                this.charset = charset;
            }
            return this;
        }

        public Builder withAlwaysWriteExceptions(final boolean alwaysWriteExceptions) {
            this.alwaysWriteExceptions = alwaysWriteExceptions;
            return this;
        }

        public Builder withNoConsoleNoAnsi(final boolean noConsoleNoAnsi) {
            this.noConsoleNoAnsi = noConsoleNoAnsi;
            return this;
        }

        public Builder withHeader(final String header) {
            this.header = header;
            return this;
        }

        public Builder withFooter(final String footer) {
            this.footer = footer;
            return this;
        }

        @Override
        public CustomPatternLayout build() {
            // fall back to DefaultConfiguration
            if (configuration == null) {
                configuration = new DefaultConfiguration();
            }
            return new CustomPatternLayout(configuration, regexReplacement, pattern,
                    patternSelector, charset, alwaysWriteExceptions, noConsoleNoAnsi, header,
                    footer);
        }
    }
}
  • LogUtil
代码语言:javascript复制
package com.yanxml.log4j2.demos.sensitive;

import lombok.extern.log4j.Log4j2;

/**日志工具类 * @author dongp * */
@Log4j2
public class LogUtil { 
   
    private static final String REGEX = "[\d]{8,15}";
    private static final String REPLACEMENT = "********";

    public static void main(String[] args) throws InterruptedException {
         String text = "asdsad13800005001asd";
// String text = "asdsad12345678asd";
        log.info(text);
        //Thread.sleep(100000);
    }

    /** * 定制输出文本 可以根据个人需求进行更改。 * * @param text * @return */
    public static String customize(String text) {
        return text.replaceAll(REGEX, REPLACEMENT);

    }
}

//2018-07-27 16:40:14 [main] INFO LogUtil:com.yanxml.log4j2.demos.sensitive.LogUtil.main(LogUtil.java:17) - asdsad********asd
  • log4j2.xml
代码语言:javascript复制
<?xml version="1.0" encoding="UTF-8"?>

<Configuration status="DEBUG" packages="com.yanxml.log4j2.demos.sensitive">

    <properties>
        <property name="logPath">log</property>
    </properties>

    <Appenders>
        <Console name="Console" target="SYSTEM_OUT">
            <CustomPatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} [%t] %-5p %c{1}:%l - %msg%n" />
        </Console>

        <RollingFile name="RollingFile" filename="${logPath}/automation.log" filepattern="${logPath}/%d{yyyyMMddHHmmss}-automation.log">
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} [%t] %-5p %c{1}:%L - %msg%n" />
            <Policies>
                <SizeBasedTriggeringPolicy size="100 MB" />
            </Policies>
            <DefaultRolloverStrategy max="20" />
        </RollingFile>

    </Appenders>
    <Loggers>
        <Root level="debug">
            <AppenderRef ref="Console" />
            <!-- <AppenderRef ref="LogFile" /> <AppenderRef ref="RollingFile" /> -->
            <!-- <AppenderRef ref="Rewrite" /> -->
        </Root>
    </Loggers>
</Configuration>

另有更改Log4j2源码包的设置,不推荐。

Reference

[1]. log4j2 java日志脱敏 [2]. 使用log4j2实现日志数据脱敏 [3]. log4j 日志脱敏处理 java properties文件加载

发布者:全栈程序员栈长,转载请注明出处:https://javaforall.cn/139688.html原文链接:https://javaforall.cn

0 人点赞