[#26] 모니터링 환경 구성 #27

Merged
pricelees merged 14 commits from feature/#26 into main 2025-07-29 06:49:56 +00:00
Showing only changes of commit 660ac5ebc9 - Show all commits

View File

@ -0,0 +1,94 @@
package roomescape.common.log
import io.github.oshai.kotlinlogging.KLogger
import io.github.oshai.kotlinlogging.KotlinLogging
import jakarta.servlet.http.HttpServletRequest
import org.aspectj.lang.JoinPoint
import org.aspectj.lang.ProceedingJoinPoint
import org.aspectj.lang.annotation.Around
import org.aspectj.lang.annotation.Aspect
import org.aspectj.lang.annotation.Pointcut
import org.aspectj.lang.reflect.MethodSignature
import org.slf4j.MDC
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.PathVariable
import org.springframework.web.bind.annotation.RequestBody
import org.springframework.web.bind.annotation.RequestParam
import org.springframework.web.context.request.RequestContextHolder
import org.springframework.web.context.request.ServletRequestAttributes
private val log: KLogger = KotlinLogging.logger {}
@Aspect
class ControllerLoggingAspect(
private val messageConverter: ApiLogMessageConverter,
) {
@Pointcut("execution(* roomescape..web..*Controller.*(..))")
fun allController() {
}
@Around("allController()")
fun logAPICalls(joinPoint: ProceedingJoinPoint): Any? {
val startTime: Long = MDC.get("startTime").toLongOrNull() ?: System.currentTimeMillis()
val controllerPayload: Map<String, Any> = parsePayload(joinPoint)
log.info {
messageConverter.convertToControllerInvokedMessage(servletRequest(), controllerPayload)
}
try {
return joinPoint.proceed()
.also { logSuccess(startTime, it) }
} catch (e: Exception) {
throw e
}
}
private fun logSuccess(startTime: Long, result: Any) {
val responseEntity = result as ResponseEntity<*>
val logMessage = messageConverter.convertToResponseMessage(
ConvertResponseMessageRequest(
type = LogType.CONTROLLER_SUCCESS,
httpStatus = responseEntity.statusCode.value(),
startTime = startTime,
body = responseEntity.body
)
)
log.info { logMessage }
}
private fun servletRequest(): HttpServletRequest {
return (RequestContextHolder.currentRequestAttributes() as ServletRequestAttributes).request
}
private fun parsePayload(joinPoint: JoinPoint): Map<String, Any> {
val signature = joinPoint.signature as MethodSignature
val args = joinPoint.args
val payload = mutableMapOf<String, Any>()
payload["controller_method"] = joinPoint.signature.toShortString()
val requestParams: MutableMap<String, Any> = mutableMapOf()
val pathVariables: MutableMap<String, Any> = mutableMapOf()
signature.method.parameters.forEachIndexed { index, parameter ->
val arg = args[index]
parameter.getAnnotation(RequestBody::class.java)?.let {
payload["request_body"] = arg
}
parameter.getAnnotation(PathVariable::class.java)?.let {
pathVariables[parameter.name] = arg
}
parameter.getAnnotation(RequestParam::class.java)?.let {
requestParams[parameter.name] = arg
}
}
if (pathVariables.isNotEmpty()) payload["path_variable"] = pathVariables
if (requestParams.isNotEmpty()) payload["request_param"] = requestParams
return payload
}
}