300 likes | 311 Views
Logback is a faster, smaller, and more efficient logging framework than log4j. It offers a modular architecture and seamless integration with Jetty and Tomcat. Logback also provides a native implementation of SLF4J API.
E N D
Logback project Ceki Gülcü & Sébastien Pennec
~ • No revolution, only evolution. • log4j is no longer being actively developed • The same basic plumbing only done better. • Faster, smaller, higher gas mileage, and generally more bang for the buck.
Modular architecture • logback-core Joran, Status, Context, pattern parsing • logback-classic developer logging • logback-access container (access) logging
Access Logging • Definition: Access log The log generated when a user accesses a web-page on a web server. • Logback-access integrates seamlessly with Jetty and Tomcat
logback-classic implements SLF4J • Logback offers a native implementation of the SLF4J API => Logback exposes its logging API through SLF4J. • If you are using logback, you are actually using SLF4J • SLF4J can delegate to log4j, logback, java.util.logging or JCL • SLF4J can bridge log4j, JCL and j.u.l.
Joran: a bowl of fresh air • Given rules (patterns & actions) it can configure any object. • Joran can learn new rules on the fly. • With its implicit rules, you don’t even have to write rules. • It can do partial replay. • It is generic (can be used in your own projects)
Configuration example: <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender"> <File>logFile.log</File> <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy"> <FileNamePattern> logFile.%d{yyyy-MM-dd}.log.zip </FileNamePatter> </rollingPolicy> <layout class="ch.qos.logback.classic.PatternLayout"> <Pattern> %d{HH:mm:ss,SSS} [%thread] %-5level %logger{22} - %msg%n </Pattern> </layout> </appender>
Logback-access configuration <appender name="FILE" class="c.q.l.c.r.RollingFileAppender"> <File>access.log"</File> <rollingPolicy class="c.q.l.c.r.TimeBasedRollingPolicy"> <FileNamePattern> access.%d{yyyy-MM-dd}.log.zip </FileNamePattern> </rollingPolicy> <layout class="c.q.l.access.PatternLayout"> <Pattern">combined</Pattern"> </layout> </appender>
Another example: <testShell name="test1"> <period>5 minutes</period> <!-- we need to configure a totally new test object for each run of the test --> <test class="com.wombat.myTest"> <DataSource class="c.w.JNDIDS"> <url>jndi://com.wombat/ds"</url> </DataSource> </test> <testShell> <testShell name="test2"> <period>60 seconds</period> <test class="com.wombat.myTest2"> <file>c:/wombat/foo.properties</file> </test> </testShell>
Is Joran for me? • Joran is ideal for building frameworks which need to support arbitrary user-developed plug-ins.
Internal error reporting • Who shall guard the guards? • Logback modules cannot use logging to report their own state. • Something more generic is needed.
Errors in action • Internal state available via StatusManager • Exceptions and status messages accompanied by references, i.e. URLs, to external documents
JMX • Logback configuration can be reloaded via JMX • Statistical results exposed via JMX
Documentation • Major area of effort. • Complete manual, with over 150 pages of documentation, is available for free • A short introduction to access logging with logback-access and Jetty • javadoc, FAQ, error codes,…
Filters, Filters. Filters everywhere • Filters attachable to any Appender • Evaluator filters • Janino filters for evaluation based on java expressions • TurboFilters for optimized global processing
EvaluatorFilter & Janino <appender name="CYCLIC" class="c.q.l.core.read.CyclicBufferAppender"> <filter class="c.q.l.core.filter.EvaluatorFilter"> <evaluator name="loggingTaskEval"> <expression> logger.contains("LoggingTask") && message.contains("Howdydy-diddly-ho") && (timeStamp-loggerContext.getBirthTime()) >= 20000 </expression> </evaluator> <OnMatch>DENY</OnMatch> </filter> <MaxSize>512</MaxSize> </appender>
TurboFilters <turboFilter class="c.q.l.classic.turbo.MDCFilter"> <MDCKey>userid</MDCKey> <Value>sebastien</Value> <OnMatch>ACCEPT</OnMatch> </turboFilter>
Parameterized logging Integer entry = new Interger(50); logger.debug("The entry is "+entry+"."); can be optimized as: if(logger.isDebugEnabled()) { logger.debug("The entry is "+entry+"."); } or better yet: logger.debug("The entry is {}.", entry);
Markers for specialized handling • Markers are metadata for logging statements, coloring them for specialized processing
SiftingAppender or the appender-making appender • Sift logging according to runtime attributes • E.g. separate logs according to user sessions, so that the log file generated by every user go into distinct log files, one log file per user. • Works with any appender, not just FileAppender
SiftingAppender (continued) <appender name="SIFT" class="ch.qos.logback.classic.sift.SiftingAppender"> <discriminator> <Key>userid</Key> <DefaultValue>unknown</DefaultValue> </discriminator> <sift> <appender name="FILE-${userid}" class="ch.qos.logback.core.FileAppender"> <File>${userid}.log</File>s <Append>false</Append> <layout> <Pattern>%d %level %mdc %logger - %msg%n</Pattern> </layout> </appender> </sift> </appender>
Tested & Ready • Battery of over 450 unit tests • Tests written concomitantly with the code
Package versions in stack traces java.lang.NullPointerException at com.xyz.Wombat(Wombat.java:57) ~[wombat-1.3.jar:1.3] at com.xyz.Wombat(Wombat.java:76) ~[wombat-1.3.jar:1.3] at sun.reflect.NativeMethodAccessorImpl.invoke0(Native) ~[na:1.5.0_06] at java.lang.reflect.Method.invoke(Method.java:585) ~[na:1.5.0_06] at junit.runners.TestMethod.invoke(TestMethod.java:59) [junit-4.4.jar:na] etc..
Odds and ends • RollingFileAppender automatic file compression the background • FileAppender and RollingFileAppender allow for the same log file to be written to by instances located in different JVMs • 10 fold improvement in the speed of transporting logging events over the wire • SMTPAppender now does TLS and SSL, subject line in outgoing email now based on PatternLayout
Odds and ends II • %() in pattern strings can do magic %-50(%d %level [%thread]) - %m%n • DuplicateMessage filter
Odds and ends II • %() in pattern strings can do magic %-50(%d %level [%thread]) - %m%n • DuplicateMessage filter
Plans for the near future • Finer threading model leading to less contention • Better documentation • Eclipse plug-in to visualize your logs
Conclusion • Logback is the unofficial successor of log4j, as the latter is no longer being actively developed.
Questions? • read the docs at http://logback.qos.ch/ • study the code at http://svn.qos.ch • write to us at logback-user@qos.ch • file a bug report at http://jira.qos.ch/ • chat with us at irc.freenode.net#qos • talk to us at +41 21 312 32 26