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:
- Quarkus documentation: https://quarkus.io/guides/
- RESTEasy documentation: https://www.resteasy.org/
- SLF4J documentation: https://www.slf4j.org/