Guide to Jersey logging on Server and Client side

In this guide, we will learn how to enable logging in Jersey rest API web application. Basically, we can enable logging on the server and client side. In this guide, we will learn step by step with complete source code example. 
Important : Jersey uses JDK built-in logging feature : `java.util.logging`

Technology and tools used

  • Maven 3
  • JDK 8
  • Jersey 2.27
  • Apache Tomcat 8.5
  • Eclipse Neon

1. Create a Maven Web Application Project

You can create a quick start Java web application project by using the Maven maven-archetype-webapp template. In a terminal (*Unix or Mac) or command prompt (Windows), navigate to the folder you want to create the project.
Type this command :
$ mvn archetype:generate -DgroupId={project-packaging} 
 -DartifactId={project-name} 
 -DarchetypeArtifactId=maven-archetype-webapp 
 -DinteractiveMode=false

//for example 
$ mvn archetype:generate -DgroupId=com.ramesh
 -DartifactId=jersey-logging-server-client-example
 -DarchetypeArtifactId=maven-archetype-webapp 
 -DinteractiveMode=false

2. Update Jersey Dependencies in a Pom.Xml File

<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/maven-v4_0_0.xsd">
  <modelVersion>4.0.0</modelVersion>
  <groupId>com.javadevelopersguide.jersey</groupId>
  <artifactId>jersey-logging-server-client-example</artifactId>
  <packaging>war</packaging>
  <version>0.0.1-SNAPSHOT</version>
  <name>jersey-logging-server-client-example Maven Webapp</name>
  <url>http://maven.apache.org</url>
  
  <dependencies>
     <!-- https://mvnrepository.com/artifact/javax.servlet/javax.servlet-api -->
   <dependency>
   <groupId>javax.servlet</groupId>
   <artifactId>javax.servlet-api</artifactId>
   <version>3.1.0</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>

  <!-- https://mvnrepository.com/artifact/org.glassfish.jersey.media/jersey-media-moxy -->
  <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>

  <!-- Required only when you are using JAX-RS Client -->
  <dependency>
   <groupId>org.glassfish.jersey.core</groupId>
   <artifactId>jersey-client</artifactId>
   <version>${jersey.version}</version>
  </dependency>

  <dependency>
   <groupId>org.slf4j</groupId>
   <artifactId>slf4j-log4j12</artifactId>
   <version>1.7.21</version>
  </dependency>
 </dependencies>

 <build>
  <finalName>jersey-logging-server-client-example</finalName>
  <plugins>
   <plugin>
    <groupId>org.apache.maven.plugins</groupId>
    <artifactId>maven-war-plugin</artifactId>
    <configuration>
     <failOnMissingWebXml>false</failOnMissingWebXml>
    </configuration>
   </plugin>
   <plugin>
    <artifactId>maven-compiler-plugin</artifactId>
    <version>2.0.2</version>
    <configuration>
     <source>1.8</source>
     <target>1.8</target>
    </configuration>
   </plugin>
   <plugin>
    <groupId>org.apache.tomcat.maven</groupId>
    <artifactId>tomcat7-maven-plugin</artifactId>
    <version>2.2</version>
   </plugin>
  </plugins>
 </build>

 <properties>
  <jersey.version>2.26</jersey.version>
 </properties>
 
</project>

3. Data Model - User

User class is the data model for this RESTful CRUD services. I have used moxy-json support for JSON binding feature from jersey-media-moxy.
package com.javadevelopersguide.jersey.model;

import javax.xml.bind.annotation.XmlRootElement;

@XmlRootElement
public class User {
 private long id;
 private String name;
 private String email;
 
 public User() {
  
 }
 
 
 public User(long id, String name, String email) {
  super();
  this.id = id;
  this.name = name;
  this.email = email;
 }
 public long getId() {
  return id;
 }
 public void setId(long id) {
  this.id = id;
 }
 public String getName() {
  return name;
 }
 public void setName(String name) {
  this.name = name;
 }
 public String getEmail() {
  return email;
 }
 public void setEmail(String email) {
  this.email = email;
 }
}

4. Create a Resource class - UserResource.java

Create Rest APIs in root UserResource class.
@Path("/users")
public class UserResource {

