0

I hope I can find some help do understand how I can fix my sample application log.

This is a Jersey server and this is its only resource:

package br.com.logplanning.jersey.resources;

import javax.ws.rs.GET;
import javax.ws.rs.Path;
import javax.ws.rs.Produces;
import javax.ws.rs.core.MediaType;

@Path("hello")
public class HelloResource {

    @GET
    @Produces(MediaType.TEXT_PLAIN)
    public String showMessage() {
        return "Hello from Brazil";
    }

}

The structure of the sample project is this:

Sample Project Structure

This is the pom.xml, with all dependencies I think Jersey demands to work:

<project xmlns="http://maven.apache.org/POM/4.0.0"
    xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
    xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>

    <groupId>br.com.logplanning.jersey</groupId>
    <artifactId>hello-jersey-logging</artifactId>
    <version>1.0-SNAPSHOT</version>

    <packaging>war</packaging>

    <name>Jersey and LoggingFeatures</name>
    <url>http://wwww.logplanning.com.br</url>

    <properties>
        <project.build.sourceEncoding>UTF-8</project.build.sourceEncoding>
        <maven.compiler.source>1.8</maven.compiler.source>
        <maven.compiler.target>1.8</maven.compiler.target>
        <junit.version>4.12</junit.version>
        <javax.servlet.version>3.1.0</javax.servlet.version>
        <jersey.version>2.28</jersey.version>
    </properties>

    <build>
        <finalName>hello-jersey-logging</finalName>
    </build>

    <dependencies>
        <dependency>
            <groupId>junit</groupId>
            <artifactId>junit</artifactId>
            <version>${junit.version}</version>
        </dependency>
        <dependency>
            <groupId>javax.servlet</groupId>
            <artifactId>javax.servlet-api</artifactId>
            <version>${javax.servlet.version}</version>
            <scope>provided</scope>
        </dependency>
        <dependency>
            <groupId>org.glassfish.jersey.core</groupId>
            <artifactId>jersey-server</artifactId>
            <version>${jersey.version}</version>
        </dependency>

        <dependency>
            <groupId>org.glassfish.jersey.containers</groupId>
            <artifactId>jersey-container-servlet</artifactId>
            <version>${jersey.version}</version>
        </dependency>

        <dependency>
            <groupId>org.glassfish.jersey.media</groupId>
            <artifactId>jersey-media-moxy</artifactId>
            <version>${jersey.version}</version>
        </dependency>

        <dependency>
            <groupId>org.glassfish.jersey.inject</groupId>
            <artifactId>jersey-hk2</artifactId>
            <version>${jersey.version}</version>
        </dependency>

    </dependencies>
</project>

