By default, Jersey uses JUL for logging – and does not print request/response entity bodies in logs. To print entity content, you must create your own LoggingFiler
, and register it in place of default org.glassfish.jersey.filter.LoggingFilter
. In this example, I am creating one such basic CustomLoggingFilter
which extends org.glassfish.jersey.filter.LoggingFilter
and implements ContainerRequestFilter
and ContainerResponseFilter
interfaces so that it can intercept the ongoing requests and responses.
Table of Contents Create CustomLoggingFilter Register CustomLoggingFilter Log statements with default LoggingFilter Log statements with CustomLoggingFilter
Create CustomLoggingFilter
Let’s go straight to custom logging filter class for this jersey demo.
package com.howtodoinjava.jersey.provider; import java.io.ByteArrayInputStream; import java.io.ByteArrayOutputStream; import java.io.IOException; import java.io.InputStream; import javax.ws.rs.container.ContainerRequestContext; import javax.ws.rs.container.ContainerRequestFilter; import javax.ws.rs.container.ContainerResponseContext; import javax.ws.rs.container.ContainerResponseFilter; import org.glassfish.jersey.filter.LoggingFilter; import org.glassfish.jersey.message.internal.ReaderWriter; public class CustomLoggingFilter extends LoggingFilter implements ContainerRequestFilter, ContainerResponseFilter { @Override public void filter(ContainerRequestContext requestContext) throws IOException { StringBuilder sb = new StringBuilder(); sb.append("User: ").append(requestContext.getSecurityContext().getUserPrincipal() == null ? "unknown" : requestContext.getSecurityContext().getUserPrincipal()); sb.append(" - Path: ").append(requestContext.getUriInfo().getPath()); sb.append(" - Header: ").append(requestContext.getHeaders()); sb.append(" - Entity: ").append(getEntityBody(requestContext)); System.out.println("HTTP REQUEST : " + sb.toString()); } private String getEntityBody(ContainerRequestContext requestContext) { ByteArrayOutputStream out = new ByteArrayOutputStream(); InputStream in = requestContext.getEntityStream(); final StringBuilder b = new StringBuilder(); try { ReaderWriter.writeTo(in, out); byte[] requestEntity = out.toByteArray(); if (requestEntity.length == 0) { b.append("").append("\n"); } else { b.append(new String(requestEntity)).append("\n"); } requestContext.setEntityStream( new ByteArrayInputStream(requestEntity) ); } catch (IOException ex) { //Handle logging error } return b.toString(); } @Override public void filter(ContainerRequestContext requestContext, ContainerResponseContext responseContext) throws IOException { StringBuilder sb = new StringBuilder(); sb.append("Header: ").append(responseContext.getHeaders()); sb.append(" - Entity: ").append(responseContext.getEntity()); System.out.println("HTTP RESPONSE : " + sb.toString()); } }
Register CustomLoggingFilter
To register this CustomLoggingFilter
, register in this way.
package com.howtodoinjava.jersey; import org.glassfish.jersey.jackson.JacksonFeature; import org.glassfish.jersey.server.ResourceConfig; import com.howtodoinjava.jersey.provider.CustomLoggingFilter; public class CustomApplication extends ResourceConfig { public CustomApplication() { packages("com.howtodoinjava.jersey"); register(JacksonFeature.class); register(CustomLoggingFilter.class); } }
Log statements with default LoggingFilter
Now if you try to use any existing REST API without CustomLoggingFilter, logs will appear in this way.
Request
Logs
Sep 30, 2015 6:18:41 PM org.glassfish.jersey.filter.LoggingFilter log INFO: 1 * Server has received a request on thread http-bio-8080-exec-4 1 > POST http://localhost:8080/JerseyDemos/rest/employees 1 > accept: text/html,application/xhtml+xml,application/xml;q=0.9,*/*;q=0.8 1 > accept-encoding: gzip, deflate 1 > accept-language: null 1 > cache-control: no-cache 1 > connection: keep-alive 1 > content-length: 35 1 > content-type: application/json; charset=UTF-8 1 > host: localhost:8080 1 > pragma: no-cache 1 > user-agent: Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.0 Sep 30, 2015 6:18:41 PM org.glassfish.jersey.filter.LoggingFilter log INFO: 1 * Server responded with a response on thread http-bio-8080-exec-4 1 < 200 1 < Content-Type: application/json
Log statements with CustomLoggingFilter
After adding CustomLoggingFilter
, you will get much better logs like below.
HTTP REQUEST : User: unknown - Path: employees - Header: {host=[localhost:8080], user-agent=[Mozilla/5.0 (Windows NT 6.1; WOW64; rv:40.0) Gecko/20100101 Firefox/40.0], accept=, accept-language=[null], accept-encoding=[gzip, deflate], content-type=[application/json; charset=UTF-8], content-length=[35], connection=[keep-alive], pragma=[no-cache], cache-control=[no-cache]} - Entity: {"id":2,"name":"Alex Kolenchiskey"} HTTP RESPONSE : Header: {Content-Type=[application/json]} - Entity: Employee [id=2, name=Alex Kolenchiskey]
Happy Learning !!
Leave a Reply