Search code examples
hibernatelogginglog4jlog4j2weblogic12c

Log4j + Hibernate 5 + Weblogic 12.2.1


I use Hibernate 5.2.10.Final, log4j 1.2.17 (from here), Weblogic 12.2.1. This is how my log4j.xml looks like:

<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE log4j:configuration PUBLIC
  "-//APACHE//DTD LOG4J 1.2//EN" "http://logging.apache.org/log4j/1.2/apidocs/org/apache/log4j/xml/doc-files/log4j.dtd">
<log4j:configuration xmlns:log4j="http://jakarta.apache.org/log4j/">

    <appender name="console" class="org.apache.log4j.ConsoleAppender">
        <param name="Target" value="System.out" />
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern" value="[%5p] %d{yyyy-MM-dd HH:mm:ss} [%x] [%C.%M] - %m %n" />
        </layout>
    </appender>

    <appender name="logFile" class="org.apache.log4j.RollingFileAppender">
        <param name="File" value="../logs/mylog.log"/>
        <param name="MaxFileSize" value="100MB"/>
        <layout class="org.apache.log4j.PatternLayout">
            <param name="ConversionPattern"
                value="[%5p] %d{yyyy-MM-dd HH:mm:ss} - %m %n" />
        </layout>
    </appender>

    <logger name="interceptorLog" additivity="false">
        <level value="INFO" />
        <appender-ref ref="logFile" />
    </logger>

    <root>
        <priority value="ALL" />
        <appender-ref ref="logFile"/>
    </root>

</log4j:configuration>

Right now, all of my own logging goes to mylog.log - that's fine. When some Hibernate exceptions occur, these logs go to <weblogic-domain>/servers/AdminServer/MyApplication.log, what I want is for them to go to the same file as my logs.

At this point I tried basically everything: migrating to log4j2 (following this), adding hibernate loggers/categories to my log4j.xml, for example:

<logger name="org.hibernate">
    <level value="ALL" />
    <appender-ref ref="logFile"/>
</logger>

No progress at all, no matter what changes I make it's like they have no effect (unless I make some errors of course). I'm starting to think Weblogic is behind this, I guess the Hibernate logs go to error output and Weblogic is redirecting them to his files, no idea why I can't force them to be logged into mylog.log.

I'm mostly concerned about the exceptions, I would like to see them together with all the of my custom logs, not hidden somewhere in Weblogic domain files.


Solution

  • It can be frustrating at times to deal Java EE application servers (especially WLS) without fully understanding their class loading mechanism. Long story short, for making this work with WLS 12, you'll need to instruct WebLogic to prefer org.jboss.logging.* packages (from jboss-logging; dependency for hibernate-core) from your application libs using deployment descriptor (weblogic.xml). You can read about it here.

    An example to help you:

    <?xml version="1.0" encoding="UTF-8"?>
    <wls:weblogic-web-app
    xmlns:wls="http://xmlns.oracle.com/weblogic/weblogic-web-app"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://xmlns.jcp.org/xml/ns/javaee
         http://xmlns.jcp.org/xml/ns/javaee/web-app_3_1.xsd http://xmlns.oracle.com/weblogic/weblogic-web-app
     http://xmlns.oracle.com/weblogic/weblogic-web-app/1.9/weblogic-web-app.xsd">
    
    <wls:weblogic-version>12.2.1.2.0</wls:weblogic-version>
    
    <wls:context-root>example</wls:context-root>
    
    <wls:container-descriptor>
        <wls:prefer-application-packages>
            <wls:package-name>org.springframework.*</wls:package-name>
            <wls:package-name>org.hibernate.*</wls:package-name>
            <wls:package-name>org.apache.*</wls:package-name>
            <wls:package-name>javax.validation.*</wls:package-name>
            <wls:package-name>com.fasterxml.jackson.*</wls:package-name>
            <wls:package-name>org.slf4j.*</wls:package-name>
            <wls:package-name>org.jboss.logging.*</wls:package-name>
        </wls:prefer-application-packages>
        <wls:prefer-application-resources>
            <wls:resource-name>org/slf4j/impl/StaticLoggerBinder.class</wls:resource-name>
        </wls:prefer-application-resources>
    </wls:container-descriptor>
    

    The above configuration uses SLF4J as the logging API and the new Log4J (log4j2) as logging backend. But even if you are using Log4J (note that older log4j has been deprecated now) straight away, this should pretty much do it for you.