generated from pricelees/issue-pr-template
feat: 로그 관련 설정 클래스 추가 및 이전의 로깅 필터 제거
This commit is contained in:
parent
660ac5ebc9
commit
0cab9c133a
35
src/main/kotlin/roomescape/common/log/LogConfiguration.kt
Normal file
35
src/main/kotlin/roomescape/common/log/LogConfiguration.kt
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
package roomescape.common.log
|
||||||
|
|
||||||
|
import com.fasterxml.jackson.databind.ObjectMapper
|
||||||
|
import org.springframework.boot.web.servlet.FilterRegistrationBean
|
||||||
|
import org.springframework.context.annotation.Bean
|
||||||
|
import org.springframework.context.annotation.Configuration
|
||||||
|
import org.springframework.context.annotation.DependsOn
|
||||||
|
import org.springframework.core.Ordered
|
||||||
|
import org.springframework.web.filter.OncePerRequestFilter
|
||||||
|
|
||||||
|
@Configuration
|
||||||
|
class LogConfiguration {
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@DependsOn(value = ["apiLogMessageConverter"])
|
||||||
|
fun filterRegistrationBean(
|
||||||
|
apiLogMessageConverter: ApiLogMessageConverter
|
||||||
|
): FilterRegistrationBean<OncePerRequestFilter> {
|
||||||
|
val filter = HttpRequestLoggingFilter(apiLogMessageConverter)
|
||||||
|
|
||||||
|
return FilterRegistrationBean<OncePerRequestFilter>(filter)
|
||||||
|
.apply { this.order = Ordered.HIGHEST_PRECEDENCE + 2 }
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
@DependsOn(value = ["apiLogMessageConverter"])
|
||||||
|
fun apiLoggingAspect(apiLogMessageConverter: ApiLogMessageConverter): ControllerLoggingAspect {
|
||||||
|
return ControllerLoggingAspect(apiLogMessageConverter)
|
||||||
|
}
|
||||||
|
|
||||||
|
@Bean
|
||||||
|
fun apiLogMessageConverter(objectMapper: ObjectMapper): ApiLogMessageConverter {
|
||||||
|
return ApiLogMessageConverter(objectMapper)
|
||||||
|
}
|
||||||
|
}
|
||||||
@ -1,74 +0,0 @@
|
|||||||
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
|
|
||||||
import java.nio.charset.StandardCharsets
|
|
||||||
|
|
||||||
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"] = parseContent(it) }
|
|
||||||
|
|
||||||
response.contentAsByteArray.takeIf { it.isNotEmpty() }
|
|
||||||
?.let { payload["response_body"] = parseContent(it) }
|
|
||||||
}
|
|
||||||
|
|
||||||
log.info { objectMapper.writeValueAsString(payload) }
|
|
||||||
}
|
|
||||||
|
|
||||||
private fun parseContent(content: ByteArray): Any {
|
|
||||||
return try {
|
|
||||||
objectMapper.readValue(content, Map::class.java)
|
|
||||||
} catch (_: Exception) {
|
|
||||||
String(content, StandardCharsets.UTF_8)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Loading…
x
Reference in New Issue
Block a user