1

I've created a test webapp in Maven that uses logback. Here is my logback.xml configuration file:

<configuration scan="true">

  <!-- For more information: http://logback.qos.ch/manual/configuration.html -->

  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <!-- encoders are assigned the type
         ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
    <encoder>
      <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
    </encoder>
  </appender>

  <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>D:/Oracle/user_projects/domains/base_domain/servers/AdminServer/logs/myapp.log</file>

    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <!-- daily rollover -->
      <fileNamePattern>D:/Oracle/user_projects/domains/base_domain/servers/AdminServer/logs/archive/myapp.%d{yyyy-MM-dd}.log</fileNamePattern>

      <!-- keep 31 days' worth of history -->
      <maxHistory>31</maxHistory>
    </rollingPolicy>

    <encoder>
      <pattern>%date [%level] [%thread] [%file:%line] %msg%n</pattern>
    </encoder>
  </appender>

  <root level="debug">
    <appender-ref ref="FILE" />
    <appender-ref ref="STDOUT" />
  </root>

</configuration>

I've copied this file to both src/main/resources and src/test/resources

When I run mvn test, everything works fine. The test log message is written to both the console, as well as the myapp.log file:

public class TestLogService extends TestCase {

    public TestLogService( String name ) {
        super( name );
    }

    public void testLogMessage() throws Exception {
        LogService.debug( "Hello from {}!", "TestLogService" );
    }

}

After that, I run mvn install and deploy the resulting war file (which has logback.xml under WEB-INF/classes) to my local WebLogic server. Once that's done, I hit a test servlet which is supposed to just log a single statement to the log file:

public class TestServlet extends HttpServlet {
    private static final long serialVersionUID = 1L;

    public TestServlet() {
        // TODO Auto-generated constructor stub
    }

    protected void doGet(HttpServletRequest request, HttpServletResponse response) throws ServletException, IOException {
        LogService.debug( "Hello from {}!", "doGet()" );
        response.getWriter().append("Served at: ").append(request.getContextPath());
    }
}

But, aside from the "Served at: /myapp" output, nothing happens! Nothing is written to the log file, nor the console. I don't even get any error messages on the console. It's as if logback is failing silently or something.

And the LogService class is just a wrapper for logback calls:

public class LogService {

    private static Logger logger = LoggerFactory.getLogger("com.myapp");

    public static void debug( String message ) {
        logger.debug( message );
    }

    public static void debug( String message, Object... argArray ) {
        logger.debug( message, argArray );
    }
}

I tried setting logback.configurationFile property in my Java start options, as well setting it programmatically as detailed here (Setting logback.xml path programmatically).

But I got the exact same result with both approaches: mvn test logs the message just fine, but nothing happens when I run the test servlet on localhost.

Any idea what the issue could be?

Additional Information

I added some debug statements to LogService:

System.out.println("[LogService.debug] isDebugEnabled = " + logger.isDebugEnabled());
System.out.println("[LogService.debug] getName = " + logger.getName());
System.out.println("[LogService.debug] ROOT_LOGGER_NAME = " + Logger.ROOT_LOGGER_NAME);
System.out.println("[LogService.debug] toString = " + logger.toString());

And now mvn test and hitting the TestServlet give different output:

mvn test says:                                      TestServlet says:
-----------------------------------------------     -----------------------------------------------
[LogService.debug] isDebugEnabled = true            [LogService.debug] isDebugEnabled = false
[LogService.debug] getName = com.myapp              [LogService.debug] getName = com.myapp
[LogService.debug] ROOT_LOGGER_NAME = ROOT          [LogService.debug] ROOT_LOGGER_NAME = ROOT
[LogService.debug] toString = Logger[com.myapp]     [LogService.debug] toString = org.slf4j.impl.JDK14LoggerAdapter(com.myapp)

So that at least explains why I don't see debug log statements from the TestServlet. Now I just have to figure out why.

Community
  • 1
  • 1
Eren
  • 68
  • 3
  • 9
  • To troubleshoot, try enabling debug output with ``. Alternatively, enable debug with a system property `-Dlogback.debug=true`. – tony19 Jun 09 '16 at 20:57
  • @tony19 Thanks. I enabled debug output, and saw the debug output with mvn test. But hitting the servlet continues to give me silent treatment. I'm starting to think the problem is something incredibly simple and obvious that I've managed to completely miss. – Eren Jun 10 '16 at 12:22
  • It looks like logback logging implementation is not picked up by SLF4J. Please check whether logback.jar is in web-app/lib and that there are no other logging implementations like slf4j-jdk14 logging. – inigo skimmer Jun 10 '16 at 12:55

1 Answers1

5

It sounds like you need to override the default SLF4J implementation in WebLogic. To do this, add the following code to your weblogic.xml file:

<wls:container-descriptor>
        <wls:prefer-web-inf-classes>true</wls:prefer-web-inf-classes>
</wls:container-descriptor>

This will prioritize the SLF4J implementation that you provided with your other necessary logback libs.

In regards to configuration file location, you're going to want to put your logback.xml file in your domain root, which should look something like: "../user_projects/domains/$domain_name".

I hope this helps.

Derek
  • 76
  • 6