Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[DEPLOY] logging (#100) #101

Merged
merged 1 commit into from
Aug 20, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,9 @@ import jakarta.servlet.http.HttpServletRequest
import jakarta.servlet.http.HttpServletResponse
import net.minidev.json.JSONObject
import org.slf4j.LoggerFactory
import org.slf4j.MDC
import org.springframework.security.access.AccessDeniedException
import org.springframework.security.core.context.SecurityContextHolder
import org.springframework.security.web.access.AccessDeniedHandler
import org.springframework.stereotype.Component

Expand All @@ -26,11 +28,24 @@ class JwtAccessDeniedHandler : AccessDeniedHandler {
put("isSuccess", false)
}

val authentication = SecurityContextHolder.getContext().authentication
if (authentication != null && authentication.isAuthenticated) {
val userString = authentication.name.toString()
val userId = parseUserIdFromPrincipal(userString)
MDC.put("userId", userId)
}

logger.error("접근 권한이 없는 토큰으로 요청했습니다. : {}", accessDeniedException.message, accessDeniedException)

response.writer.print(json)
}

private fun parseUserIdFromPrincipal(userString: String): String {
val idPattern = """id=(\d+)""".toRegex()
val matchResult = idPattern.find(userString)
return matchResult?.groupValues?.get(1) ?: "unknown"
}

