SLF4J and LOGBack
Next Generation Logging!
31-08-2010
LOGBack : History
It’s a successor of log4j
LOGBack together with SLF4J designed to be the next generation logging framework
There is no active developer community for log4j
What is SLF4J?
Remember commons-logging?SLF4J is a façade for different logging toolsDifferent logging tools can be plugged without any code changeNo classloader and memory leak issueBetter support of MDC (Later!)No difference using with LOGBack but advantageous on the way!
Hello SLF4J
import org.slf4j.Logger;import org.slf4j.LoggerFactory;
public class HelloSLF4J { private static final Logger logger = LoggerFactory.getLogger(HelloSLF4J.class); public static void main(String[] args) {
logger.info("Hello World"); }}
logger.debug("The entry is {}.", entry);
SLF4J Enforcing Best Practices!
if(logger.isDebugEnabled()) {logger.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));
}
•Parameterised Logging•String manipulation after checking loglevel
Exception Logging
logger.error("some accompanying message", e);
try { Integer i = Integer.valueOf(s);} catch (NumberFormatException e){ logger.error("Failed to format {}", s, e);}
What is LOGBack?
“LOGBack is faster, reliable and feature upgraded logging tool compared to its predecessors“
SLF4J and Logback : Dream Dates!
Logback implements SLF4J natively
No computational and memory overhead
Fully compliant to SLF4J
Faster they say! 10 times!! Smaller Blue Print
Core, classic and access modules
Pre-Requirements
logback.xml/logback.groovy
slf4j-api.jar
logback-classic.jar
logback-core.jar
Why Logback
Automatic Reloading• LOGLEVELs can be changed on the fly. • <configuration scan="true" scanPeriod="30 seconds" >
Prudent Model Recovery (3 times slower)• Multiple JVM can share same log file.• Graceful recovery from IO failures(100% disk usage) without
process restart. File Server recovery will let log files working automatically
Filters And MDCRolling Policies• Compress and Roll• Housekeeping with maxHistory property
Why LogbackConditional Processing• Good For Dev/Prod switch
Is It Worth A Use?
Why Logback
Stack Traces Pointing jar files
logback.xmlConsoleAppenderConsoleAppender
RollingFileAppenderRollingFileAppender
rollover daily or whenever the file size reaches 100MB rollover daily or whenever the file size reaches 100MB
logback.groovy
import ch.qos.logback.classic.encoder.PatternLayoutEncoderimport ch.qos.logback.core.ConsoleAppender
import static ch.qos.logback.classic.Level.DEBUG
appender("STDOUT", ConsoleAppender) { encoder(PatternLayoutEncoder) { pattern = "%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} -
%msg%n" }}root(DEBUG, ["STDOUT"])
Best Practice
Though the samples here used are xml for our understanding, groovy is simpler
Maven will take care most!• src/test/resources/logback-test.xml
• src/main/resources/logback.xml
• No setting required, scanner checks groovy, test and production in an order!
MDC
MDC : Map Diagnostic Context• Helps to uniquely stamp requests
• Similar to NDC : Nested Diagnostic Context
• Correlating the logs effectively
The MDC manages contextual information on a per thread basis(and its children)
MDC Use Case: User Based Loggingpublic class UserServletFilter implements Filter { private final String USER_KEY = "username"; public void doFilter(ServletRequest request, ServletResponse response, FilterChain chain) throws IOException, ServletException { HttpServletRequest req = (HttpServletRequest) request; Principal principal = req.getUserPrincipal(); if (principal != null) { String username = principal.getName(); MDC.put(USER_KEY, username); } try { chain.doFilter(request, response); } finally { MDC.remove(USER_KEY); } }}
MDC Use Case: User Based Logging
<appender name="CONSOLE“ class="ch.qos.logback.core.ConsoleAppender"> <layout class="ch.qos.logback.classic.PatternLayout"> <Pattern>%-4r [%thread] %-5level C:%X{username} - %msg%n</Pattern> </layout> </appender>
MDC Use Case: InsertingServletFilter
%X{req.remoteHost}
%X{req.requestURI}%n%d - %m%n
MDC Use Case: SiftingAppender
Separate logging based runtime attributeslogger.debug("Application started");
MDC.put("userid", "Alice");
logger.debug("Alice says hello");
Filters: LevelFilter
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> <filter class="ch.qos.logback.classic.filter.LevelFilter"> <level>INFO</level> <onMatch>ACCEPT</onMatch> <onMismatch>DENY</onMismatch> </filter> <encoder> <pattern> %-4relative [%thread] %-5level %logger{30} - %msg%n </pattern> </encoder> </appender>
Filters: ThresholdFilter
<configuration> <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender"> <!-- deny all events with a level below INFO, that is TRACE and DEBUG --> <filter class="ch.qos.logback.classic.filter.ThresholdFilter"> <level>INFO</level> </filter> <encoder> <pattern> %-4relative [%thread] %-5level %logger{30} - %msg%n </pattern> </encoder> </appender> <root level="DEBUG"> <appender-ref ref="CONSOLE" /> </root></configuration>
Filters:EvaluatorFilter
<configuration> <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <filter class="ch.qos.logback.core.filter.EvaluatorFilter"> <evaluator>
<expression>message.contains("billing")</expression> </evaluator> <OnMismatch>NEUTRAL</OnMismatch> <OnMatch>DENY</OnMatch> </filter> <encoder> <pattern> %-4relative [%thread] %-5level %logger - %msg%n </pattern> </encoder> </appender>
<root level="INFO"> <appender-ref ref="STDOUT" /> </root></configuration>
Good To Know!
Logback-access• powerful HTTP-access log with tomcat and jetty
• UI based
• JMX support
• Statistical Data of UI accesses
• TeeFilter, CountingFilter, ViewStatusMessagesServlet
Tools : SLF4J Migrator tool
DANKE!!!
Top Related