 @GET
 @Produces(MediaType.APPLICATION_JSON)
 public List<User> fetchAll() {
   List<User> users = new ArrayList<User>();
  users.add(new User(100, "A", "[email protected]"));
  users.add(new User(101, "B", "[email protected]"));
  users.add(new User(102, "C", "[email protected]"));
  return users;
 }
}

5. Descriptor-Less Deployment Configuration

5.1 Configure server-side logging

import javax.ws.rs.ApplicationPath;

// Deployment of a JAX-RS application using @ApplicationPath with Servlet 3.0
// Descriptor-less deployment
import org.glassfish.jersey.server.ResourceConfig;

@ApplicationPath("resources")
public class AppResourceConfig extends ResourceConfig {
 public AppResourceConfig() {
  packages("com.javadevelopersguide.jersey.resources");
  register(new LoggingFeature(Logger.getLogger(LoggingFeature.DEFAULT_LOGGER_NAME),
    Level.INFO, LoggingFeature.Verbosity.PAYLOAD_ANY, 10000));
 }
}
From the above configuration, the important part to configure logging on the server side is:
register(new LoggingFeature(Logger.getLogger(LoggingFeature.DEFAULT_LOGGER_NAME),
    Level.INFO, LoggingFeature.Verbosity.PAYLOAD_ANY, 10000));

5.2 Configure client-side logging

package com.javadevelopersguide.jersey.client;

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

import javax.ws.rs.client.Client;
import javax.ws.rs.client.ClientBuilder;
import javax.ws.rs.core.MediaType;

import org.glassfish.jersey.client.ClientConfig;
import org.glassfish.jersey.logging.LoggingFeature;

public class UserResourceClient {

 public static void main(String[] args) {
   getUsers();
 }
 protected static ClientConfig createClientConfig() {
  ClientConfig config = new ClientConfig();
  config.register(new LoggingFeature(Logger.getLogger(LoggingFeature.DEFAULT_LOGGER_NAME), Level.INFO, LoggingFeature.Verbosity.PAYLOAD_ANY, 10000));
  return config;
 }
 
 private static void getUsers() {
  Client client = ClientBuilder.newClient(createClientConfig());

  String entity = client.target("http://localhost:8080/jersey-logging-server-client-example/resources").path("users")
    .request(MediaType.APPLICATION_JSON).header("some-header", "true").get(String.class);

  System.out.println(entity);
 }

}
From the above configuration, the important part to configure logging on the client side is:
ClientConfig config = new ClientConfig();
  config.register(new LoggingFeature(Logger.getLogger(LoggingFeature.DEFAULT_LOGGER_NAME), Level.INFO, LoggingFeature.Verbosity.PAYLOAD_ANY, 10000));

6. Output

Let's print the logging in the console:
Jun 13, 2018 6:15:02 PM org.glassfish.jersey.logging.LoggingInterceptor log
INFO: 6 * Server has received a request on thread http-nio-8080-exec-7
6 > GET http://localhost:8080/jersey-logging-server-client-example/resources/users
6 > accept: text/html,application/xhtml+xml,application/xml;q=0.9,image/webp,image/apng,*/*;q=0.8
6 > accept-encoding: gzip, deflate, br
6 > accept-language: en-US,en;q=0.9
6 > cache-control: max-age=0
6 > connection: keep-alive
6 > host: localhost:8080
6 > upgrade-insecure-requests: 1
6 > user-agent: Mozilla/5.0 (Windows NT 6.1; Win64; x64) AppleWebKit/537.36 (KHTML, like Gecko) Chrome/67.0.3396.79 Safari/537.36

Jun 13, 2018 6:15:02 PM org.glassfish.jersey.logging.LoggingInterceptor log
INFO: 6 * Server responded with a response on thread http-nio-8080-exec-7
6 < 200
6 < Content-Type: application/json
[{"email":"[email protected]","id":100,"name":"A"},{"email":"[email protected]","id":101,"name":"B"},{"email":"[email protected]","id":102,"name":"C"}]

7. Conclusion

This guide illustrated how to enable logging on the server side and client side in Jersey Framework.
In the next guide of the series, we will focus on more Jersey rest examples, concepts, and more.
All the code of this article is available over on Github. This is a Maven-based project, so it should be easy to import and run as it is.

Github Repository: Guide to Jersey logging on Server and Client side

Comments