Spring AOP를 활용한 자동 로그 시스템 만들기
Spring AOP와 Aspect(Around Advice)를 활용하여 자동 로그 시스템을 구축해봅니다.
아래의 순서로 구축을 해보자
- 특정 API의 요청이 들어왔을 때 API의 종류를 로그를 출력한다.
- 특정 API의 요청에 따른 서버의 Response 값을 추가로 출력한다.
- 만약 처리과정에서 Exception이 일어난다면, 그 Exception의 정보를 로그로 출력한다.
특정 API의 요청이 들어왔을 때 API의 종류를 출력하기
먼저 @AutoLogging이라는 어노테이션을 추가한다.
@AutoLogging
@GetMapping("/getItem")
public Response getItem(@RequestParam String name) {
Item item = itemService.getItem(name);
return new ResponseData<Item>(HttpStatus.OK, "물품 정보 반환 성공", item);
}
그 후, AutoLogging 어노테이션을 정의한다
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface AutoLogging {
}
그리고 PointCut을 AutoLogging 어노테이션으로 설정하는 메서드를 만든다
@Component
@Aspect
@Slf4j
public class LoggingAspect {
@Pointcut("@annotation(jejeongmin.MakeAnything.common.annotation.AutoLogging)")
public void logging() {}
}
그 후 실제로 동작하게 될 Around Advice를 만든다
@Around("logging()")
public Response methodLogging(ProceedingJoinPoint joinPoint) {
Object response = joinPoint.proceed();
Map<String, Object> params = new HashMap<>();
params.put("Controller", joinPoint.getSignature().getDeclaringType().getSimpleName());
params.put("Method", "/"+joinPoint.getSignature().getName());
params.put("Time", new Date());
return response;
}
이까지 했으면 자동으로 API 요청이 올 시 시간과, 메서드, 컨트롤러가 출력이 된다.
특정 API의 요청에 따른 서버의 Response 값을 추가로 출력하기
joinPoint.proceed()는 Aspect를 사용하는 메서드의 실행결과를 반환하는데, 이를 이용해서 메서드의 response 값을 사용할 수 있다.
//methodLogging 메서드에 일부 코드를 추가하자
ResponseData<Object> response = (ResponseData<Object>) joinPoint.proceed();
params.put("Status", response.getStatus());
params.put("Message", response.getMessage());
params.put("Data", response);
이제 자동으로 API 요청이 올 시, 추가로 서버의 Response 정보를 확인할 수 있다
만약 처리과정에서 Exception이 일어난다면, 그 Exception의 정보를 로그로 출력하기
PointCut을 Exception을 핸들링하는 모든 클래스로 지정해준다.
@Pointcut("execution(* jejeongmin.MakeAnything.common.handler.*.*(..))")
public void loggingOnlyException() {}
마지막으로 그에 맞는 Around Advice를 만든다
@Around("loggingOnlyException()")
public Response methodLoggingOnlyException(ProceedingJoinPoint joinPoint) throws Throwable {
ResponseError responseError = (ResponseError) joinPoint.proceed();
Map<String, Object> params = new HashMap<>();
params.put("Status", Integer.toString(responseError.getStatus()));
params.put("Message", responseError.getMessage());
params.put("Exception", responseError.getError());
log.info("@AutoLogging {}", params);
return responseError;
}
이까지 모두 했다면 API의 요청에 Exception이 발생하더라도, 그에 따른 서버의 반환값을 로그로 출력해볼 수 있다.
Leave a comment