I am trying to figure out how to log every request and its associated response that comes into my application. Currently I have created a Grails interceptor that captures the request and response. The issue that I keep running into is if I log the request body before it reaches the controller then the resource is consumed by my logger and request body is null. So I tried logging the request body after it's been processed by the controller. The problem with that is then the input stream is closed and I can no longer access it.
this is my interceptor:
import grails.plugin.springsecurity.SpringSecurityService
import javax.servlet.ServletRequest
class HttpLoggingInterceptor {
SpringSecurityService springSecurityService
HttpLoggingService httpLoggingService
HttpLoggingInterceptor() {
match(controller: "*")
}
boolean before() {
httpLoggingService.logRequest(request, response, springSecurityService.principal)
true
}
}
This is the httpLoggingService:
import grails.transaction.Transactional
import org.apache.commons.io.IOUtils
import org.springframework.security.core.userdetails.User
import javax.servlet.http.HttpServletRequest
import javax.servlet.http.HttpServletRequestWrapper
import javax.servlet.http.HttpServletResponse
import java.nio.charset.StandardCharsets
@Transactional
class HttpLoggingService {
static final String CR = "\r\n"
def logRequest(HttpServletRequestWrapper request, HttpServletResponse response, User user) {
log.debug("REQUEST:${CR}" +
"Request URL: ${request?.method} ${request?.requestURL}${CR}" +
"Request QueryString: ${request?.queryString}${CR}" +
"Request Body : ${getRequestBody(request)}" +
"Request Client IP: ${request?.remoteAddr}${CR}" +
"Request User: ${getUserInfo(user)}${CR}" +
"Request Headers: ${getRequestHeaders(request)}${CR}" +
"Request Query String Parameters: ${getRequestParameters(request)}${CR}" +
"Response Status: ${response?.status}${CR}" +
"Respones Body: ${getResponseBody(response)}" +
"Response Properties: ${response?.properties}${CR}" +
"Response Headers: ${getResponseHeaders(response)}${CR}" +
CR
)
}
private String getUserInfo(User user) {
String userInfo = null
if (user instanceof CipUserDetails) {
userInfo = "${user?.username} [${user?.fullName}] - ${user?.authorities[0]?.role}"
}
userInfo
}
private String getRequestBody(HttpServletRequestWrapper request) {
String requestBody = IOUtils.toString(request.getInputStream(), StandardCharsets.UTF_8)
requestBody
}
private String getRequestParameters(HttpServletRequest request) {
Map parameterMap = request?.parameterMap
String parameterString = ""
for (String name : request?.parameterNames) {
parameterString += "${CR} ${name}=${parameterMap?.get(name)}"
}
parameterString
}
private String getRequestHeaders(HttpServletRequest request) {
String parameterString = ""
for (String name : request.headerNames) {
parameterString += "${CR} ${name}=${request?.getHeader(name)}"
}
parameterString
}
private String getResponseHeaders(HttpServletResponse response) {
String parameterString = ""
for (String name : response?.headerNames) {
parameterString += "${CR} ${name}=${response?.getHeader(name)}"
}
parameterString
}
}
Could someone please help me figure out how to do this?