22
33import devkor .ontime_back .dto .RequestInfoDto ;
44import devkor .ontime_back .entity .ApiLog ;
5- import devkor .ontime_back .repository . ApiLogRepository ;
5+ import devkor .ontime_back .logging . RequestLogPolicy ;
66import devkor .ontime_back .response .GeneralException ;
77import devkor .ontime_back .service .ApiLogService ;
88import jakarta .servlet .http .HttpServletRequest ;
99import lombok .RequiredArgsConstructor ;
1010import lombok .extern .slf4j .Slf4j ;
11- import org .aspectj .lang .JoinPoint ;
1211import org .aspectj .lang .ProceedingJoinPoint ;
13- import org .aspectj .lang .annotation .AfterThrowing ;
1412import org .aspectj .lang .annotation .Around ;
1513import org .aspectj .lang .annotation .Aspect ;
1614import org .aspectj .lang .annotation .Pointcut ;
17- import org .aspectj .lang .reflect .MethodSignature ;
1815import org .springframework .http .ResponseEntity ;
19- import org .springframework .security .access .AccessDeniedException ;
2016import org .springframework .security .core .Authentication ;
2117import org .springframework .security .core .context .SecurityContextHolder ;
2218import org .springframework .stereotype .Component ;
23- import org .springframework .web .bind .MethodArgumentNotValidException ;
24- import org .springframework .web .bind .annotation .PathVariable ;
25- import org .springframework .web .bind .annotation .RequestBody ;
2619import org .springframework .web .context .request .RequestContextHolder ;
2720import org .springframework .web .context .request .ServletRequestAttributes ;
2821
29- import java .lang .annotation .Annotation ;
30- import java .util .Map ;
31-
32-
3322@ Slf4j
3423@ Aspect
3524@ Component
3625@ RequiredArgsConstructor
3726public class LoggingAspect {
3827
3928 private final ApiLogService apiLogService ;
40- private static final String NO_PARAMS = "No Params" ;
41- private static final String NO_BODY = "No Body" ;
4229
4330 @ Pointcut ("bean(*Controller)" )
4431 private void allRequest () {}
4532
4633 @ Around ("allRequest()" )
4734 public Object logRequest (ProceedingJoinPoint joinPoint ) throws Throwable {
48- RequestInfoDto requestInfoDto = extractRequestInfo ();
49-
50- // requestTime
35+ ServletRequestAttributes attributes = (ServletRequestAttributes ) RequestContextHolder .currentRequestAttributes ();
36+ HttpServletRequest request = attributes .getRequest ();
37+ String requestId = RequestLogPolicy .resolveRequestId (request );
38+ RequestLogPolicy .exposeRequestId (attributes , requestId );
39+ RequestInfoDto requestInfoDto = extractRequestInfo (request );
5140 long beforeRequest = System .currentTimeMillis ();
5241
53- // pathVariable, requestBody
54- MethodSignature signature = (MethodSignature ) joinPoint .getSignature ();
55- Object [] args = joinPoint .getArgs ();
56- Annotation [][] parameterAnnotations = signature .getMethod ().getParameterAnnotations ();
57-
58- String pathVariable = null ;
59- String requestBody = null ;
60-
61- for (int i = 0 ; i < parameterAnnotations .length ; i ++) {
62- Annotation [] annotations = parameterAnnotations [i ];
63- for (Annotation annotation : annotations ) {
64- if (annotation instanceof PathVariable ) {
65- pathVariable = args [i ].toString (); // @PathVariable 값 저장
66- } else if (annotation instanceof RequestBody ) {
67- requestBody = args [i ].toString (); // @RequestBody 값 저장
68- }
69- }
70- }
71-
72- // responseStatus
73- int responseStatus = 200 ;
74- Object result ;
7542 try {
76- // 실제 메서드 실행
77- result = joinPoint . proceed () ;
43+ Object result = joinPoint . proceed ();
44+ int responseStatus = 200 ;
7845 if (result instanceof ResponseEntity ) {
7946 ResponseEntity <?> responseEntity = (ResponseEntity <?>) result ;
80- responseStatus = responseEntity .getStatusCodeValue (); // 상태 코드 추출
47+ responseStatus = responseEntity .getStatusCode (). value ();
8148 }
8249
83- // 정상 요청 로그 저장
8450 long timeTaken = System .currentTimeMillis () - beforeRequest ;
85-
86- ApiLog apiLog = buildApiLog (requestInfoDto , responseStatus , timeTaken );
87- apiLogService .saveLog (apiLog );
88-
89- log .info ("[Request Log] requestUrl: {}, requestMethod: {}, userId: {}, clientIp: {}, pathVariable: {}, requestBody: {}, responseStatus: {}, timeTaken: {}" ,
90- requestInfoDto .getRequestUrl (), requestInfoDto .getRequestMethod (), requestInfoDto .getUserId (), requestInfoDto .getClientIp (),
91- pathVariable != null ? pathVariable : NO_PARAMS ,
92- requestBody != null ? requestBody : NO_BODY ,
93- responseStatus , timeTaken );
51+ saveApiLog (requestInfoDto , responseStatus , timeTaken );
52+ log .info ("[Request Log] requestId: {}, route: {}, method: {}, actor: {}, clientIp: {}, responseStatus: {}, timeTakenMs: {}" ,
53+ requestId , requestInfoDto .getRequestUrl (), requestInfoDto .getRequestMethod (), requestInfoDto .getUserId (),
54+ requestInfoDto .getClientIp (), responseStatus , timeTaken );
9455
9556 return result ;
96-
97- } catch (Exception ex ) {
57+ } catch (Throwable ex ) {
58+ int responseStatus = mapExceptionToStatusCode (ex );
59+ long timeTaken = System .currentTimeMillis () - beforeRequest ;
60+ saveApiLog (requestInfoDto , responseStatus , timeTaken );
61+ log .error ("[Error Log] requestId: {}, route: {}, method: {}, actor: {}, clientIp: {}, exception: {}, responseStatus: {}, timeTakenMs: {}" ,
62+ requestId , requestInfoDto .getRequestUrl (), requestInfoDto .getRequestMethod (), requestInfoDto .getUserId (),
63+ requestInfoDto .getClientIp (), ex .getClass ().getSimpleName (), responseStatus , timeTaken );
9864 throw ex ;
9965 }
10066 }
10167
102- @ AfterThrowing (pointcut = "allRequest()" , throwing = "ex" )
103- public void logException (JoinPoint joinPoint , Exception ex ) {
104- RequestInfoDto requestInfoDto = extractRequestInfo ();
105-
106- // exceptionName
107- String exceptionName ;
108- if (ex instanceof GeneralException ) {
109- exceptionName = ((GeneralException ) ex ).getErrorCode ().name ();
110- } else {
111- exceptionName = ex .getClass ().getSimpleName ();
112- };
113- // exceptionMessage
114- String exceptionMessage = ex .getMessage ();
115- // responseStatus
116- int responseStatus = mapExceptionToStatusCode (ex );
117-
118- log .error ("[Error Log] requestUrl: {}, requestMethod: {}, userId: {}, clientIp: {}, exception: {}, message: {}, responseStatus: {}" ,
119- requestInfoDto .getRequestUrl (), requestInfoDto .getRequestMethod (), requestInfoDto .getUserId (), requestInfoDto .getClientIp (), exceptionName , exceptionMessage , responseStatus );
120-
121- ApiLog errorLog = buildApiLog (requestInfoDto , responseStatus , 0 );
122- apiLogService .saveLog (errorLog );
123- }
124-
12568 // requestinfo 추출
126- private RequestInfoDto extractRequestInfo () {
127- HttpServletRequest request = ((ServletRequestAttributes ) RequestContextHolder .currentRequestAttributes ()).getRequest ();
128-
69+ private RequestInfoDto extractRequestInfo (HttpServletRequest request ) {
12970 String requestUrl = request .getRequestURI ();
13071 String requestMethod = request .getMethod ();
13172 Authentication authentication = SecurityContextHolder .getContext ().getAuthentication ();
@@ -137,6 +78,11 @@ private RequestInfoDto extractRequestInfo() {
13778 return new RequestInfoDto (requestUrl , requestMethod , userId , clientIp );
13879 }
13980
81+ private void saveApiLog (RequestInfoDto requestInfoDto , int responseStatus , long timeTaken ) {
82+ ApiLog apiLog = buildApiLog (requestInfoDto , responseStatus , timeTaken );
83+ apiLogService .saveLog (apiLog );
84+ }
85+
14086 // apilog 생성
14187 private ApiLog buildApiLog (RequestInfoDto info , int responseStatus , long timeTaken ) {
14288 return ApiLog .builder ()
@@ -149,7 +95,7 @@ private ApiLog buildApiLog(RequestInfoDto info, int responseStatus, long timeTak
14995 .build ();
15096 }
15197
152- private int mapExceptionToStatusCode (Exception e ) {
98+ private int mapExceptionToStatusCode (Throwable e ) {
15399 if (e instanceof GeneralException ge ) {
154100 return ge .getErrorCode ().getCode ();
155101 }
0 commit comments