logging with logback in scala
TRANSCRIPT
![Page 1: Logging with Logback in Scala](https://reader034.vdocument.in/reader034/viewer/2022052602/55a5251a1a28abdf0e8b4612/html5/thumbnails/1.jpg)
Logging with Logback in Scala
Rishi Khandelwal Software Consultant Knoldus Software LLP
![Page 2: Logging with Logback in Scala](https://reader034.vdocument.in/reader034/viewer/2022052602/55a5251a1a28abdf0e8b4612/html5/thumbnails/2.jpg)
Agenda
Logging Logback Logback Architecture Logback-classic-module Configuration Variable Substitution Appenders
![Page 3: Logging with Logback in Scala](https://reader034.vdocument.in/reader034/viewer/2022052602/55a5251a1a28abdf0e8b4612/html5/thumbnails/3.jpg)
What is Logging ?
![Page 4: Logging with Logback in Scala](https://reader034.vdocument.in/reader034/viewer/2022052602/55a5251a1a28abdf0e8b4612/html5/thumbnails/4.jpg)
Logging is the process of recording application actions and state to a secondary interface.
![Page 5: Logging with Logback in Scala](https://reader034.vdocument.in/reader034/viewer/2022052602/55a5251a1a28abdf0e8b4612/html5/thumbnails/5.jpg)
Logging Levels
TRACE DEBUG INFO WARN ERROR
![Page 6: Logging with Logback in Scala](https://reader034.vdocument.in/reader034/viewer/2022052602/55a5251a1a28abdf0e8b4612/html5/thumbnails/6.jpg)
Don't log everything.
![Page 7: Logging with Logback in Scala](https://reader034.vdocument.in/reader034/viewer/2022052602/55a5251a1a28abdf0e8b4612/html5/thumbnails/7.jpg)
Excessive logging is costly.
Performance will be affected.
Take a long time to analyze important information
![Page 8: Logging with Logback in Scala](https://reader034.vdocument.in/reader034/viewer/2022052602/55a5251a1a28abdf0e8b4612/html5/thumbnails/8.jpg)
Logback ???
![Page 9: Logging with Logback in Scala](https://reader034.vdocument.in/reader034/viewer/2022052602/55a5251a1a28abdf0e8b4612/html5/thumbnails/9.jpg)
Logback is intended as a successor to the popular log4j project.
Logback is divided into three moduleslogback-corelogback-classiclogback-access
logback-core module lays the groundwork for the other two modules.
logback-classic natively implements the SLF4J API
logback-access module integrates with Servlet containers, such as Tomcat and Jetty
![Page 10: Logging with Logback in Scala](https://reader034.vdocument.in/reader034/viewer/2022052602/55a5251a1a28abdf0e8b4612/html5/thumbnails/10.jpg)
![Page 11: Logging with Logback in Scala](https://reader034.vdocument.in/reader034/viewer/2022052602/55a5251a1a28abdf0e8b4612/html5/thumbnails/11.jpg)
Logback-classic-module
Built upon three main classes: Logger, Appender and Layout
Logger → logback-classic Appender & layout → logback-core
![Page 12: Logging with Logback in Scala](https://reader034.vdocument.in/reader034/viewer/2022052602/55a5251a1a28abdf0e8b4612/html5/thumbnails/12.jpg)
Logger Context
It is the logging space which is categorized according to developer-chosen criteria.
Every single logger is attached to a LoggerContext.
It is responsible for arranging loggers in a tree like hierarchy.
Loggers are named entities which is case-sensitive.
They follow the hierarchical naming rule.
![Page 13: Logging with Logback in Scala](https://reader034.vdocument.in/reader034/viewer/2022052602/55a5251a1a28abdf0e8b4612/html5/thumbnails/13.jpg)
Named Hierarchy
A logger is said to be an ancestor of another logger if its name followed by a dot is prefix of the descendant logger name.
A logger is said to be a parent of a child logger if there are no ancestors between itself and the descendant logger.
"com.foo" is a parent of the logger named "com.foo.Bar".
"java" is a parent of "java.util" and an ancestor of "java.util.Vector".
![Page 14: Logging with Logback in Scala](https://reader034.vdocument.in/reader034/viewer/2022052602/55a5251a1a28abdf0e8b4612/html5/thumbnails/14.jpg)
Root LoggerThe root logger resides at the top of the logger hierarchy. It is
exceptional in that it is part of every hierarchy at its inception. Like every logger, it can be retrieved by its name, as follows:
val rootLogger = LoggerFactory.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME)
Other methods :
package org.slf4j;
public interface Logger {
// Printing methods:
public void trace(String message);
public void debug(String message);
public void info(String message);
public void warn(String message);
public void error(String message);
}
![Page 15: Logging with Logback in Scala](https://reader034.vdocument.in/reader034/viewer/2022052602/55a5251a1a28abdf0e8b4612/html5/thumbnails/15.jpg)
Effective Level
Loggers may be assigned levels
If a given logger is not assigned a level, then it inherits one from its closest ancestor with an assigned level
The root logger always has an assigned level. By default, this is DEBUG.
The effective level for a given logger L, is equal to the first non-null level in its hierarchy, starting at L itself and proceeding upwards in the hierarchy towards the root logger.
![Page 16: Logging with Logback in Scala](https://reader034.vdocument.in/reader034/viewer/2022052602/55a5251a1a28abdf0e8b4612/html5/thumbnails/16.jpg)
![Page 17: Logging with Logback in Scala](https://reader034.vdocument.in/reader034/viewer/2022052602/55a5251a1a28abdf0e8b4612/html5/thumbnails/17.jpg)
Basic Selection RuleA log request of level p issued to a logger having an effective level q, is enabled if p >=
q.
levels order: TRACE < DEBUG < INFO < WARN < ERROR.
![Page 18: Logging with Logback in Scala](https://reader034.vdocument.in/reader034/viewer/2022052602/55a5251a1a28abdf0e8b4612/html5/thumbnails/18.jpg)
Configuration
Logback tries to find a file called logback.groovy in the classpath.
If no such file is found, logback tries to find a file called logback-test.xml in the classpath.
If no such file is found, it checks for the file logback.xml in the classpath..
If neither file is found, logback configures itself automatically using the BasicConfigurator which will cause logging output to be directed to the console.
![Page 19: Logging with Logback in Scala](https://reader034.vdocument.in/reader034/viewer/2022052602/55a5251a1a28abdf0e8b4612/html5/thumbnails/19.jpg)
logback.xml
![Page 20: Logging with Logback in Scala](https://reader034.vdocument.in/reader034/viewer/2022052602/55a5251a1a28abdf0e8b4612/html5/thumbnails/20.jpg)
Printing status messages
<configuration debug="true">
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoders are assigned the type
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="debug">
<appender-ref ref="STDOUT" />
</root>
</configuration>
![Page 21: Logging with Logback in Scala](https://reader034.vdocument.in/reader034/viewer/2022052602/55a5251a1a28abdf0e8b4612/html5/thumbnails/21.jpg)
Automatically reloading configuration file upon modification
<configuration scan="true">
...
</configuration>
For scan periods :
<configuration scan="true" scanPeriod="30 seconds" >
...
</configuration>
![Page 22: Logging with Logback in Scala](https://reader034.vdocument.in/reader034/viewer/2022052602/55a5251a1a28abdf0e8b4612/html5/thumbnails/22.jpg)
Configuration file syntax
![Page 23: Logging with Logback in Scala](https://reader034.vdocument.in/reader034/viewer/2022052602/55a5251a1a28abdf0e8b4612/html5/thumbnails/23.jpg)
Case sensitivity of tag names
Configuring loggers, or the <logger> element
Configuring the root logger, or the <root> element
Configuring Appenders
![Page 24: Logging with Logback in Scala](https://reader034.vdocument.in/reader034/viewer/2022052602/55a5251a1a28abdf0e8b4612/html5/thumbnails/24.jpg)
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern> %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n </pattern> </encoder> </appender>
<logger name="com.configuration" level="INFO" /> <logger name="chapters.configuration.Foo" level="DEBUG" />
<root level="DEBUG"> <appender-ref ref="STDOUT" /> </root>
</configuration>
![Page 25: Logging with Logback in Scala](https://reader034.vdocument.in/reader034/viewer/2022052602/55a5251a1a28abdf0e8b4612/html5/thumbnails/25.jpg)
<configuration> <appender name="FILE" class="ch.qos.logback.core.FileAppender"> <file>myApp.log</file> <encoder> <pattern>%date %level [%thread] %logger{10} [%file:%line] %msg%n</pattern> </encoder> </appender>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender"> <encoder> <pattern>%msg%n</pattern> </encoder> </appender>
<logger name="chapters.configuration"> <appender-ref ref="FILE" /> </logger>
<root level="debug"> <appender-ref ref="STDOUT" /> </root></configuration>
![Page 26: Logging with Logback in Scala](https://reader034.vdocument.in/reader034/viewer/2022052602/55a5251a1a28abdf0e8b4612/html5/thumbnails/26.jpg)
Variable Substitution
Simple substitution :
<configuration>
<property name="USER_HOME" value="/home/rishi/Application/blog_projects/knolx/src/main/resources/log" />
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>${USER_HOME}/myApp.log</file>
<encoder>
<pattern>%msg%n</pattern>
</encoder>
</appender>
<root level="debug">
<appender-ref ref="FILE" />
</root>
</configuration>
![Page 27: Logging with Logback in Scala](https://reader034.vdocument.in/reader034/viewer/2022052602/55a5251a1a28abdf0e8b4612/html5/thumbnails/27.jpg)
Variable Substitution
System Variable substitution :
<configuration>
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>${USER_HOME}/myApp.log</file>
<encoder>
<pattern>%msg%n</pattern>
</encoder>
</appender>
<root level="debug">
<appender-ref ref="FILE" />
</root>
</configuration>
sbt -DUSER_HOME="/home/rishi/Application/blog_projects/knolx/src/main/resources/log" run
![Page 28: Logging with Logback in Scala](https://reader034.vdocument.in/reader034/viewer/2022052602/55a5251a1a28abdf0e8b4612/html5/thumbnails/28.jpg)
Variable Substitution
Variable substitution using a separate file :
<configuration>
<property file="/home/rishi/Application/blog_projects/knolx/src/main/resources/variable.properties" />
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>${USER_HOME}/myApp.log</file>
<encoder>
<pattern>%msg%n</pattern>
</encoder>
</appender>
<root level="debug">
<appender-ref ref="FILE" />
</root>
</configuration>
![Page 29: Logging with Logback in Scala](https://reader034.vdocument.in/reader034/viewer/2022052602/55a5251a1a28abdf0e8b4612/html5/thumbnails/29.jpg)
Conditional processing <!-- if-then form -->
<if condition="some conditional expression">
<then>
...
</then>
</if>
<!-- if-then-else form -->
<if condition="some conditional expression">
<then>
...
</then>
<else>
...
</else>
</if>
Conditional processing requires the Janino library.
"org.codehaus.janino" % "janino" % "2.6.1"
![Page 30: Logging with Logback in Scala](https://reader034.vdocument.in/reader034/viewer/2022052602/55a5251a1a28abdf0e8b4612/html5/thumbnails/30.jpg)
Appenders
Logback delegates the task of writing a logging event to components called appenders Logback-core
Console Appender
OutputStreamAppender File Appender
Rolling File Appender
Time Based Size based Fixed Window
![Page 31: Logging with Logback in Scala](https://reader034.vdocument.in/reader034/viewer/2022052602/55a5251a1a28abdf0e8b4612/html5/thumbnails/31.jpg)
Console Appender
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg %n</pattern>
</encoder>
</appender>
File Appender :
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>testFile.log</file>
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
</encoder>
</appender>
![Page 32: Logging with Logback in Scala](https://reader034.vdocument.in/reader034/viewer/2022052602/55a5251a1a28abdf0e8b4612/html5/thumbnails/32.jpg)
Time base rolling :
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>logFile.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- daily rollover -->
<fileNamePattern>logFile.%d{yyyy-MM-dd}.log</fileNamePattern>
<!-- keep 30 days' worth of history -->
<maxHistory>30</maxHistory>
</rollingPolicy>
![Page 33: Logging with Logback in Scala](https://reader034.vdocument.in/reader034/viewer/2022052602/55a5251a1a28abdf0e8b4612/html5/thumbnails/33.jpg)
Fixed Window :
<rollingPolicy class="ch.qos.logback.core.rolling.FixedWindowRollingPolicy">
<fileNamePattern>tests.%i.log.zip</fileNamePattern>
<minIndex>1</minIndex>
<maxIndex>3</maxIndex>
</rollingPolicy>
<triggeringPolicy class="ch.qos.logback.core.rolling.SizeBasedTriggeringPolicy">
<maxFileSize>5MB</maxFileSize>
</triggeringPolicy>
![Page 34: Logging with Logback in Scala](https://reader034.vdocument.in/reader034/viewer/2022052602/55a5251a1a28abdf0e8b4612/html5/thumbnails/34.jpg)
Size and Time based :
<appender name="ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>mylog.txt</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- rollover daily -->
<fileNamePattern>mylog-%d{yyyy-MM-dd}.%i.txt</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy
class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<!-- or whenever the file size reaches 100MB -->
<maxFileSize>100MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
</rollingPolicy>
<encoder>
<pattern>%msg%n</pattern>
</encoder>
</appender>
![Page 35: Logging with Logback in Scala](https://reader034.vdocument.in/reader034/viewer/2022052602/55a5251a1a28abdf0e8b4612/html5/thumbnails/35.jpg)
SMTP Appender :
<appender name="EMAIL" class="ch.qos.logback.classic.net.SMTPAppender">
<smtpHost>smtp.gmail.com</smtpHost>
<smtpPort>587</smtpPort>
<STARTTLS>true</STARTTLS>
<username>USERNAMNE</username>
<password>PASSWORD</password>
<asynchronousSending>false</asynchronousSending>
<to>EMAIL_IDS</to>
<from>NAME</from>
<subject>ERROR: %logger{20} - %m</subject>
<layout class="ch.qos.logback.classic.PatternLayout">
<pattern>%date %-5level %logger - %message%n</pattern>
</layout>
</appender>
<root level="info">
<appender-ref ref="CONSOLE" />
<appender-ref ref="EMAIL" />
</root>
![Page 36: Logging with Logback in Scala](https://reader034.vdocument.in/reader034/viewer/2022052602/55a5251a1a28abdf0e8b4612/html5/thumbnails/36.jpg)