The Jersey's ServletContainer is initialized via deployment descriptor (I couldn't make it start by code):

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         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"
         version="3.1">
    <display-name>Contact - REST Service</display-name>
    <servlet>
        <servlet-name>Jersey and LoggingFeatures</servlet-name>
        <servlet-class>org.glassfish.jersey.servlet.ServletContainer</servlet-class>
        <init-param>
            <param-name>jersey.config.server.provider.packages</param-name>
            <param-value>br.com.logplanning.jersey.resources</param-value>
        </init-param>
        <load-on-startup>1</load-on-startup>
    </servlet>
    <servlet-mapping>
        <servlet-name>Jersey and LoggingFeatures</servlet-name>
        <url-pattern>/*</url-pattern>
    </servlet-mapping>
</web-app>

Finally, the project has this class to configure the LoggingFeature:

package br.com.logplanning.jersey.resources;

import java.util.Enumeration;
import java.util.logging.ConsoleHandler;
import java.util.logging.Formatter;
import java.util.logging.Handler;
import java.util.logging.Level;
import java.util.logging.LogManager;
import java.util.logging.Logger;
import java.util.logging.SimpleFormatter;

import javax.ws.rs.ApplicationPath;

import org.glassfish.jersey.logging.LoggingFeature;
import org.glassfish.jersey.server.ResourceConfig;

@ApplicationPath("resources")
public class AppResourceConfig extends ResourceConfig {

    private static final Logger LOG = Logger.getLogger(AppResourceConfig.class.getName());

    public AppResourceConfig() {
        // Registering a new LoggingFeature object
        register(new LoggingFeature(Logger.getLogger(LoggingFeature.DEFAULT_LOGGER_NAME), Level.ALL, LoggingFeature.Verbosity.PAYLOAD_ANY, Integer.MAX_VALUE));
        LOG.info("===========> " + LoggingFeature.DEFAULT_LOGGER_NAME);

        // Searching for all handlers and setting then to Level.ALL
        LogManager manager = LogManager.getLogManager();
        Enumeration<String> loggerNames = manager.getLoggerNames();
        while (loggerNames.hasMoreElements()) {
            String nextElement = loggerNames.nextElement();
            Logger logger = manager.getLogger(nextElement);
            if (logger.getHandlers().length > 0) {
                Handler[] handlers = logger.getHandlers();
                for (Handler h : handlers) {
                    Level oldLevel = h.getLevel();
                    if (!oldLevel.equals(Level.ALL))
                        h.setLevel(Level.ALL);
                        LOG.info("===========> " + nextElement + ": from " + oldLevel + " to " + h.getLevel());
                    }
                }
            }
        }
    }

}

The problem is that the requests and the responses are not being logged while the endpoint is being called.

I tried, as you can see above, to be sure that the logger would be set properly no matter what.

I think that its handler is in place, but for some reason Jersey is not sending it anything.

I would appreciate some clarifications, please.

Community
  • 1
  • 1

2 Answers2

1

I think that its handler is in place, but for some reason Jersey is not sending it anything.

The logger tree is dynamic and will attach loggers to the tree as code demands the creation of a logger. It is possible your configuration code is running before the code created the logger. Try setting the root logger level to ALL as this logger is always created. This is done by adding the following to your code:

Logger.getLogger("").setLevel(Level.ALL);

Next verify that the logger level changes have been applied to your logger tree and handlers. You can also use JConsole in most cases to inspect the logger tree at runtime.

If you know the name of the logger that records the requests and responses then you can create 'private static final' references to those logger by calling Logger::getLogger with the proper argument.

jmehrens
  • 10,580
  • 1
  • 38
  • 47
0

Thanks for your help, jmehrens, now everything is working fine! First, I got rid of DD (web.xml) initialization. The web.xml file has been reduced to its minimum content, like so:

<web-app xmlns="http://xmlns.jcp.org/xml/ns/javaee"
         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"
         version="3.1">
    <display-name>Contact - REST Service</display-name>
</web-app>

All the initialization were put together into the AppResourceConfig class:

package br.com.logplanning.jersey.resources;

import java.util.logging.Level;
import java.util.logging.Logger;

import javax.ws.rs.ApplicationPath;

import org.glassfish.jersey.logging.LoggingFeature;
import org.glassfish.jersey.server.ResourceConfig;

@ApplicationPath("resources")
public class AppResourceConfig extends ResourceConfig {

    private static final Logger LOGGING_INTERCEPTOR = Logger.getLogger(LoggingFeature.DEFAULT_LOGGER_NAME);

    public AppResourceConfig() {
        //Registering the resources package (no DD needed)
        packages("br.com.logplanning.jersey.resources");

        // Registering a new LoggingFeature object
        //https://www.javaguides.net/2018/06/jersey-rest-logging-using-loggingfeature.html
        register(new LoggingFeature(LOGGING_INTERCEPTOR, Level.INFO,
                LoggingFeature.Verbosity.PAYLOAD_ANY, Integer.MAX_VALUE));

        // https://stackoverflow.com/questions/44882648/logging-not-showing/44888306#44888306
        Logger.getLogger("").setLevel(Level.INFO);
    }
}

One part of the solutions was to correct the logger hierarchy settings and another part was about initializing the log intercepting along with the resource package registration.

svarog
  • 9,477
  • 4
  • 61
  • 77