companion object {
private val logger = LoggerFactory.getLogger("AuthenticationLog")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import jakarta.servlet.http.HttpServletRequest
import jakarta.servlet.http.HttpServletResponse
import net.minidev.json.JSONObject
import org.slf4j.LoggerFactory
import org.slf4j.MDC
import org.springframework.security.core.AuthenticationException
import org.springframework.security.web.AuthenticationEntryPoint
import org.springframework.stereotype.Component
Expand All @@ -17,6 +18,7 @@ class JwtAuthenticationEntryPoint : AuthenticationEntryPoint {
authException: AuthenticationException,
) {
val exception = request.getAttribute("exception") as? String
MDC.put("userId", "anonymous")
when (exception) {
"NotExistUser" -> {
setResponse(response, ErrorType.NOT_EXIST_USER_ERROR)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@ import jakarta.servlet.FilterChain
import jakarta.servlet.http.HttpServletRequest
import jakarta.servlet.http.HttpServletResponse
import org.slf4j.LoggerFactory
import org.slf4j.MDC
import org.springframework.security.core.context.SecurityContextHolder
import org.springframework.stereotype.Component
import org.springframework.web.context.request.RequestContextHolder
Expand All @@ -26,6 +27,7 @@ class JwtAuthenticationFilter(
if (!jwt.isNullOrBlank() && jwtValidator.validateAccessTokenFromRequest(servletRequest, jwt)) {
val authentication = jwtValidator.getAuthentication(jwt)
SecurityContextHolder.getContext().authentication = authentication
MDC.put("userId", parseUserIdFromPrincipal(authentication.name.toString()))
Companion.logger.info("${authentication.name} 해당하는 유저가 $requestURI 경로로 접근했습니다.")
}

Expand All @@ -44,6 +46,12 @@ class JwtAuthenticationFilter(
}
}

private fun parseUserIdFromPrincipal(userString: String): String {
val idPattern = """id=(\d+)""".toRegex()
val matchResult = idPattern.find(userString)
return matchResult?.groupValues?.get(1) ?: "unknown"
}

companion object {
private val logger = LoggerFactory.getLogger("AuthenticationLog")
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -4,18 +4,44 @@ import com.myongjiway.core.api.support.error.CoreApiException
import com.myongjiway.core.api.support.error.ErrorType
import com.myongjiway.core.api.support.response.ApiResponse
import com.myongjiway.core.domain.error.CoreException
import org.slf4j.LoggerFactory
import org.slf4j.MDC
import org.springframework.http.ResponseEntity
import org.springframework.web.bind.annotation.ExceptionHandler
import org.springframework.web.bind.annotation.RestControllerAdvice

@RestControllerAdvice
class ApiControllerAdvice {
@ExceptionHandler(CoreApiException::class)
fun handleCoreApiException(e: CoreApiException): ResponseEntity<ApiResponse<Any>> = ResponseEntity(ApiResponse.error(e.errorType, e.data), e.errorType.status)
fun handleCoreApiException(e: CoreApiException): ResponseEntity<ApiResponse<Any>> {
MDC.put("status", e.errorType.status.toString())
logging(e)
return ResponseEntity(ApiResponse.error(e.errorType, e.data), e.errorType.status)
}

@ExceptionHandler(Exception::class)
fun handleException(e: Exception): ResponseEntity<ApiResponse<Any>> = ResponseEntity(ApiResponse.error(ErrorType.DEFAULT_ERROR, e.message), ErrorType.DEFAULT_ERROR.status)
fun handleException(e: Exception): ResponseEntity<ApiResponse<Any>> {
MDC.put("status", "500")
logging(e, true)
return ResponseEntity(ApiResponse.error(ErrorType.DEFAULT_ERROR, e.message), ErrorType.DEFAULT_ERROR.status)
}

@ExceptionHandler(CoreException::class)
fun handleCoreException(e: CoreException): ResponseEntity<ApiResponse<Any>> = ResponseEntity(ApiResponse.error(e.coreErrorType, e.data), ErrorType.COMMON_ERROR.status)
fun handleCoreException(e: CoreException): ResponseEntity<ApiResponse<Any>> {
MDC.put("status", "400")
logging(e)
return ResponseEntity(ApiResponse.error(e.coreErrorType, e.data), ErrorType.COMMON_ERROR.status)
}

private fun logging(e: Throwable, includeFullStackTrace: Boolean = false) {
if (includeFullStackTrace) {
MDC.put("exceptionFull", e.stackTraceToString())
}
logger.error("Exception occurred", e)
MDC.clear()
}

companion object {
private val logger = LoggerFactory.getLogger("ErrorLog")
}
}

This file was deleted.

Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package com.myongjiway.core.api.support.logging

import jakarta.servlet.http.HttpServletRequest
import org.aspectj.lang.JoinPoint
import org.aspectj.lang.annotation.After
import org.aspectj.lang.annotation.Aspect
import org.aspectj.lang.annotation.Before
import org.aspectj.lang.annotation.Pointcut
import org.slf4j.LoggerFactory
import org.slf4j.MDC
import org.springframework.security.core.context.SecurityContextHolder
import org.springframework.stereotype.Component
import org.springframework.web.context.request.RequestContextHolder
import org.springframework.web.context.request.ServletRequestAttributes
import java.util.UUID

@Aspect
@Component
class RequestLoggingAspect {

// core-api 모듈의 모든 컨트롤러 메서드에 적용
@Pointcut("execution(* com.myongjiway.core.api..controller..*(..))")
fun coreApiControllerMethods() {}

// 요청 전 로깅
@Before("coreApiControllerMethods()")
fun logRequest(joinPoint: JoinPoint) {
val request = getCurrentHttpRequest()
MDC.put("method", request.method)
MDC.put("requestUri", request.requestURI)
MDC.put("sourceIp", request.remoteAddr)
MDC.put("userAgent", request.getHeader("User-Agent"))
MDC.put("referer", request.getHeader("Referer") ?: "Direct Access")
MDC.put("requestId", UUID.randomUUID().toString())

val authentication = SecurityContextHolder.getContext().authentication
if (authentication != null && authentication.isAuthenticated) {
val userString = authentication.name.toString()
val userId = parseUserIdFromPrincipal(userString)
MDC.put("userId", userId)
}

logger.info("Request received for method: ${joinPoint.signature.name}")
}

@After("coreApiControllerMethods()")
fun clearMDC() {
MDC.clear()
}

private fun getCurrentHttpRequest(): HttpServletRequest =
(RequestContextHolder.currentRequestAttributes() as ServletRequestAttributes).request

private fun parseUserIdFromPrincipal(userString: String): String {
val idPattern = """id=(\d+)""".toRegex()
val matchResult = idPattern.find(userString)
return matchResult?.groupValues?.get(1) ?: "unknown"
}

companion object {
private val logger = LoggerFactory.getLogger("HttpRequestLog")
}
}
19 changes: 9 additions & 10 deletions support/logging/src/main/resources/logback/logback-live.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,7 +13,7 @@
<!-- 에러 로그 파일 출력 앱펜더 -->
<appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<filter class="ch.qos.logback.classic.filter.ThresholdFilter">
<level>WARN</level>
<level>ERROR</level>
</filter>

<file>logs/error.log</file>
Expand All @@ -33,16 +33,10 @@
{
"timestamp": "%d{yyyy-MM-dd'T'HH:mm:ss.SSS'Z'}",
"level": "%level",
"logger": "%logger",
"thread": "%thread",
"class": "%class",
"method": "%method",
"line": "%line",
"exception": "%ex{short}",
"exceptionFull": "%X{exceptionFull:-}",
"message": "%message",
"api": "%X{api:-}",
"userId": "%X{userId:-}",
"requestId": "%X{requestId:-}",
"status": "%X{status:-}"
}
</pattern>
Expand Down Expand Up @@ -104,6 +98,7 @@
{
"timestamp": "%d{yyyy-MM-dd'T'HH:mm:ss.SSS'Z'}",
"level": "%level",
"userId": "%X{userId:-}",
"message": "%message"
}
</pattern>
Expand All @@ -122,6 +117,11 @@
<appender-ref ref="AUTHENTICATION"/>
</logger>

<!-- 에러 로거 -->
<logger name="ErrorLog" level="ERROR" additivity="false">
<appender-ref ref="FILE"/>
</logger>

<!-- Spring 프레임워크 로거 -->
<logger name="org.springframework" level="INFO" additivity="false">
<appender-ref ref="STDOUT"/>
Expand All @@ -135,7 +135,6 @@
<!-- 루트 로거 -->
<root level="INFO">
<appender-ref ref="STDOUT"/>
<appender-ref ref="FILE"/>
</root>
</configuration>

</configuration>
Loading
Loading