3

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?

Ethan Davis
  • 93
  • 1
  • 13
  • 2
    I don't know how to do this, so just a couple of comments and not an actual answer! First comment: watch out for security problems this way; you're going to end up logging passwords and such, if you have those! Second comment: this may be something that apache or tomcat or whatever server you're using is better at doing, rather than grails specifically. At least, they're designed to be able to do that without impacting performance or altering the request/response in any way. – Daniel Jul 10 '17 at 16:34
  • Thanks i'll look into what tomcat has to offer! – Ethan Davis Jul 10 '17 at 17:04
  • 1
    Question is similar to the following: https://stackoverflow.com/questions/8831658/grails-on-tomcat-how-to-log-raw-http-request-response – Matthew Heironimus Jul 12 '17 at 01:11

0 Answers0