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) {
}