서비스 모듈 | Log Aspect

Faithful Dev·2025년 3월 12일

Log Aspect는 AOP(Aspect-Oriented Programming, 관점 지향 프로그래밍)를 활용하여 로그(logging) 기능을 모듈화한 것을 의미한다. 일반적으로 Spring AOP 또는 AspectJ를 사용하여 특정 메서드가 실행될 때 자동으로 로그를 기록하도록 설정할 수 있다.


개념

애플리케이션에서 로깅은 중요한 기능이지만, 여러 클래스와 메서드에 로깅을 직접 구현하면 코드 중복이 발생하고 가독성이 떨어진다. 이를 해결하기 위해 Log Aspect를 사용하여 로깅을 횡단 관심사(cross-cutting concern)로 분리할 수 있다.


주요 기능

  1. 메서드 실행 전후 로그 기록
    • 메서드 실행 전 입력 파라미터 로깅
    • 메서드 실행 후 반환값 로깅
    • 실행 시간 측정
  2. 예외 발생 시 로그 기록
    • 예외 메시지와 스택 트레이스를 자동으로 기록
  3. 특정 패키지 또는 어노테이션을 가진 메서드만 로깅
    • 특정 클래스나 패키지에만 적용 가능
    • @Controller, @Service 등 특정 어노테이션이 붙은 메서드만 로깅 가능

Spring AOP를 활용한 에제

Gradle 의존성 추가

Spring AOP와 AspectJ를 사용하려면 build.gradle에 다음 의존성을 추가한다:

dependencies {
    implementation 'org.springframework.boot:spring-boot-starter-aop'
}

Log Aspect 클래스 구현

import org.aspectj.lang.ProceedingJoinPoint;
import org.aspectj.lang.annotation.Around;
import org.aspectj.lang.annotation.Aspect;
import org.aspectj.lang.annotation.Pointcut;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.stereotype.Component;

@Aspect
@Component
public class LogAspect {
    private static final Logger logger = LoggerFactory.getLogger(LogAspect.class);

    // 대상이 될 메서드 설정 (컨트롤러 패키지 하위 모든 메서드)
    @Pointcut("execution(* com.example.controller..*(..))")
    public void controllerMethods() {}

    // 메서드 실행 전후로 로그 기록
    @Around("controllerMethods()")
    public Object logExecutionTime(ProceedingJoinPoint joinPoint) throws Throwable {
        long startTime = System.currentTimeMillis();

        logger.info("Method Start: {} with args: {}", joinPoint.getSignature(), joinPoint.getArgs());

        Object result;
        try {
            result = joinPoint.proceed(); // 실제 메서드 실행
        } catch (Exception e) {
            logger.error("Exception in {}: {}", joinPoint.getSignature(), e.getMessage());
            throw e;
        }

        long endTime = System.currentTimeMillis();
        logger.info("Method End: {} - Execution time: {} ms", joinPoint.getSignature(), (endTime - startTime));

        return result;
    }
}

적용 방식

  1. @Aspect: 해당 클래스가 AOP Aspect임을 나타냄.
  2. @Pointcut: 특정 메서드 또는 패키지에 대해 로깅을 적용할 위치를 지정.
  3. @Around: 지정한 포인트컷을 감싸서 메서드 실행 전후 로직을 수행.
  4. ProceedingJoinPoint: 실제 대상 메서드를 실행하고 결과를 반환하는 역할.

로그 출력 예시

INFO  [main] LogAspect - Method Start: com.example.controller.UserController.getUser() with args: [1]
INFO  [main] LogAspect - Method End: com.example.controller.UserController.getUser() - Execution time: 5 ms

장점

  • 중복 코드 제거: 여러 클래스에서 개별적으로 로깅 코드를 작성할 필요 없음.
  • 유지보수성 향상: 로깅 정책을 한 곳에서 관리 가능.
  • 가독성 증가: 핵심 비즈니스 로직과 로깅을 분리하여 코드가 깔끔해짐.
  • 일관된 로깅: 모든 메서드에 대해 동일한 형식의 로그를 남길 수 있음.

정리

Log Aspect는 AOP를 활용하여 애플리케이션의 로깅을 중앙 집중화하고 코드의 유지보수성을 향상시키는 강력한 방법이다. 특히 Spring Boot 환경에서 손쉽게 적용할 수 있으며, 실행 시간 측정, 예외 로깅, 입력/출력값 추적 등을 간편하게 수행할 수 있다.

profile
Turning Vision into Reality.

0개의 댓글