어드민 프로젝트
어드민 프로젝트 사용자 행동 로그파일 저장(AOP) - 2
꾸준2
2025. 6. 6. 22:36
logback-spring.xml
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="30 seconds">
<!-- 로그 파일 저장 경로 지정 -->
<property name="LOG_PATH" value="C:\log" />
<!-- 로그 패턴 정의 -->
<property name="LOG_PATTERN"
value="%d{yyyy-MM-dd HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n" />
<!-- 콘솔 출력 -->
<appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>${LOG_PATTERN}</pattern>
</encoder>
</appender>
<!-- USER_ACTION 로그 파일 -->
<appender name="USER_ACTION_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
<file>${LOG_PATH}/user-action.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<fileNamePattern>${LOG_PATH}/user-action.%d{yyyy-MM-dd}.log</fileNamePattern>
<maxHistory>30</maxHistory>
</rollingPolicy>
<encoder>
<pattern>${LOG_PATTERN}</pattern>
</encoder>
</appender>
<!-- USER_ACTION 전용 로거 -->
<logger name="USER_ACTION" level="INFO" additivity="false">
<appender-ref ref="USER_ACTION_FILE" />
</logger>
<!-- 로그 레벨: 루트 로거는 INFO 이상만 기록 -->
<root level="INFO">
<appender-ref ref="CONSOLE" />
<appender-ref ref="INFO_FILE" />
<appender-ref ref="ERROR_FILE" />
</root>
</configuration>
AOP
@Aspect
@Component
public class UserLoggingAspect {
private static final Logger logger = LoggerFactory.getLogger("USER_ACTION");
@Pointcut("execution(* com.example.admin_project..controller..*(..))")
public void userLoggerPointCut() {}
@Around("userLoggerPointCut()")
public Object methodUserLogger(ProceedingJoinPoint joinPoint) throws Throwable {
HttpServletRequest request = ((ServletRequestAttributes) RequestContextHolder.getRequestAttributes()).getRequest();
String ip = request.getRemoteAddr();
String uri = request.getRequestURI();
String httpMethod = request.getMethod();
LocalDateTime currentTime = LocalDateTime.now();
logger.info("URI={}, IP={}, httpMethod={}, currentTime={}", uri, ip, httpMethod, currentTime);
// 실제 메서드 실행
return joinPoint.proceed();
}
}
Logger 직접 생성 VS @Slf4j
1. 로그 분리 목적에 최적화된 명시적 로거 이름 부여
- LoggerFactory.getLogger("USER_ACTION") 는 "USER_ACTION"이라는 명확한 로거 이름을 직접 지정하는 방식
- 이를 통해 logback 설정에서 "USER_ACTION" 이름에 대한 별도 로그 파일과 로그 레벨 정책을 독립적으로 관리할 수 있음
- 반면 @Slf4j는 기본적으로 클래스 이름 기반 로거를 생성하기 때문에
특정 이름으로 로그 분리 및 별도 관리가 어렵거나 복잡해질 수밖에 없어서 Logger 직접 생성 선택
2. logback 설정에서 손쉬운 로그 경로 및 형식 관리
- logback.xml에서 "USER_ACTION" 로거에 대해 다음처럼 설정
<logger name="USER_ACTION" level="INFO" additivity="false">
<appender-ref ref="USER_ACTION_FILE" />
</logger>
- 이를 통해 사용자 행동 로그를 전용 파일(user-action.log) 에 저장하며
일반 정보 로그(info.log)와 분리하여 가독성과 관리 편의성을 극대화