🌏고민의 시작
프로젝트를 진행하며 로그에 대한 체크를 자주하게 되었습니다.
특히 구현한 메서드에 대한 input parameter 가 제대로 들어오는지 확인하고 싶었습니다.
@Slf4j 를 이용한 추적을 진행해도 큰문제는 없다고 생각했지만, 점점 문제를 느끼게 되었습니다.
- 매번 반복되는 @Slf4j 어노테이션을 이용한 log 추적에 피로도 증가
- 체크를 위한 로그 표기의 일관성 부족(ex. log.info("매번 바뀌는 로그 추적 양식"))
이러한 문제를 느끼게 되었고, 지금까지 학습한 내용 중 이러한 문제를 해결하기 위해 AOP를 활용한 Input Parameter 추적 어노테이션을 개발하고 적용하게 되었습니다.
🌏고민 해결 방법
- 매번 반복되는 @Slf4j 어노테이션을 이용한 log 추적에 피로도 증가
- 체크를 위한 로그 표기의 일관성 부족(ex. log.info("매번 바뀌는 로그 추적 양식"))
위에 있는 2가지를 해결하기 위해 AOP 를 이용한 Input Parameter 로그 추적 어노테이션 개발을 진행하게 되었습니다.
🌏 구현
아래와 같은 방법으로 구현을 진행했습니다.
- AOP 를 구현하기 위해서는, 어느 어노테이션에 적용할 지 Around 를 설정합니다.
- 어드바이스( Advice ) 로 메서드를 구현하면 됩니다.
@Slf4j
@Aspect
public class LogParameterTraceAop {
/**
* @Around 애노테이션의 값인 annotation(com.mapwithplan.mapplan..annotation.LogInputTrace)) 는 포인트컷이 된다.
* @Around 애노테이션의 메서드인 checkInputLog 는 어드바이스( Advice )가 된다.
* 해당 메서드에 대한 Input 파라미터의 값을 출력한다.
* 다만 해당 어노테이션을 사용하기 위해서는 로그 추적을 원하는 도메인에 toString 을 구현해야한다.
* @param joinPoint
* @return
* @throws Throwable
*/ @Around("@annotation(com.mapwithplan.mapplan.common.aop.logparameteraop.annotation.LogInputTrace)")
public Object checkInputLog(ProceedingJoinPoint joinPoint) throws Throwable {
Object[] args = joinPoint.getArgs();
String className = joinPoint.getTarget().getClass().getName();
String methodName = joinPoint.getSignature().getName();
Arrays.stream(args)
.forEach(parameter ->
log.info("className = {}, methodName ={}, Parameter: {}",
className, methodName, parameter));
return joinPoint.proceed();
}
}
위의 메서드를 보면 ProceedingJoinPoint joinPoint
에서 각 파라미터의 클래스, 메서드를 출력합니다.
그리고 joinPoint.getArgs();
에서 input 된 파라미터 값을 출력 합니다.
그리고 이 기능을 적용할 어노테이션 입니다.
@Target(ElementType.METHOD)
@Retention(RetentionPolicy.RUNTIME)
public @interface LogInputTrace {
}
하지만, 이 @LogInputTrace 어노테이션에서 정확한 Input Parameter 값을 추적하기 위해서는
객체의 toString 을 구현해야 합니다.
만약에 구현을 하지 않는다면, Input Parameter의 객체 주소만 나오는 문제가 있으므로 정확한 파라미터 추적에 있어서는 toString 을 구현해야 합니다.
아래는 예시 입니다. (IDE를 통해 구현 하는 것이 가장 안전한 방법입니다.)
@Override
public String toString() {
return "TestDomain{" +
"test=" + test +
", testString='" + testString + '\'' +
", helloTestArray=" + helloTestArray +
'}';
}
이러한 과정을 거치게 되면서,
반복되는 과정을 줄일 수 있었을 뿐 아니라 형식의 통일을 하게 되었습니다.
🌏마무리
간단한 작업이었지만, 실제 개발 상황에서 느낀 불편함을 학습한 AOP 의 개념을 적용해 해결해볼 수 있던 경험을 하게 되었습니다.
'프로젝트 기록 > spring' 카테고리의 다른 글
[Spring Project] Util 메서드는 Spring bean 으로 등록해야할까? (feat. static Method) (0) | 2025.03.23 |
---|---|
[spring] @ComponentScan 의 대상 위치 (0) | 2024.01.21 |