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

Log4j2模拟附加程序

郏志诚
2023-03-14

我有一个类,我在其中获取我的所有属性,并在日志记录之前隐藏它们的密码。

@Override
public void afterPropertiesSet() throws Exception {
    Properties loadedProperties = this.mergeProperties();
    loadedProperties.entrySet().stream().forEach(singleProperty -> {
        String key = singleProperty.getKey().toString();
        String value = HIDDEN_VALUE;

        if (!Arrays.stream(PASSWORD_PATTERNS).anyMatch(pattern -> key.toLowerCase().contains(pattern))) {
            value = singleProperty.getValue().toString();                  
        }

        logger.info("LoadedProperty: "+ key +"=" + value);
    });
}

我已经迁移到log4j2,并希望测试这个类,检查log4j2的输出。它目前使用log4j并且可以工作,但是当我迁移到log4j2时,我得到了

但是,还有其他与这个mock的交互:mockappender.getName();->在org.apache.logging.log4j.core.config.AbstractConfiguration.AddLoggerAppender(AbstractConfiguration.java:675)

mockappender.getName();->在org.apache.logging.log4j.core.config.AppenderControl.(AppenderControl.java:51)

下面是我的log4j1测试类:

import org.apache.log4j.Appender;
import org.apache.log4j.LogManager;
import org.apache.log4j.spi.LoggingEvent;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.Mockito;
import org.mockito.runners.MockitoJUnitRunner;

import java.util.Properties;

@RunWith(MockitoJUnitRunner.class)
public class SpmPropertyTracerTest {

@Mock
private Appender appenderMock;

@Captor
private ArgumentCaptor captorLoggingEvent;

private SpmPropertyTracer tracer;

@Before
public void setup() {
    LogManager.getRootLogger().addAppender(appenderMock);
    tracer = new SpmPropertyTracer();
}

@After
public void teardown() {
    LogManager.getRootLogger().removeAppender(appenderMock);
}

@Test
public void printPropertiesTest() throws Exception{
    String key1 = "Foo";
    String val1 = "True";
    Properties properties = new Properties();
    properties.setProperty(key1, val1);
    tracer.setProperties(properties);
    String expectedString = String.format("LoadedProperty: %s=%s", key1, val1);
    tracer.afterPropertiesSet();
    Mockito.verify(appenderMock).doAppend((LoggingEvent)captorLoggingEvent.capture());
    LoggingEvent loggingEvent = (LoggingEvent) captorLoggingEvent.getValue();
    assert expectedString.equals(loggingEvent.getRenderedMessage());
}

}

这是我的log4j2测试类,我在log4j到log4j2的迁移中做错了什么吗?

import org.apache.logging.log4j.Level;
import org.apache.logging.log4j.LogManager;
import org.apache.logging.log4j.core.Appender;
import org.apache.logging.log4j.core.LogEvent;
import org.apache.logging.log4j.core.Logger;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;
import org.junit.runner.RunWith;
import org.mockito.ArgumentCaptor;
import org.mockito.Captor;
import org.mockito.Mock;
import org.mockito.runners.MockitoJUnitRunner;

import java.util.Properties;

import static org.junit.Assert.assertEquals;
import static org.mockito.Mockito.*;



@RunWith(MockitoJUnitRunner.class)
public class TestClass {
@Mock
private Appender mockAppender;
@Captor
private ArgumentCaptor<LogEvent> captorLoggingEvent;

private SpmPropertyTracer tracer;

private Logger logger;

private LogEvent logEvent;

@Before
public void setup() {
    // prepare the appender so Log4j likes it
    when(mockAppender.getName()).thenReturn("MockAppender");
    when(mockAppender.isStarted()).thenReturn(true);
    when(mockAppender.isStopped()).thenReturn(false);

    logger = (Logger)LogManager.getLogger(SpmPropertyTracer.class);
    logger.addAppender(mockAppender);
    logger.setLevel(Level.INFO);

    tracer = new SpmPropertyTracer();
}

@After
public void tearDown() {
    // the appender we added will sit in the singleton logger forever
    // slowing future things down - so remove it
    logger.removeAppender(mockAppender);
}

@Test
public void loggingIsCaptured() throws Exception {
    String key1 = "Foo";
    String val1 = "True";
    Properties properties = new Properties();
    properties.setProperty(key1, val1);
    tracer.setProperties(properties);
    String expectedString = String.format("LoadedProperasdfty: %s=%s", key1, val1);
    tracer.afterPropertiesSet();
    verifyErrorMessages(expectedString);
}


// handy function to inspect the messages sent to the logger
private void verifyErrorMessages(String ... messages) {
    verify(mockAppender, times(messages.length)).append((LogEvent)captorLoggingEvent.capture());

    int i=0;
    for(LogEvent loggingEvent:captorLoggingEvent.getAllValues()) {
        assertEquals(messages[i++], loggingEvent.getMessage().getFormattedMessage());
    }
}

共有1个答案

刘昌翰
2023-03-14

父项目包含了log4j依赖项,因此slf4j绑定了log4j,而不是log4j2,这就是为什么没有调用append方法的原因。删除依赖关系修复了我的错误。

 类似资料:
  • 问题内容: 我需要将事件记录到系统日志中。我使用lo4j2和syslog附加程序。我的appender阻止如下所示: 如您所见,我有一个带有特定PatternLayout的Console附加程序和RollingFile附加程序。我想对Syslog附加程序使用相同的PatternLayout。但是,系统日志中的日志消息似乎总是使用预定义的布局。我尝试执行以下操作: 但这没有任何作用。syslog消息

  • 问题内容: 我在log4j2中创建了一个自定义附加程序。使用自定义追加程序时,出现以下错误:“ ERROR试图追加到未启动的追加程序”。任何帮助表示赞赏。 问题答案: Log4j 2将检查每个日志事件附加器是否处于可用状态。您看到的错误是Log4j检测到尚未准备好使用附加程序。 一些附加器需要进行准备才能使用。在生命周期的方法是其中追加程序可以做初始化的地方。Log4j不会将事件路由到未处于STA

  • 我正在为我的web应用程序设置log4j2。问题是,这样配置的记录器没有使用Main和Err appender记录任何内容。如果通过调试器查看log4j2代码,就会发现在log4j2初始化期间没有添加这两个附加符。 以前,每个附加程序都有单独的记录器,但我们只需要一个记录器。这样做有可能吗? 类的工厂方法 以及:

  • 我有一个非常基本(几乎是教科书)的Log4J2示例,使用最新的(2.14.1): (取自官方appender文档): 程序,: <代码>pom。xml: 当我运行它时,我确实在中获得了预期的ERROR日志行;但是Java进程挂起(在完成后不会关闭)。线程转储显示(除了Java的本机线程之外)一个非守护进程异步附加线程,它仍然保持(很可能是挂起的原因)。 删除异步附加器(并直接附加到MyFile)会

  • 这是我的log4j2。xml配置文件: 输出如下所示: 缺少右方括号。如何配置log4j2以添加结束标记?