Logging HTTP requests and responses in quarkus resteasy

3 min read 05-10-2024
Logging HTTP requests and responses in quarkus resteasy


Logging HTTP Requests and Responses in Quarkus RESTEasy: A Comprehensive Guide

Problem: You're building a Quarkus RESTEasy application and need to log incoming HTTP requests and outgoing responses for debugging, security, or audit purposes.

Rephrased: Imagine you're building a web application. You want to see exactly what requests are coming in and what responses your application sends back. This is useful for troubleshooting problems, understanding how your app is behaving, or for tracking user activity.

Scenario: Let's say you have a simple REST endpoint in your Quarkus application:

@Path("/users")
public class UserController {

    @GET
    @Produces(MediaType.APPLICATION_JSON)
    public List<User> getUsers() {
        // ... Logic to retrieve users
        return userList;
    }
}

You want to log the incoming HTTP request (e.g., method, path, headers) and the outgoing response (e.g., status code, headers, response body).

Solution: Quarkus provides a powerful logging system that seamlessly integrates with RESTEasy. You can leverage this to log HTTP requests and responses efficiently. Here's how:

1. Enable Logging:

By default, Quarkus provides basic logging using SLF4J. You can configure the logging level in your application.properties file:

quarkus.log.level=INFO

2. Use the RequestLoggingFilter:

RESTEasy offers a built-in RequestLoggingFilter that automatically logs request details. Add the following dependency to your pom.xml:

<dependency>
    <groupId>org.jboss.resteasy</groupId>
    <artifactId>resteasy-jaxrs</artifactId>
</dependency>

And activate the filter in your application.properties:

quarkus.resteasy.request-logging.enabled=true

This will log the request method, path, headers, and request body (if enabled). You can further customize the logging format and level using properties like:

  • quarkus.resteasy.request-logging.level: Sets the logging level (e.g., DEBUG, INFO).
  • quarkus.resteasy.request-logging.log-body: Enables/disables logging of the request body.
  • quarkus.resteasy.request-logging.log-headers: Enables/disables logging of request headers.

3. Log Response Details:

To log response details, you can use a custom filter or interceptor. Here's an example using a @PreMatching interceptor:

import org.jboss.resteasy.annotations.interception.PreMatching;
import org.jboss.resteasy.core.ResourceMethodInvoker;
import org.jboss.resteasy.spi.HttpRequest;
import org.jboss.resteasy.spi.HttpResponse;

import javax.interceptor.AroundInvoke;
import javax.interceptor.Interceptor;
import javax.interceptor.InvocationContext;
import java.io.ByteArrayOutputStream;
import java.io.IOException;

@Interceptor
@PreMatching
public class ResponseLoggingInterceptor {

    @AroundInvoke
    public Object logResponse(InvocationContext invocationContext) throws Exception {
        Object result = invocationContext.proceed();
        ResourceMethodInvoker methodInvoker = (ResourceMethodInvoker) invocationContext.getTarget();
        HttpRequest request = methodInvoker.getHttpRequest();
        HttpResponse response = methodInvoker.getHttpResponse();

        // Log the response
        logResponse(request, response, result);
        return result;
    }

    private void logResponse(HttpRequest request, HttpResponse response, Object result) throws IOException {
        // Extract response body
        ByteArrayOutputStream baos = new ByteArrayOutputStream();
        response.getOutputStream().transferTo(baos);
        String responseBody = new String(baos.toByteArray());

        // Log the response details
        log.info("Response details: {}", String.format("Request: %s, Path: %s, Method: %s, Status Code: %s, Response Body: %s",
                request.getRemoteAddr(),
                request.getUri(),
                request.getMethod(),
                response.getStatus(),
                responseBody));
    }
}

Explanation:

  • This interceptor intercepts the request before it reaches the endpoint method.
  • It then proceeds with the request and captures the response.
  • Finally, it logs the response details, including the status code, headers, and body.

Benefits:

  • Increased Visibility: Comprehensive logging of requests and responses provides valuable insights into your application's behavior.
  • Debugging Made Easier: Easily track down issues by analyzing request and response logs.
  • Security Monitoring: Log suspicious activities or unauthorized access attempts.
  • Auditing and Compliance: Meet audit requirements by logging user activity.

Additional Tips:

  • Log Level: Adjust the logging level to suit your needs (DEBUG, INFO, WARN, ERROR).
  • Body Logging: Be mindful of logging sensitive information within request or response bodies.
  • Filtering: Use log4j filters or patterns to customize the logging format and filter specific information.
  • Centralized Logging: Consider using a centralized logging solution (e.g., ELK stack) for efficient log management and analysis.

Conclusion:

By incorporating HTTP request and response logging in your Quarkus RESTEasy application, you gain invaluable insights that improve debugging, security, and auditing capabilities. Utilize the provided techniques and customize them to fit your specific needs, ensuring a robust and transparent application.

Resources: