generated from pricelees/issue-pr-template
<!-- 제목 양식 --> <!-- [이슈번호] 작업 요약 (예시: [#10] Gitea 템플릿 생성) --> ## 📝 관련 이슈 및 PR **PR과 관련된 이슈 번호** - #26 ## ✨ 작업 내용 <!-- 어떤 작업을 했는지 알려주세요! --> - actuator, micrometer tracing / datasource 추가 - 로그에 traceId, spanId 추가 - 로깅 방식 개선: 필터가 http 요청 기록 -> 컨트롤러 요청 / 응답은 AOP를 이용하여 기록 ## 🧪 테스트 <!-- 어떤 테스트를 생각했고 진행했는지 알려주세요! --> - 로그 메시지를 만들고, 마스킹하는 두 클래스에 대한 테스트 완료 - 전체 테스트 정상 통과 확인 ## 📚 참고 자료 및 기타 <!-- 참고한 자료, 또는 논의할 사항이 있다면 알려주세요! --> Reviewed-on: #27 Co-authored-by: pricelees <priceelees@gmail.com> Co-committed-by: pricelees <priceelees@gmail.com>
82 lines
2.5 KiB
Kotlin
82 lines
2.5 KiB
Kotlin
package roomescape.common.log
|
|
|
|
import com.fasterxml.jackson.databind.ObjectMapper
|
|
import jakarta.servlet.http.HttpServletRequest
|
|
import org.slf4j.MDC
|
|
|
|
enum class LogType {
|
|
INCOMING_HTTP_REQUEST,
|
|
CONTROLLER_INVOKED,
|
|
CONTROLLER_SUCCESS,
|
|
AUTHENTICATION_FAILURE,
|
|
APPLICATION_FAILURE,
|
|
UNHANDLED_EXCEPTION
|
|
}
|
|
|
|
class ApiLogMessageConverter(
|
|
private val objectMapper: ObjectMapper
|
|
) {
|
|
fun convertToHttpRequestMessage(
|
|
request: HttpServletRequest
|
|
): String {
|
|
val payload: MutableMap<String, Any> = commonRequestPayload(LogType.INCOMING_HTTP_REQUEST, request)
|
|
|
|
request.queryString?.let { payload["query_params"] = it }
|
|
payload["client_ip"] = request.remoteAddr
|
|
payload["user_agent"] = request.getHeader("User-Agent")
|
|
|
|
return objectMapper.writeValueAsString(payload)
|
|
}
|
|
|
|
fun convertToControllerInvokedMessage(
|
|
request: HttpServletRequest,
|
|
controllerPayload: Map<String, Any>,
|
|
): String {
|
|
val payload: MutableMap<String, Any> = commonRequestPayload(LogType.CONTROLLER_INVOKED, request)
|
|
val memberId: Long? = MDC.get("member_id")?.toLong()
|
|
if (memberId != null) payload["member_id"] = memberId else payload["member_id"] = "NONE"
|
|
|
|
payload.putAll(controllerPayload)
|
|
|
|
return objectMapper.writeValueAsString(payload)
|
|
}
|
|
|
|
fun convertToResponseMessage(request: ConvertResponseMessageRequest): String {
|
|
val payload: MutableMap<String, Any> = mutableMapOf()
|
|
payload["type"] = request.type
|
|
payload["status_code"] = request.httpStatus
|
|
|
|
MDC.get("member_id")?.toLongOrNull()
|
|
?.let { payload["member_id"] = it }
|
|
?: run { payload["member_id"] = "NONE" }
|
|
|
|
request.startTime?.let { payload["duration_ms"] = System.currentTimeMillis() - it }
|
|
request.body?.let { payload["response_body"] = it }
|
|
request.exception?.let {
|
|
payload["exception"] = mapOf(
|
|
"class" to it.javaClass.simpleName,
|
|
"message" to it.message
|
|
)
|
|
}
|
|
|
|
return objectMapper.writeValueAsString(payload)
|
|
}
|
|
|
|
private fun commonRequestPayload(
|
|
logType: LogType,
|
|
request: HttpServletRequest
|
|
): MutableMap<String, Any> = mutableMapOf(
|
|
"type" to logType,
|
|
"method" to request.method,
|
|
"uri" to request.requestURI
|
|
)
|
|
}
|
|
|
|
data class ConvertResponseMessageRequest(
|
|
val type: LogType,
|
|
val httpStatus: Int = 200,
|
|
val startTime: Long? = null,
|
|
val body: Any? = null,
|
|
val exception: Exception? = null
|
|
)
|