ServletContextRequestLoggingFilter

공부는 혼자하는 거·2023년 9월 21일
0

Spring Tip

목록 보기
48/52

그동안은 Request 로깅을 위해 별도의 런타임 프록시를 이용했는데, 이번에는 스프링부트에서 제공하는 클래스인 ServletContextRequestLoggingFilter 라는 걸 알아서 이걸 한 번 커스텀해서 사용해보았다.

class CustomServletContextRequestLoggingFilter(


) : ServletContextRequestLoggingFilter() {

    init {
        isIncludeHeaders = true
        isIncludeClientInfo = true
        isIncludePayload = true
        isIncludeQueryString = true
        maxPayloadLength = 1000
    }

    override fun shouldLog(request: HttpServletRequest): Boolean {
  
        val userAgent = request.getHeader("User-Agent")
        return !userAgent.contains("ELB-HealthChecker")
    }


    override fun createMessage(request: HttpServletRequest, prefix: String, suffix: String): String {

        val url = if (isIncludeQueryString){
            var requestURI = request.requestURI
            val queryString = request?.queryString
            if (queryString != null){
                requestURI += "?$queryString"

            }
            requestURI
        }else request.requestURI

        val headers = if (isIncludeHeaders) {
            val httpHeaders = ServletServerHttpRequest(request).getHeaders()
            if (headerPredicate != null) {
                val names = request.headerNames
                while (names.hasMoreElements()) {
                    val header = names.nextElement()
                    if (!headerPredicate!!.test(header)) {
                        httpHeaders[header] = "masked"
                    }
                }
            }
            httpHeaders.toString()
        }else ""


        val clientInfoTotal = if (isIncludeClientInfo) {
            var clientInfo = ""
            if (StringUtils.hasLength(request.remoteAddr)) {
                clientInfo += " , client=${request.remoteAddr} "
            }
            if (request.getSession(false) != null) {
                clientInfo += " , session=${request.getSession(false).id} "
            }
            if (request.remoteUser != null) {
                clientInfo += " , user=${request.remoteUser} "
            }
            clientInfo
        }else ""


        val payload = if (isIncludePayload) {
            val payloadData = getMessagePayload(request)
            payloadData ?: ""
        }else ""


        return  """
            
            HTTP Method: ${request.method}
            url: ${url} 
            clientInfo: ${clientInfoTotal}
            headers: ${headers}
            payload: $payload
                      
        """.trimIndent()
    }
}

user-agent:"ELB-HealthChecker/2.0" ELB 헬스체크 요청은 모조리 로깅에서 제외했다. 기본으로 제공하는 로그 메시지 양식이 맘에 안 들어서 직접 createMessage를 오버라이딩하였다.

@Configuration 클래스에 간단하게 Bean으로 동작하면 작동한다.

참고

https://veluxer62.github.io/retrospective/2023-may-dev-log/

profile
시간대비효율

0개의 댓글