About Alex Soto

Using slf4j with logback tutorial

In current post I am going to show you how to configure your application to use slf4j and logback as logger solution.

The Simple Logging Facade For Java (slf4j) is a simple facade for various logging frameworks, like JDK logging (java.util.logging), log4j, or logback. Even it contains a binding tat will delegate all logger operations to another well known logging facade called jakarta commons logging (JCL).

Logback is the successor of log4j logger API, in fact both projects have the same father, but logback offers some advantages over log4j, like better performance and less memory consumption, automatic reloading of configuration files, or filter capabilities, to cite a few features.

Native implementation of slf4j is logback, thus using both as logger framework implies zero memory and computational overhead.

First we are going to add slf4j and logback into pom as dependencies.

<properties>
 <slf4j.version>1.6.4</slf4j.version>
 <logback.version>1.0.1</logback.version>
</properties>

<dependencies>

 <dependency>
  <groupId>org.slf4j</groupId>
  <artifactId>slf4j-api</artifactId>
  <version>${slf4j.version}</version>
 </dependency>

 <dependency>
  <groupId>ch.qos.logback</groupId>
  <artifactId>logback-classic</artifactId>
  <version>${logback.version}</version>
 </dependency>

 <dependency>
  <groupId>ch.qos.logback</groupId>
  <artifactId>logback-core</artifactId>
  <version>${logback.version}</version>
 </dependency>

</dependencies>

Note that three files are required, one for slf4j, and two for logback. The last two dependencies will change depending on you logging framework, if for example you want to still use log4j, instead of having logback dependencies we would have log4j dependency itself and slf4j-log4j12.

Next step is creating the configuration file. Logback supports two formats of configurations files, the traditional way, using XML or using a Groovy DSL style. Let’s start with traditional way, and we are going to create a file called logback.xml into classpath. File name is mandatory, but logback-test.xml is also valid. In case that both files are found in classpath the one ended with -test, will be used.

<?xml version="1.0" encoding="UTF-8"?>

<configuration>

  <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{5} - %msg%n</pattern>
    </encoder>
  </appender>

  <logger name="com.lordofthejars.foo" level="INFO" additivity="false">
   <appender-ref ref="STDOUT" />
  </logger>

  <!-- Strictly speaking, the level attribute is not necessary since -->
  <!-- the level of the root level is set to DEBUG by default.       -->
  <root level="DEBUG">          
    <appender-ref ref="STDOUT" />
  </root>  
  
</configuration>

In general file is quite intuitive, we are defining the appender (the output of log messages), in this case to console, a pattern, and finally root level logger (DEBUG) and a different level logger (INFO) for classes present in foo package.

Obviously this format is much readable than typical log4j.properties. Recall on additivity attribute, the appender named STDOUT is attached to two loggers, to root and to com.lordofthejars.foo. because the root logger is the ancestor of all loggers, logging request made by com.lordofthejars.foo logger will be output twice. To avoid this behavior you can set additivity attribute to false, and message will be printed only once.

Now let’s create to classes which will use slf4j. First class called BarComponent is created on com.lordofthejars.bar:

public class BarComponent {

 private static final Logger logger = LoggerFactory.getLogger(BarComponent.class);

 public void bar() {

  String name = "lordofthejars";

  logger.info("Hello from Bar.");


  logger.debug("In bar my name is {}.", name);

 }

}

Note two big differences from log4j. The first one is that is no longer required the typical if construction above each log call. The other one is a pair of ‘{}’. Only after evaluating whether to log or not, logback will format the message replacing ‘{}’ with the given string value.

The other one called FooComponent is created on com.lordofthejars.foo:

public class FooComponent {

 private static final Logger logger = LoggerFactory.getLogger(FooComponent.class);

 public void foo() {

  String name = "Alex";

  logger.info("Hello from Foo.");

  logger.debug("In foo my name is {}.", name);

 }

}

And now calling foo and bar method, with previous configuration, the output produced will be:

13:49:59.586 [main] INFO  c.l.b.BarComponent - Hello from Bar.
13:49:59.617 [main] DEBUG c.l.b.BarComponent - In bar today is 5/3/2012
13:49:59.618 [main] INFO  c.l.f.FooComponent - Hello from Foo.

Notice that debug lines in foo method are not shown. This is ok, because we have set to be in this way.

Next step we are going to take is configuring logback, but instead of using xml approach we are going to use groovy DSL approach. Logback will give preference to groovy configuration over xml configuration, so keep in mind it if you are mixing configuration approaches.

So first thing to do is add groovy as dependency.

<dependency>
 <groupId>org.codehaus.groovy</groupId>
 <artifactId>groovy</artifactId>
 <version>${groovy.version}</version>
 <scope>runtime</scope>
</dependency>

And then we are going to create the same configuration created previously but in groovy format.

import ch.qos.logback.classic.encoder.PatternLayoutEncoder
import ch.qos.logback.core.ConsoleAppender

import static ch.qos.logback.classic.Level.DEBUG
import static ch.qos.logback.classic.Level.INFO

appender("STDOUT", ConsoleAppender) {
  encoder(PatternLayoutEncoder) {
    pattern = "%d{HH:mm:ss.SSS} [%thread] %-5level %logger{5} Groovy - %msg%n"
  }
}

logger("com.lordofthejars.foo", INFO)
root(DEBUG, ["STDOUT"])

You can identify the same parameters of xml approach but as groovy functions.

I wish you have found this post useful, and in next project, if you can, use slf4j in conjunction with logback, your application will run faster than logging with log4j.

Download Code

Reference: Using slf4j with logback tutorial from our JCG partner Alex Soto at the One Jar To Rule Them All blog.

Related Whitepaper:

Functional Programming in Java: Harnessing the Power of Java 8 Lambda Expressions

Get ready to program in a whole new way!

Functional Programming in Java will help you quickly get on top of the new, essential Java 8 language features and the functional style that will change and improve your code. This short, targeted book will help you make the paradigm shift from the old imperative way to a less error-prone, more elegant, and concise coding style that’s also a breeze to parallelize. You’ll explore the syntax and semantics of lambda expressions, method and constructor references, and functional interfaces. You’ll design and write applications better using the new standards in Java 8 and the JDK.

Get it Now!  

2 Responses to "Using slf4j with logback tutorial"

  1. Дмитрий Кривенко says:

    10Q)

Leave a Reply


× 5 = ten



Java Code Geeks and all content copyright © 2010-2014, Exelixis Media Ltd | Terms of Use
All trademarks and registered trademarks appearing on Java Code Geeks are the property of their respective owners.
Java is a trademark or registered trademark of Oracle Corporation in the United States and other countries.
Java Code Geeks is not connected to Oracle Corporation and is not sponsored by Oracle Corporation.

Sign up for our Newsletter

15,153 insiders are already enjoying weekly updates and complimentary whitepapers! Join them now to gain exclusive access to the latest news in the Java world, as well as insights about Android, Scala, Groovy and other related technologies.

As an extra bonus, by joining you will get our brand new e-books, published by Java Code Geeks and their JCG partners for your reading pleasure! Enter your info and stay on top of things,

  • Fresh trends
  • Cases and examples
  • Research and insights
  • Two complimentary e-books