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:
JavaScript
x
@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
JavaScript
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
JavaScript
new celogappender
start appender
event added
shutdown
but I am missing the output from my stop method:
JavaScript
@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
JavaScript
@Override
public boolean stop(long timeout, TimeUnit timeUnit) {
}