[logback-user] Error counter appender

Ceki Gulcu ceki at qos.ch
Wed Feb 25 17:28:42 CET 2009


Hello Lukas,

I just added one line to your code, after errAppender.start();

   errAppender.start();
   StatusPrinter.print(lc);   <--- this is the new line of code

This resulted in the following output (edited for brevity):

INFO in c.q.l.c.LoggerContext - Could NOT find resource logback-test.xml]
INFO in c.q.l.c.LoggerContext - Could NOT find resource [logback.xml]
INFO in c.q.l.c.LoggerContext - Setting up default configuration.
ERROR in ErrorCounterAppender - No layout set for the appender named [null].

The error message explains the reasons for the behavior you are seeing.

HTH,

Lukas Zapletal wrote:
> Hello,
> 
> I need to count number of error messages coming thru SLF4J into my app and
> integrate this number with System.exit() call at the end of the program.
> 
> I have found that best solution would be to write an appender and dynamicaly
> add it in the code of my application. I am configuring logging by calling
> LoggerConfigurer (loading XML file) but I do not want to have my appender in
> this configuration - I do want to configure it dynamically not allowing user
> to modify XML and disable this error counter appender. But this does not
> work - the new appender method append() is never called. I think there is a
> problem with context or something. Here is the code:
> 
> public class Test {
> 	final org.slf4j.Logger logger =
> org.slf4j.LoggerFactory.getLogger(Test.class);
> 
> 	public void main(String[] args) {
>            String fileName = "myfile.xml";
> 	    LoggerContext lc = (LoggerContext) LoggerFactory.getILoggerFactory();
> 
> 		try {
> 			JoranConfigurator configurator = new JoranConfigurator();
> 			configurator.setContext(lc);
> 			// the context was probably already configured by default configuration
> 			// rules
> 			lc.shutdownAndReset();
> 			configurator.doConfigure(fileName);
> 
> 			ErrorCounterAppender errAppender = new ErrorCounterAppender();
> 			Logger root = LoggerFactory.getLogger(LoggerContext.ROOT_NAME);
> 			errAppender.setContext(lc);
> 			errAppender.start();
> 			((ch.qos.logback.classic.Logger) root).addAppender(errAppender);
> 			logger.error("TEST");
> 			logger.info("Number of errors: {}", errAppender.getErrorNumber()); //
> prints 0
> 			System.exit(errAppender.getErrorNumber()); // returns 0 (instead of 1)
> 
> 		} catch (Throwable t) {
> 			logger.warn("Cannot configure logger from location " + fileName, t);
> 		}
> 		StatusPrinter.print(lc);
> 	}
> 
> }
> 
> I think there must be some problem in the context or something. Or is there
> any better solution of my problem? Here is my appender:
> 
> /**
> 
>  * Thread-safe implementation of error counter appender for LogBack.
> 
>  */
> 
> public class ErrorCounterAppender extends AppenderBase<LoggingEvent> {
> 
> 
> 
> 	AtomicInteger errorCounter = new AtomicInteger(0);
> 
> 
> 
> 	private Layout<LoggingEvent> layout;
> 
> 
> 
> 	public ErrorCounterAppender() {
> 
> 	}
> 
> 
> 
> 	@Override
> 
> 	public void setLayout(Layout<LoggingEvent> layout) {
> 
> 		this.layout = layout;
> 
> 	}
> 
> 
> 
> 	public void resetErrorNumber() {
> 
> 		errorCounter.set(0);
> 
> 	}
> 
> 
> 
> 	public int getErrorNumber() {
> 
> 		return errorCounter.get();
> 
> 	}
> 
> 
> 
> 	@Override
> 
> 	public void start() {
> 
> 		if (this.layout == null) {
> 
> 			addError("No layout set for the appender named [" + name + "].");
> 
> 			return;
> 
> 		}
> 
> 		super.start();
> 
> 	}
> 
> 
> 
> 	@Override
> 
> 	public void append(LoggingEvent event) {
> 
> 		if (event == null)
> 
> 			return;
> 
> 
> 
> 		if (Level.ERROR == event.getLevel()) {
> 
> 			errorCounter.incrementAndGet();
> 
> 		}
> 
> 	}
> 
> }
> 
> 
> 
> -----
> --
> Lukas Zapletal
> http://lukas.zapletalovi.com

-- 
Ceki Gülcü
Logback: The reliable, generic, fast and flexible logging framework for Java.
http://logback.qos.ch


More information about the Logback-user mailing list