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.
No comments:
Post a Comment