@Around 어노테이션을 활용한 요청/응답 시점 로그 처리joinPoint.getArgs()를 활용한 RequestBody 추출과 로깅 방법 확인@AdminLogging 어노테이션@Retention(RetentionPolicy.RUNTIME), @Target(ElementType.METHOD)으로 설정AdminLogginAspect 클래스 구조@Aspect, @Component로 정의@Around("@annotation(...AdminLogging)")을 통해 AOP 진입HttpServletRequest에서 사용자 정보(userId)와 요청 URI 추출joinPoint.getArgs()를 통해 요청 파라미터(JSON 직렬화) 추출joinPoint.proceed() 이후 응답 또는 예외를 처리@Around("@annotation(org.example.expert.logging.AdminLogging)")
public Object logAdminAccess(ProceedingJoinPoint joinPoint) throws Throwable {
Long userId = (Long) request.getAttribute("userId");
String uri = request.getRequestURI();
LocalDateTime time = LocalDateTime.now();
String requestBody = objectMapper.writeValueAsString(joinPoint.getArgs());
log.info("어드민 요청 - userId: {}, URI: {}, time: {}, request: {}", userId, uri, time, requestBody);
Object result = null;
try {
result = joinPoint.proceed();
return result;
} catch (Throwable e) {
log.warn("어드민 응답 실패 - userId: {}, URI: {}, error: {}", userId, uri, e.getMessage());
throw e;
} finally {
if (result != null) {
String responseJson = objectMapper.writeValueAsString(result);
log.info("어드민 응답 - userId: {}, URI: {}, response: {}", userId, uri, responseJson);
} else {
log.info("어드민 응답 - userId: {}, URI: {}, response: 예외 발생 또는 반환값 없음");
}
}
}
개선된 점
@Around는 메서드 실행 전후를 포괄적으로 제어할 수 있는 강력한 도구joinPoint.getArgs()는 RequestBody와 PathVariable 모두 확인 가능