Showing posts with label Logging. Show all posts
Showing posts with label Logging. Show all posts

Monday, 22 October 2012

Setting Logging Dependencies In Spring

This post describes how to set-up logging dependencies in Spring. It is based on information available in a post by Dave Syer. A reminder on Java logging frameworks is available here. The code example is available at GitHub in the Spring-Logging-Dependencies directory.

Spring uses Jakarta Commons Logging API (JCL). Unfortunately, many people do not like its runtime discovery algorithm. We can disactivate it and use SLF4J with Logback instead. We will use a variation of the Spring MVC with Annotations example to do so.

Here is the modified controller:
import org.springframework.stereotype.Controller;
import org.springframework.ui.Model;
import org.springframework.web.bind.annotation.RequestMapping;

@Controller
public class MyController {

    private static final Logger LOG
        = LoggerFactory.getLogger(MyController.class);

    @RequestMapping(value = "/")
    public String home(Model model) {

        String s = "Logging at: " + System.currentTimeMillis();
        LOG.info(s);

        model.addAttribute("LogMsg", s);

        return "index";

    }

}
We create a SFL4J logger and log some information with current time in milliseconds.

The maven dependencies are:
<properties>
    ...
    <spring.version>3.1.2.RELEASE</spring.version>
    <slf4j.version>1.7.1</slf4j.version>
    <logback.version>0.9.30</logback.version>
</properties>

<dependency>
    <groupId>org.springframework</groupId>
    <artifactId>spring-context</artifactId>
    <version>${spring.version}</version>
    <exclusions>
        <exclusion>
            <groupId>commons-logging</groupId>
            <artifactId>commons-logging</artifactId>
        </exclusion>
    </exclusions>
    <type>jar</type>
</dependency>

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>jcl-over-slf4j</artifactId>
    <version>${slf4j.version}</version>
    <scope>runtime</scope>
</dependency>

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

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

Once built, one can start the example by browsing: http://localhost:9393/spring-logging-dependencies/. It will display the following:

Spring Logging Configuration

In the logs, you will find the logged statement:

Spring Logging Statement

More Spring posts here.

Tuesday, 16 October 2012

Understanding Logging Frameworks In Java

Logging in Java is about reporting issues at runtime in an application. Information about an issue is collected, then formatted and at last handled by an issue handler. This handler may display the issue (log record) on a screen, report it in a file or in a database. These log records can be tagged for severity and filtered too.

History

Over time, several logging frameworks were created by different parties for Java. Therefore, Java libraries were written using different logging frameworks. This was not an issue if an application used a unique logging framework, but when they started to reference each other's libraries, it became a different game.

This is why logging interfaces were created to bridge these multiple logging frameworks. The purpose is to centralize logs calls to one framework.

Log4J

Log4J is a login framework which was created before Sun Microsystems introduced its own logging framework (called JUL of JDK Logger) in Java 1.4. Many developers chose to stick to Log4J, rather than move to the JDK Logger, because it contained better features.

However, after logging interfaces were created, some people became wary of Log4J, because it is very low level. They were using Java libraries using different frameworks. Many decided to use logging interfaces, rather than directly implementing Log4J in their code.

Java Logging API (JUL or JDK Logger)

This logging framework is available in the java.util.logging package since Java 1.4. It can be extended via the API. Many developers complained about too many logging levels: FINE, FINER, FINEST where DEGUG would have been enough, or missing features which Log4J was already offering.

Some developers also complained this framework was not well designed for web containers. For example, some containers, such as Tomcat, provided access to a common root logger shared by multiple applications. If a filter was set on it, it was set for all applications.

Jakarta Commons Logging API (JCL)

JCL is a logging interface developed by Apache. It aims at bridging different logging frameworks (Log4J, JUL, ...) through a discovery process at runtime. Unfortunately, some fundamental issues were reported, especially in multi-classloader contexts. See here for a detailed discussion.

SLF4J

SLF4J stands for Simple Logging Facade for Java, it is a logging interface. Per se, one must configure a target logging framework which will receive calls made to SLF4J. It is also possible to use bridges for third parties libraries using a different logging framework. For example, the JUL bridge to SLF4J will forward every third party log call made to JUL to SFL4J, which will call the configured logging framework.

Logback

Logback is the introduced as the successor of Log4J. It implements SLF4J natively, which improves performance dramatically in some cases. It can be used as the target framework for SLF4J.

Conclusion

There are many logging frameworks we have not covered here. Today, the safe strategy, for an application referencing 3rd party libraries using different logging frameworks, is SLF4J with corresponding bridges. For performance, configuring Logback as the target of SLF4J is a good choice.