Friday 25 February 2022

Logback: appenders

Using Logback, we can publish the log messages to different destinations. In Logback world, output destination is specified by an appender. Logback supports variety of appenders to publish messages.

 

Following is the list of appenders supported by Logback.

a.   console,

b.   files,

c.    remote socket servers,

d.    MySQL, PostgreSQL, Oracle and other databases,

e.   JMS, and

f.     remote UNIX Syslog daemons etc.,

 

Can I attach more than one appender to a logger?

Yes, you can.

 

You can configure an appender either programmatically using addAppender method or via configuration.

 

Let’s see it with an example.

 

AppenderDemo.java

package com.sample.app;

import org.slf4j.LoggerFactory;

import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.FileAppender;

public class AppenderDemo {

	public static void main(String[] args) {

		ch.qos.logback.classic.Logger logger = (ch.qos.logback.classic.Logger) LoggerFactory
				.getLogger(HelloWorld.class);

		LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
		PatternLayoutEncoder ple = new PatternLayoutEncoder();

		ple.setPattern("%date %level [%thread] %logger{10} [%file:%line] %msg%n");
		ple.setContext(loggerContext);
		ple.start();
		FileAppender<ILoggingEvent> fileAppender = new FileAppender<ILoggingEvent>();
		fileAppender.setFile("/Users/Shared/logback/app.log");
		fileAppender.setEncoder(ple);
		fileAppender.setContext(loggerContext);
		fileAppender.start();

		logger.addAppender(fileAppender);
		logger.setAdditive(false);

		logger.trace("Trace message");
		logger.debug("Debug message");
		logger.info("Info message");
		logger.warn("Warning message");
		logger.error("Error message");

	}
}

 

Run above application, and open the file /Users/Shared/logback/app.log to see the log messages.

$cat app.log 
2022-02-20 12:35:30,219 DEBUG [main] c.s.a.HelloWorld [AppenderDemo.java:33] Debug message
2022-02-20 12:35:30,221 INFO [main] c.s.a.HelloWorld [AppenderDemo.java:34] Info message
2022-02-20 12:35:30,221 WARN [main] c.s.a.HelloWorld [AppenderDemo.java:35] Warning message
2022-02-20 12:35:30,221 ERROR [main] c.s.a.HelloWorld [AppenderDemo.java:36] Error message
$

 

When you rerun the application, you can observe that the log messages are appended to app.log file.

 


Appender additivity

The output of a log statement of logger L1 will go to all the appenders of L1 and its ancestors.

 

Let’s see it with an example.

 

AppenderAdditivity.java

package com.sample.app;

import org.slf4j.LoggerFactory;

import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.FileAppender;

public class AppenderAdditivity {

	private static Logger getLogger(String name) {
		Logger logger = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(name);

		LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
		PatternLayoutEncoder ple = new PatternLayoutEncoder();

		ple.setPattern("%date %level [%thread] %logger{10} [%file:%line] %msg%n");
		ple.setContext(loggerContext);
		ple.start();
		FileAppender<ILoggingEvent> fileAppender = new FileAppender<ILoggingEvent>();
		fileAppender.setFile("/Users/Shared/logback/" + name + ".log");
		fileAppender.setEncoder(ple);
		fileAppender.setContext(loggerContext);
		fileAppender.start();

		logger.addAppender(fileAppender);

		return logger;
	}

	public static void main(String[] args) {

		Logger loggerA = getLogger("A");
		Logger loggerADotB = getLogger("A.B");
		Logger loggerADotBDotC = getLogger("A.B.C");

		loggerADotBDotC.info("Hello world....");
		
	}
}

As you see above snippet, I defined 3 loggers with name

a.   A

b.   A.B

c.    A.B.C

And attach a file appender to each of these loggers. When I write message to A.B.C logger, it is delivered to the appenders of A, A.B and A.B.C.

 

When you ran above application, you can observe A.log, A.B.log, A.B.C.log files are created in /Users/Shared/logback folder.



How to disable additivity of a logger?

Appender additivity is enabled by default. You can disabled this using setAdditivity method.

 

Example

logger.setAdditive(false);

 

 

AppenderAdditivity.java

package com.sample.app;

import org.slf4j.LoggerFactory;

import ch.qos.logback.classic.Logger;
import ch.qos.logback.classic.LoggerContext;
import ch.qos.logback.classic.encoder.PatternLayoutEncoder;
import ch.qos.logback.classic.spi.ILoggingEvent;
import ch.qos.logback.core.FileAppender;

public class AppenderAdditivity {

	private static Logger getLogger(String name) {
		Logger logger = (ch.qos.logback.classic.Logger) LoggerFactory.getLogger(name);

		LoggerContext loggerContext = (LoggerContext) LoggerFactory.getILoggerFactory();
		PatternLayoutEncoder ple = new PatternLayoutEncoder();

		ple.setPattern("%date %level [%thread] %logger{10} [%file:%line] %msg%n");
		ple.setContext(loggerContext);
		ple.start();
		FileAppender<ILoggingEvent> fileAppender = new FileAppender<ILoggingEvent>();
		fileAppender.setFile("/Users/Shared/logback/" + name + ".log");
		fileAppender.setEncoder(ple);
		fileAppender.setContext(loggerContext);
		fileAppender.start();

		logger.addAppender(fileAppender);
		
		// Comment below lin if you want to enable appender additivity
		logger.setAdditive(false);

		return logger;
	}

	public static void main(String[] args) {

		Logger loggerA = getLogger("A");
		Logger loggerADotB = getLogger("A.B");
		Logger loggerADotBDotC = getLogger("A.B.C");

		loggerADotBDotC.info("Hello world....");
		
	}
}

 

Output


From the above image, you can confirm that the messages are not passed to parent appenders.

 

 

Previous                                                 Next                                                 Home

No comments:

Post a Comment