generated from pricelees/issue-pr-template
feat: API 요청 / 응답 결과 기록 필터 추가
This commit is contained in:
parent
792a2281e6
commit
d34a6ad27e
65
src/main/kotlin/roomescape/common/log/LoggingFilter.kt
Normal file
65
src/main/kotlin/roomescape/common/log/LoggingFilter.kt
Normal file
@ -0,0 +1,65 @@
|
|||||||
|
package roomescape.common.log
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper
|
||||||
|
import io.github.oshai.kotlinlogging.KotlinLogging
|
||||||
|
import jakarta.servlet.FilterChain
|
||||||
|
import jakarta.servlet.http.HttpServletRequest
|
||||||
|
import jakarta.servlet.http.HttpServletResponse
|
||||||
|
import org.springframework.core.Ordered
|
||||||
|
import org.springframework.core.annotation.Order
|
||||||
|
import org.springframework.stereotype.Component
|
||||||
|
import org.springframework.web.filter.OncePerRequestFilter
|
||||||
|
import org.springframework.web.util.ContentCachingRequestWrapper
|
||||||
|
import org.springframework.web.util.ContentCachingResponseWrapper
|
||||||
|
|
||||||
|
private val log = KotlinLogging.logger {}
|
||||||
|
|
||||||
|
@Component
|
||||||
|
@Order(Ordered.HIGHEST_PRECEDENCE)
|
||||||
|
class LoggingFilter(
|
||||||
|
private val objectMapper: ObjectMapper
|
||||||
|
) : OncePerRequestFilter() {
|
||||||
|
|
||||||
|
override fun doFilterInternal(
|
||||||
|
request: HttpServletRequest,
|
||||||
|
response: HttpServletResponse,
|
||||||
|
filterChain: FilterChain
|
||||||
|
) {
|
||||||
|
val cachedRequest = ContentCachingRequestWrapper(request)
|
||||||
|
val cachedResponse = ContentCachingResponseWrapper(response)
|
||||||
|
|
||||||
|
val startTime = System.currentTimeMillis()
|
||||||
|
filterChain.doFilter(cachedRequest, cachedResponse)
|
||||||
|
val duration = System.currentTimeMillis() - startTime
|
||||||
|
|
||||||
|
logAPISummary(cachedRequest, cachedResponse, duration)
|
||||||
|
cachedResponse.copyBodyToResponse()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun logAPISummary(
|
||||||
|
request: ContentCachingRequestWrapper,
|
||||||
|
response: ContentCachingResponseWrapper,
|
||||||
|
duration: Long
|
||||||
|
) {
|
||||||
|
val payload = linkedMapOf<String, Any>(
|
||||||
|
"type" to "API_LOG",
|
||||||
|
"method" to request.method,
|
||||||
|
"url" to request.requestURL.toString(),
|
||||||
|
)
|
||||||
|
request.queryString?.let { payload["query_params"] = it }
|
||||||
|
payload["remote_ip"] = request.remoteAddr
|
||||||
|
payload["status_code"] = response.status
|
||||||
|
payload["duration_ms"] = duration
|
||||||
|
|
||||||
|
if (log.isDebugEnabled()) {
|
||||||
|
request.contentAsByteArray.takeIf { it.isNotEmpty() }
|
||||||
|
?.let { payload["request_body"] = objectMapper.readValue(it, Map::class.java) }
|
||||||
|
|
||||||
|
response.contentAsByteArray.takeIf { it.isNotEmpty() }
|
||||||
|
?.let { payload["response_body"] = objectMapper.readValue(it, Map::class.java) }
|
||||||
|
}
|
||||||
|
|
||||||
|
log.info { objectMapper.writeValueAsString(payload) }
|
||||||
|
}
|
||||||
|
}
|
||||||
Loading…
x
Reference in New Issue
Block a user