Can't enable spring orm / transaction log even though log4j.xml is configured

I have a configuration issue to enable spring bundled logging in my application, since I am using EclipseLink, JPA 2.0 and spring 4.0, I need to check when the object manager is closed or cleared during transactions.

My JTA application is included, so everything is controlled by my container (Websphere). Here is my log4j.xml

<?xml version="1.0"?>
<!DOCTYPE log4j:configuration SYSTEM "log4j.dtd">

<log4j:configuration debug="true" xmlns:log4j="http://jakarta.apache.org/log4j/">

    <!-- CONSOLE normally used in desktop environment -->
    <appender name="console" class="org.apache.log4j.ConsoleAppender">
        <param name="Encoding" value="UTF-8" />
        <param name="Threshold" value="DEBUG"/>
        <param name="Target" value="System.out" />
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d [%-8X{context}] %-5p %-40.40c{2} - %m%n"/>
        </layout> 
    </appender>

    <appender name="FILE_APPENDER" class="org.apache.log4j.DailyRollingFileAppender">
        <param name="File" value="C:\\proj\\was\\logs\\spring.log"/>
        <param name="DatePattern" value="'-'yyyy-MM-dd'.txt'"/>
        <param name="Threshold" value="DEBUG"/>
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="%d{yyyy-MM-dd HH:mm:ss} %-4p [%t] %C{2} - %m%n"/>
        </layout>
    </appender>


    <!-- Spring -->
    <logger name="org.springframework.transaction" additivity="false">
        <level value="DEBUG" />
        <appender-ref ref="FILE_APPENDER"/>
    </logger>

    <logger name="org.springframework.orm.jpa.EntityManagerFactoryUtils" additivity="false">
        <level value="DEBUG" />
        <appender-ref ref="FILE_APPENDER"/>
    </logger>

    <logger name="org.springframework.orm.jpa" additivity="false">
        <level value="DEBUG" />
        <appender-ref ref="FILE_APPENDER"/>
    </logger>



     <root>
        <level value="DEBUG" />
        <appender-ref ref="console" />
        <appender-ref ref="FILE_APPENDER" />
    </root> 

</log4j:configuration>

      

I have also tried many solutions like this but it didn't help. Please help me where am I going wrong?

+3


source to share


3 answers


From your comment, it looks like you don't have a slf4j adapter for log4j. Or have a different adapter.

To check the adapter used, use the code:

StaticLoggerBinder binder = StaticLoggerBinder.getSingleton();
System.out.println(binder.getLoggerFactoryClassStr());

      



If the log4j12 adapter is not showing:

  • Check out the war you should have slf4j-api-xxxx.jar in WEB-INF / lib.
  • put slf4j-log4j12-xxxx.jar (same version) in WEB-INF / lib
  • if there is logback-xxxxx.jar remove it, otherwise slf4j will move it to the log
  • if there is log4j-over-slf4j-xxxx.jar remove it, otherwise it is possible that log4j log will be redirected to slf4j which will be redirected to log4j etc.
  • there may be another adapter (like slf4j-jcl-xxxx.jar) that needs to be removed.
+1


source


Registrar hierarchy

In most logging systems, the logger has a parent and child relationship in which children inherit

  • Level
  • Appender
  • ResourceBoudle

from the registrar. And the root registrar exists at the top of inheritance. Children will submit an event log to the fathers log, depending on additivity

. False means it will not post log to log.

So, from the original configuration, you did not allow the associated Spring log to send the log to the root log.

suggestions

So now we understand that we have to set the value additivity

to true and change the log4j configuration like this:

<logger name="org.springframework.transaction" additivity="true"/>

<logger name="org.springframework.orm.jpa.EntityManagerFactoryUtils" additivity="true"/>

<logger name="org.springframework.orm.jpa" additivity="true"/>

 <root>
    <level value="DEBUG" />
    <appender-ref ref="console" />
    <appender-ref ref="FILE_APPENDER" />
</root> 

      



More details

  • Here and here are blog posts I am writing about slf4j and log4j and logback that Spring uses and you can read to improve your understanding of logging;
  • If you change additivity

    and still can't see the log in the console / file, I suggest you set a breakpoint on any line of the logging to EntityManagerFactoryUtils

    , then enter the code to see what is wrong:

Update

The logger EntityManagerFactoryUtils

, as we can from the source code, is not slf4j or log4j. This is a regular registration. So your log4j config about this class won't work.

import org.apache.commons.logging.Log;

private static final Log logger = LogFactory.getLog(EntityManagerFactoryUtils.class);

      

For your configuration to work, you have to do some bridging :

  • exclude commons-logging.jar

    from spring -orm
  • add jcl-over-slf4j.jar

  • make sure you have slf4j-api & slf4j-log4j

0


source


Looking at the Jars on your classpath might need some cleanup, but for that we need to understand what each of the Jars does.

log4j-1.2.9.jar Is the implementation of Log4j. This is necessary in order to log anything with Log4j and of course read the log4j configuration file.

slf4j.api-1.6.1.jar Is an Slf4j API library, only required if you or some of your third party dependencies are using Slf4j for logging, which seems quite likely since you already have it in your classpath. This allows you to write to logs via the Slf4J API, for example:

private static final Logger LOG = org.slf4j.LoggerFactory.getLogger(MyLoggingClass.class);

      

slf4j.jdk14-1.6.1.jar Is JDK 1.4, also known as java.util.logging binding for Slf4j, used to use java.util.logging as the logging mechanism when using Slf4j. Obviously, we will be using log4j as the log implementation, not java.util.logging, which means this needs to be removed.

SLF4J-log4j12-1.7.12.jar Is the log4j 1.2 binding for Slf4j, required to route logs from Slf4j to your Log4j implementation. This is only needed if slf4j.api-1.6.1.jar is required. However, versions must be consistent to avoid conflicts.

commons-logging-1.1.1.jar and commons- logging.jar As far as I can tell, these are both community logging systems. This is the framework used by Spring. However, you should only have one of these in your class, where I recommend using the one that shows the version of it.

If you have the correct Jars in your classpath, commons logging should be able to pick the correct logging implementation for you (which is Log4j in your case). If it is not, explicitly place a file called commons-logging.properties at the root of your classpath and add the following line to it:

org.apache.commons.logging.Log=org.apache.commons.logging.impl.Log4jLogger

      

forcing it to use Log4j as its logging implementation.

0


source







All Articles