4

How would I go about getting Jersey LoggingFilter working with logback? I saw this post:

How to get jersey logs at server?

but it unfortunately relies on the java.util.Logger. I am not super well versed when it comes to web.xml configuration so I would not know how to go about offering the init-param different loggers.

Note that I am using Spring 3 for dependency injection, but am creating loggers per class with the code:

Logger logger = LoggerFactory.getLogger(MyClass.class);

Hope this is enough information. If not, let me know.

My web container is Tomcat 7.0.12.

Community
  • 1
  • 1
thatidiotguy
  • 8,701
  • 13
  • 60
  • 105

3 Answers3

4

I tried to use Jersey-Spring4 with logback and was not able to redirect access logs via the LoggingFeature to my logback-logger. The logback-logger was configured like <logger name="org.glassfish.jersey" level="INFO"/> and I assumed this should do the trick.

After I learned that Jersey is using JUL, I was sad for a few minutes and carried on with using org.slf4j:jul-to-slf4j. To make it work I had to

private void registerLogback(final ServletContext servletContext) {
    servletContext.addListener(new LogbackConfigListener());

    //this is only necessary if you externalise logback.xml from resources     
    try { LogbackConfigurer.initLogging(servletContext.getRealPath("/WEB-INF/logback.xml")); }
    catch (FileNotFoundException | JoranException e) { e.printStackTrace(); }

    LogManager.getLogManager().reset();
    SLF4JBridgeHandler.removeHandlersForRootLogger();
    SLF4JBridgeHandler.install();
}

in my WebApplicationInitializer.onStartup(ServletContext servletContext).

My ResourceConfig looked like

register(new LoggingFeature(createLogger(), Level.ALL, LoggingFeature.DEFAULT_VERBOSITY, 0)); 

private Logger createLogger() {
    final ConsoleHandler consoleHandler = new ConsoleHandler();
    consoleHandler.setLevel(Level.ALL);

    final Logger logger = Logger.getLogger(Logger.GLOBAL_LOGGER_NAME);
    logger.setLevel(Level.ALL);
    logger.addHandler(consoleHandler);

    return logger;
}

What logged access to the console. Removing the ConsoleHandler sadly did not end up in logs being logged to the logback-logger, the just got swallowed. But the red log statements on the console gave me the hint that this could be STDERR, albeit their were INFO.

Finally LoggingFeature not logging correctly based on configuration on constructor gave me the missing piece.

My final and working ResourceConfig ended up as

register(new LoggingFeature(Logger.getLogger(LoggingFeature.DEFAULT_LOGGER_NAME), Level.INFO, LoggingFeature.DEFAULT_VERBOSITY, 0));

Where LoggingFeature.DEFAULT_LOGGER_NAME and Level.INFO seem to be the crucial part.

In the end I don't know exactly went wrong, but this is the result of my guessing and it works. If this helps anybody I am happy.

sschrass
  • 7,014
  • 6
  • 43
  • 62
2

You can bridge java.util.Logger calls to Logback by using the jul-to-slf4j bridge. With that installed you can control Jersey logging (and any other JUL) with your logback.xml.

yossis
  • 1,243
  • 2
  • 11
  • 11
  • So I just add `handlers = org.slf4j.bridge.SLF4JBridgeHandler` to a `logging.properties` file in my classpath? – thatidiotguy Nov 05 '12 at 21:28
  • Yes. Or programmatically bu calling SLF4JBridgeHandler.install() upon initialization – yossis Nov 05 '12 at 22:25
  • 1
    So the documentation says "Once SLF4JBridgeHandler is installed, logging by j.u.l. loggers will be directed to SLF4J". What does this mean exactly? I am using logback with SLF4J and I have my logging redirected to several files. Am I going to need different configuration options to catch this? I guess I am asking what SLF4J is going to do with this information? – thatidiotguy Nov 05 '12 at 22:27
1

Slf4jLogger from org.apache.cxf:cxf-core package is another option. It implements java.util.logging.Logger and delegate cals to slf4J.

Jersey server:

ResourceConfig config = new ResourceConfig(HelloWorldResource.class);
config.register(
    new Slf4jLogger(this.getClass().getName(), null));

Jersey client:

ClientBuilder
    .newClient()
    .register(
        new LoggingFeature(
                new Slf4jLogger(this.getClass().getName(), null)));