How to use log4j 2.0 and slf4j and Commons Logging together

24,735

Solution 1

To which interface do I program my new classes? loag4j or slf4j?

If you're going to use SLF4J, program to that interface. It offers the most flexibility for underlying logging implementation. The point of slf4j is to be an interface that you can program to, so in the future if you decide to switch to, say, logback, you won't have to rewrite your code.

What's the preferred way to deploy the jars? put them in my application war or do i put them into the tomcat libs?

Put them in your WAR.

The only reason (imo) to put JARs in the Tomcat libs directory is if they need to load a native library. Since Java won't allow you to load the same native library from two different classloaders, you need to put then in a common location. But that doesn't apply here.

Some people think of the lib directory as a way to save space. That may have been valid when "server-class" machines had 1 GB of RAM, but it isn't any more. And avoiding lib means you avoid most of the hard-to-debug classloading issues.

what jars do I need to deploy?

  • slf4j-api is the basic API
  • slf4j-log4j12 routes the actual logging to Log4J
  • jcl-over-slf4j intercepts Commons Logging and routes it through SLF4J (to Log4J)
  • log4j will be your physical logging framework

I'm assuming that you already have configuration for Log4J and/or are comfortable writing that configuration. If not, and all you care about is dealing with code that uses Log4J internally, there's log4j-over-slf4j, which will intercept Log4J calls. Then you need to pick a framework, such as Logback.

(note: I originally added links to all of these packages, but don't have enough rep to post them. So here's a single link to the Maven repository with all of the SLF4J packages highlighted)

Solution 2

I am using slf4j with log4j2 and using

slf4j-api-1.7.12.jar
log4j-api-2.2.jar
log4j-core-2.2.jar
log4j-slf4j-impl-2.2.jar
jcl-over-slf4j-1.7.12.jar(get rid of commons logging jars)

if your app server has conflicting versions, you may need to override using some vendor specific classloader settings

e.g. in weblogic 12 c I have this in my weblogic.xml inside src/main/webapp/WEB-INF

<?xml version="1.0" encoding="UTF-8"?>
<weblogic-web-app 
xmlns="http://xmlns.oracle.com/weblogic/weblogic-web-app" 
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" 
xsi:schemaLocation="http://java.sun.com/xml/ns/javaee http://java.sun.com/xml/ns/javaee/web-app_2_5.xsd 
http://xmlns.oracle.com/weblogic/weblogic-web-app http://xmlns.oracle.com/weblogic/weblogic-web-app/1.5/weblogic-web-app.xsd">
<container-descriptor>
    <prefer-application-packages>
        <package-name>org.apache.log4j.*</package-name>
        <package-name>org.apache.commons.logging.*</package-name>
        <package-name>org.apache.commons.lang.*</package-name>
        <package-name>org.apache.commons.io.*</package-name>
        <package-name>org.apache.commons.collections4.*</package-name>
        <package-name>org.slf4j.*</package-name>
    </prefer-application-packages>
</container-descriptor>
<jsp-descriptor>
    <keepgenerated>true</keepgenerated>
    <debug>true</debug>
</jsp-descriptor>
<context-root>/cnfg</context-root>
</weblogic-web-app>

Solution 3

Please note that I have not used Log4J 2.0, although I have used SLF4J with Log4J 1.2. With that being said, I would answer your questions as follows:

  1. Program to SLF4J. It has a nice, simple API that is everything you will probably need from a logging framework. Plus, if you decide for some reason that you want to switch to logback or Log4J 1.2 or whatever instead of Log4J 2.0, you can just switch out the jars on the backend.
  2. Definitely put the jars in the application war. You should almost never put jars into the application server's lib directory. Otherwise, they will affect all web applications on that application server, not just yours. Furthermore, jars in the application server's lib directory cannot be controlled by deploying webapps, but have to be managed manually.
  3. It looks like you will need slf4j-api-1.7.2.jar, log4j-to-slf4j-2.0-beta4.jar, log4j-2.0-beta4.jar and log4j-core-2.0-beta4.jar, along with any dependencies. I'm sure Maven will bring in the required dependencies if you are using that.
Share:
24,735
raudi
Author by

raudi

Updated on June 10, 2020

Comments

  • raudi
    raudi almost 4 years

    I currently am starting a new Webapp (running on tomcat 6) I have components using slf4j and components using commons logging I plan to use log4j 2.0 as log implementation due to several reasons (mainly for the appenders:SocketAppender and SyslogAppender but also because of the promoted config reloading without loss of log events)

    Now my questions are: - To which interface do I program my new classes? loag4j or slf4j? or even commons logging?

    • What's the preferred way to deploy the jars? put them in my application war or do i put them into the tomcat libs?

    • what jars do I need to deploy? log4j (including slf4j and commons bindings), commons logging (slf4j-api-1.7.2.jar) and slf4j api (slf4j-api-1.7.2.jar)

  • raudi
    raudi about 11 years
    1. OK 2. as I understand it if I put all jars in my war I have the disadvantage that I can not have the logging configuration outside the war and (with auto-update) manipulate the configuration at runtime. (This might more be a tomcat/log4j_2.0 question and I should ask it in a separate post) 3. as I plan to use log4j 2.0 I assume I need log4j-slf4j-impl.jar instead of slf4j-log4j12.jar, is this correct?
  • parsifal
    parsifal about 11 years
    Haven't used log4j 2.0, so not sure which implementation JAR you'll need. But that should be available on the SLF4J site.
  • parsifal
    parsifal about 11 years
    As for keeping your configuration external so you can modify it on the fly: you can still do this, putting just the config file in the lib directory (and nothing in the WAR). It'll be found by a classpath scan from within the WAR. However, I much prefer using JMX to adjust logging levels. There's a JMX bean in Log4J 1.2, and I would expect also in 2.0; if you instantiate it, it registers itself with the platform JMX provider, so you can use a tool like JConsole to access it.
  • Benny Bottema
    Benny Bottema over 10 years
    This solution does not use log4j2, but 1.2.
  • Chathura Priyankara
    Chathura Priyankara about 9 years
    slf4j-log4j12 use log4j 1.2 not log4j 2.X.