Friday 22 December 2017

How to configure Slf4j logging in your web application with log4j or logback implementations

Background

One of the important part of any application building is to implement proper logging.  Slf4j is widely used for this. Slf4j itself is not a logging implementation but it is kind of a wrapper over existing implementations like log4j etc. In this post we will see how we can configure our web application to use slf4j logging with -
  1. log4j
  2. logback
 For log4j I am going to use ivy as dependencies management tool and in case for logback I will use maven. But you can use any really as long as you include correct dependencies in your application.

Using slf4j with log4j

 To use log4j you need to include following dependencies in your application. Your ivy.xml file would look like -

<ivy-module version="2.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
       xsi:noNamespaceSchemaLocation="http://ant.apache.org/ivy/schemas/ivy.xsd">
    <info
        organisation="osfg"
        module="WebDynamo"
        status="integration">
    </info>
    
    <dependencies>
        <dependency org="org.slf4j" name="slf4j-api" rev="1.7.21"/>
        <!-- https://mvnrepository.com/artifact/org.slf4j/slf4j-log4j12 -->
        <dependency org="org.slf4j" name="slf4j-log4j12" rev="1.7.21"/>
    </dependencies>
</ivy-module>


You can see the complete xml here - https://github.com/aniket91/WebDynamo/blob/master/ivy.xml 
and complete working app here - https://github.com/aniket91/WebDynamo

Once you have dependencies in place you need to give it a configuration file to tell how your logging behaves. A sample configuration file would look like -

<?xml version="1.0" encoding="UTF-8" ?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">
<log4j:configuration debug="true"
  xmlns:log4j='http://jakarta.apache.org/log4j/'>

    <appender name="CONSOLE" class="org.apache.log4j.ConsoleAppender">
        <layout class="org.apache.log4j.PatternLayout">
        <param name="ConversionPattern"
            value="%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n" />
        </layout>
    </appender>

    <appender name="FILE" class="org.apache.log4j.RollingFileAppender">
        <param name="append" value="false" />
        <param name="maxFileSize" value="10MB" />
        <param name="maxBackupIndex" value="10" />
        <param name="file" value="${catalina.home}/logs/webdynamo.log" />
        <layout class="org.apache.log4j.PatternLayout">
        <param name="ConversionPattern"
            value="%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n" />
        </layout>
    </appender>
    
    <category name="org.springframework">
        <priority value="debug" />
    </category>

    <category name="org.springframework.beans">
        <priority value="debug" />
    </category>

    <category name="org.springframework.security">
        <priority value="debug" />
    </category>

    <root>
        <level value="DEBUG" />
        <appender-ref ref="CONSOLE" />
        <appender-ref ref="FILE" />
    </root>

</log4j:configuration>

Again you can see this file in the same project mentioned above - https://github.com/aniket91/WebDynamo/blob/master/src/log4j.xml

This configuration file should be in the classpath. log4j implementation by default looks for a file called log4j.properties or log4j.xml in your classpath.

You can visualize this with following diagram -



Application code uses slf4j interface which in turn uses a log4j-slf4j bridge to talk to log4j implementation.

We will see how to actually use Sl4fj logger a bit later in this post. Let's look how to do the same with a logback implementation.



Using slf4j with logback

For this you need to add following dependencies. Your pom.xml dependencies section would look like -

            <dependency>
                <groupId>ch.qos.logback</groupId>
                <artifactId>logback-classic</artifactId>
                <version>1.0.13</version>
            </dependency>

NOTE : you do not need slf4j-api here as logback has it as a compile time dependency. You can see that here - https://mvnrepository.com/artifact/ch.qos.logback/logback-classic/1.0.13.

NOTE : The logback-classic module can be assimilated to a significantly improved version of log4j. Moreover, logback-classic natively implements the SLF4J API so that you can readily switch back and forth between logback and other logging frameworks such as log4j or java.util.logging (JUL).  (Source)

You can visualize this with following diagram -




As we saw in log4j implementation we need to supply a configuration file to the implementation to tell how logging should work. In case of logback it expects a file called logback.xml to be in the classpath. A sample file could be -

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <layout class="ch.qos.logback.classic.PatternLayout">
            <Pattern>%d{yyyy-MM-dd HH:mm:ss} %-5level %logger{36} - %msg%n</Pattern>
        </layout>
    </appender>
    
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${catalina.home}/logs/springdemo.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <FileNamePattern>springdemo.%d{yyyy-MM-dd}.%i.log</FileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy
            class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>10MB</maxFileSize>
                </timeBasedFileNamingAndTriggeringPolicy>
            <maxHistory>10</maxHistory>
        </rollingPolicy>
        <encoder>
            <pattern>%date{HH:mm:ss.SSS} %-5p [%t] %c{1} - %m%n</pattern>
        </encoder>
        <append>true</append>
    </appender>    
    
    <root level="DEBUG">
        <appender-ref ref="STDOUT" />
    </root>

    <logger name="com.osfg" level="DEBUG" additivity="false">
        <appender-ref ref="STDOUT" />
        <appender-ref ref="FILE" />
    </logger>
</configuration>




This is in the same app memtioned above. You can see this file here - https://github.com/aniket91/SpringFeaturesDemo/blob/master/src/logback.xml


And that's it your logging framework is all set to be used. We will now see how we can actually use this logger.


Using slf4j logger in your application

 Following is a simple controller that uses slf4j logging (implementation can be anything underneath - log4j, logback etc)

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Controller;
import org.springframework.ui.ModelMap;
import org.springframework.web.bind.annotation.PathVariable;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RequestMethod;
/**
 * 
 * @author athakur
 * Test controller
 */
@Controller
public class TestController {
    
    Logger logger = LoggerFactory.getLogger(TestController.class);

    @RequestMapping(value="/test/{data}",method=RequestMethod.GET)
    public String test(@PathVariable String data, ModelMap model,
            HttpServletRequest request, HttpServletResponse response) {
        logger.debug("Received request for test controller with data : {}", data);
        model.put("adminName", properties.getAdminName());
        return "test";    
    }
}

You can just run the code and see that logging works. This is again part of the same maven app I mentioned above in case of logback implementation. You can see this file here - https://github.com/aniket91/SpringFeaturesDemo/blob/master/src/com/osfg/controllers/TestController.java





Related Links

No comments:

Post a Comment

t> UA-39527780-1 back to top