I am trying to implement a custom log appender for log4j and will need to initialize some resources before start and cleanup at the end. Somehow my stop method will not be executed.
I’ve tried using LogManager.shutdown();
but I cannot see my method getting called.
This is my appender class:
@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"); } }
And this is a simple test
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(); } }
I can see the console output
new celogappender start appender event added shutdown
but I am missing the output from my stop method:
@Override public void stop() { super.stop(); System.out.println("stop appender"); }
Advertisement
Answer
Got the solution, I had to use/override the stop method like this
@Override public boolean stop(long timeout, TimeUnit timeUnit) { }