有 Java 编程相关的问题?

你可以在下面搜索框中键入要查询的问题!

java使用MDC或spring boot中的任何过滤器屏蔽日志消息中的密码,而不使用logback。xml文件

我必须在不使用logback的情况下屏蔽日志消息中的密码。springboot中的xml文件

示例日志: 记录器。信息(“用户密码:{}”,pwd)

预期产出: 2019-11-26 18:27:15951[http-nio-8080-exec-2]信息网。测验控制器。TestController-用户密码:***********

我可以使用logback实现同样的功能。xml文件。如下图所示。 但如果没有logback文件,则需要使用应用程序。spring启动中的属性配置文件

注意:不要使用log4jxml文件。我们应该使用slf4j或MDC或任何过滤器和应用程序。性质

<configuration>

    <property name="DEV_HOME" value="c:/logs" />

    <appender name="CONSOLE"
        class="ch.qos.logback.core.ConsoleAppender">
        <encoder
            class="ch.qos.logback.core.encoder.LayoutWrappingEncoder">
            <layout class="com.test.config.MaskingPatternLayout">
                <patternsProperty>(SSN)</patternsProperty>
                <pattern>%d [%thread] %-5level %logger{35} - %msg%n</pattern>
            </layout>
        </encoder>
    </appender>

    <logger name="com.test" level="debug" additivity="false">
        <appender-ref ref="CONSOLE" />
    </logger>

    <root level="error">
        <appender-ref ref="CONSOLE" />
    </root>

</configuration>

是否可以在不使用logback的情况下实现这一点。xml文件和log4j。xml文件

我们能否在应用程序属性文件中提及模式布局java类,而不是在logback中提及相同的内容。xml文件? 在上面的示例中,我在logback中提到了java文件

添加了MaskingPatternLayout以供参考:

package com.test.config;

import java.util.Optional;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import org.springframework.stereotype.Component;

import ch.qos.logback.classic.PatternLayout;
import ch.qos.logback.classic.spi.ILoggingEvent;

@Component
public class MaskingPatternTest 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(patternsProperty, Pattern.MULTILINE));
        } else {
            this.pattern = Optional.empty();
        }
    }

    @Override
    public String doLayout(ILoggingEvent event) {
        final StringBuilder message = new StringBuilder(super.doLayout(event));

        if (pattern.isPresent()) {
            Matcher matcher = pattern.get().matcher(message);
            while (matcher.find()) {

                int group = 1;
                while (group <= matcher.groupCount()) {
                    if (matcher.group(group) != null) {
                        for (int i = matcher.start(group); i < matcher.end(group); i++) {
                            message.setCharAt(i, '*');
                        }
                    }
                    group++;
                }
            }
        }
        return message.toString();
    }

}

请帮忙


共 (1) 个答案

  1. # 1 楼答案

    只要您想使用高级日志功能(而不是设置日志级别),就必须使用特定于日志库的配置,例如logback.xml用于Logback,log4j.xml用于log4j等等

    但是,Logback确实有一个可以调用的API。例如,您可以使用bean设置ConsoleAppender

    @Bean
    public LoggerContext loggerContext() {
        return (LoggerContext) LoggerFactory.getILoggerFactory();
    }
    
    @Bean
    public MaskPatternLayout maskPatternLayout(LoggerContext context) {
        MaskPatternLayout layout = new MaskPatternLayout();
        layout.setPatternsProperty("(SSN)");
        layout.setPattern("%d [%thread] %-5level %logger{35} - %msg%n");
        layout.setContext(context);
        layout.start();
        return layout;
    }
    
    @Bean
    public LayoutWrappingEncoder<ILoggingEvent> maskEncoder(MaskPatternLayout layout) {
        LayoutWrappingEncoder<ILoggingEvent> encoder = new LayoutWrappingEncoder<>();
        encoder.setLayout(layout);
        return encoder;
    }
    
    @Bean
    public ConsoleAppender<ILoggingEvent> maskConsoleAppender(LoggerContext context, LayoutWrappingEncoder<ILoggingEvent> maskEncoder) {
        ConsoleAppender<ILoggingEvent> appender = new ConsoleAppender<>();
        appender.setContext(context);
        appender.setEncoder(maskEncoder);
        appender.start();
        return appender;
    }
    

    现在您可以创建自己的LoggerFactory

    @Component
    public class MaskLoggerFactory {
        private final Appender<ILoggingEvent> appender;
    
        public MaskLoggerFactory(Appender<ILoggingEvent> appender) {
            this.appender = appender;
        }
    
        public org.slf4j.Logger getLogger(String name) {
            Logger logger = (Logger) LoggerFactory.getLogger(name);
            logger.addAppender(appender);
            logger.setLevel(Level.ALL);
            logger.setAdditive(false);
            return logger;
        }
    
        public org.slf4j.Logger getLogger(Class<?> cls) {
            return getLogger(cls.getName());
        }
    }
    

    然后,您可以自动连线MaskLoggerFactory以获得适当的Logger。然而,这并不能使事情更易于使用,如果您唯一的理由是避免创建单独的XML文件,我建议您继续使用该XML文件