未调用 log4j 自定义 appender 停止方法

时间:2021-05-12 08:04:13

标签: java log4j log4j2

我正在尝试为 log4j 实现自定义日志附加程序,并且需要在开始之前初始化一些资源并在最后进行清理。不知何故,我的 stop 方法不会被执行。 我试过使用 LogManager.shutdown();,但我看不到我的方法被调用。

这是我的 appender 类:

@Plugin(name = "CELogAppender", category = Core.CATEGORY_NAME, elementType = Appender.ELEMENT_TYPE)
public class CELogAppender extends AbstractAppender {
    private final ConcurrentMap<String, LogEvent> eventMap = new ConcurrentHashMap<>();

    protected CELogAppender(String name, Filter filter, Layout<? extends Serializable> layout,
                            boolean ignoreExceptions, Property[] properties) {
        super(name, filter, layout, ignoreExceptions, properties);
        System.out.println("new celogappender");
    }

    public static CELogAppender createAppender(@PluginAttribute("name") String name,
                                               @PluginAttribute("Filter") Filter filter,
                                               @PluginAttribute("Layout") Layout<? extends Serializable> layout) {
        return new CELogAppender(name, filter, layout, false, null);
    }

    @Override
    public void append(LogEvent event) {
        eventMap.put(Instant.now().toString(), event);
        System.out.println("event added");
    }

    public ConcurrentMap<String, LogEvent> getEvents() {
        return eventMap;
    }

    @Override
    public void start() {
        super.start();
        System.out.println("start appender");
    }

    @Override
    public void stop() {
        super.stop();
        System.out.println("stop appender");
    }
}

这是一个简单的测试

public class CELogAppenderTests {
    private static Logger logger;
    private static CELogAppender ceLogAppender;

    @BeforeAll
    public static void setup() {
        logger = LogManager.getLogger(CELogAppenderTests.class.getName());
        LoggerContext loggerContext = LoggerContext.getContext(false);
        Configuration config = loggerContext.getConfiguration();
        PatternLayout layout = PatternLayout.newBuilder()
                .withPattern("%d{HH:mm:ss.SSS} %-5level %logger{36} - %msg%n")
                .build();
        ceLogAppender = CELogAppender.createAppender("CELogAppender", null, layout);
        ceLogAppender.start();
        config.addAppender(ceLogAppender);


        AppenderRef appenderRef = AppenderRef.createAppenderRef("CELogAppender", null, null);
        AppenderRef[] appenderRefs = new AppenderRef[]{appenderRef};
        LoggerConfig loggerConfig = LoggerConfig.createLogger(false, Level.ALL,
                CELogAppenderTests.class.getName(), "true", appenderRefs, null, config, null);

        loggerConfig.addAppender(ceLogAppender, null, null);
        config.addLogger(CELogAppenderTests.class.getName(), loggerConfig);
        loggerContext.updateLoggers();
    }

    @Test
    public void testAppenderNotEmpty() {
        logger.info("A message");
        assertFalse(ceLogAppender.getEvents().isEmpty());
    }

    @AfterAll
    public static void shutdown() {
        System.out.println("shutdown");
        LogManager.shutdown();
    }
}

我可以看到控制台输出

new celogappender
start appender
event added
shutdown

但我缺少停止方法的输出:

    @Override
    public void stop() {
        super.stop();
        System.out.println("stop appender");
    }

1 个答案:

答案 0 :(得分:0)

得到了解决方案,我不得不像这样使用/覆盖 stop 方法

@Override
public boolean stop(long timeout, TimeUnit timeUnit) {

}