当前位置: 首页 > 知识库问答 >
问题:

在spring boot中使用MDC或任何筛选器屏蔽日志消息中的密码,而不使用logback.xml文件

贲招
2023-03-14

预期输出:2019-11-26 18:27:15,951[http-nio-8080-exec-2]INFO com.test.controller.testcontroller-用户密码:***********

我可以使用logback.xml文件实现同样的功能。如下所示。但是在Spring Boot时,需要使用application.properties配置文件,而没有logback文件。

注意:不要使用log4j xml文件。我们应该使用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>
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个答案

崔博延
2023-03-14

一旦想要使用高级日志功能(除了设置日志级别之外),就必须使用日志库特定的配置,例如Logback.xml用于日志返回,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());
    }
}
 类似资料:
  • 下面是我的请求体xml,我正在用这个请求进行rest调用。具有自定义LoggingInterceptor来记录请求和响应。我想在日志中屏蔽用户和密码。 <代码> 目前,我正在打印以下日志:

  • 问题内容: 我们的Web应用程序必须与PCI兼容,即,它不得存储任何信用卡号。该应用程序是大型机系统的前端,它在内部处理抄送号,并且-正如我们刚刚发现的那样- 有时仍会在其响应屏幕之一上吐出完整的抄送号。默认情况下,这些响应的全部内容都记录在调试级别,并且从这些响应解析的内容也可以记录在许多不同的位置。因此,我无法找到此类数据泄漏的根源。我必须确保CC号在我们的日志文件中被屏蔽。 正则表达式部分不

  • 问题内容: 当前,我们通常记录所有进出我们系统的XML文档,其中一些包含明文密码。我们希望能够配置执行此操作的logback logger / appender进行某种模式匹配或类似操作,并且如果它检测到存在替换它的密码(很可能带有星号)。注意,我们不想过滤掉日志条目,我们想掩盖其中的一部分。我很乐意提供有关如何通过注销执行此操作的建议。谢谢。 问题答案: 0.9.27版本的logback引入了替

  • 我需要能够在事件中搜索多种模式中的任何一种,并用掩码值替换模式中的文本。这是我们应用程序中的一项功能,旨在防止敏感信息落入日志。由于信息可能来自各种来源,因此对所有输入应用过滤器是不切实际的。除了日志记录之外,toString()还有其他用途,我不希望toString()对所有调用(仅日志记录)进行统一屏蔽。 我尝试在logback中使用%替换方法。xml: 这是成功的(在用字符实体替换尖括号之后

  • 我使用logback MDC来记录我的应用程序不同模块的日志,例如, logback.xml中的mdc配置 我想在不同的日志文件中记录贸易或货物sql日志,所以我想知道JOOQ是否支持这个?

  • 问题内容: 是否有可能在运行时使用MDC命名日志文件。 我有一个单独的Web应用程序,该应用程序同时使用tomcat docbase被不同的名称调用。因此,我需要为每个文件设置单独的日志文件。 问题答案: 这可以在Logback(Log4J的后继者)中完成。 Logback旨在作为流行的log4j项目的后继者,从log4j离开的地方接手。 请参阅文档筛选器 SiftingAppender在引用和配