로그는 기록 자체보다 관리가 더 중요하다. 무제한으로 쌓이는 로그는 디스크 고갈과 장애 대응 속도 저하를 야기하므로, 이를 해결하기 위한 자동화 시스템을 설계·구현하는 것을 목표로 한다.
- SLF4J : Logging Facade (Interface)
- Log4j2 : Logging Implementation
로그의 성격에 따라 물리적 저장 위치와 책임을 분리하여 관리 효율성을 높인다.
| 구분 | 역할 | 분리 기준 |
|---|---|---|
| APP | 일반 비즈니스 로직 로그 | Log Level |
| ERROR | 장애 추적용 예외 로그 | Log Level |
| AUDIT | 보안·감사 증적 로그 | Logger Name |
- Root Logger에서 수신된 모든 로그 중 Appender + Filter 조합을 통해 로그 레벨 기준으로 분리 저장
<Root level="debug">
<AppenderRef ref="Console" />
<AppenderRef ref="APP_FILE" />
<AppenderRef ref="ERROR_FILE" />
</Root>
<!-- ERROR file filter -->
<Filters>
<ThresholdFilter level="WARN" onMatch="ACCEPT" onMismatch="DENY" />
</Filters>
<!-- APP file filter -->
<Filters>
<ThresholdFilter level="WARN" onMatch="DENY" onMismatch="NEUTRAL" />
</Filters>- 전용 audit logger 활용하여 log level이 아닌 로거의 이름으로 분리
<Logger name="audit" level="info" additivity="false">
<AppenderRef ref="AUDIT_FILE"/>
</Logger>- 압축 프로세스가 1초 이내에 완료되는지 실시간 측정.
- (현재 로그 파일 크기 < 이전 측정 파일 크기)인 순간(롤링 포착 시간)을 찾아 (압축 파일 생성 시간 - 롤링 포착 시간) 차이 값이 1000ms(1초) 이내면 PASS로 판단.
if (currentSize > 0 && lastSize > 0 && currentSize < lastSize) { long rotationTime = System.currentTimeMillis(); }
- Hot (Active): 현재 기록 중인
.log파일. - Warm (Archived): 최근 발생한
.gz압축 파일. - Cold (Deleted): 생성 후 2초(시연 설정) 경과 시 별도의
deleted/폴더로 자동 이관.
log-rotating/
├── src/main/java/log_rotating/
│ ├── LogRotateTest.java (검증 및 이관 로직)
│ └── RollingTarget.java (로그 타겟 객체)
└── logs/
├── app/
│ ├── app.log (Active)
│ ├── archived/ (Warm)
│ └── deleted/ (Cold: 2초 경과 로그 이관 폴더)
├── audit/ ...
└── error/ ...디스크 풀(Full) 장애 방지 및 스토리지 가용성 확보
AUDIT 로그를 별도 관리하여 보안 사고 시 무결성 있는 증적 확보
운영 서버 자원을 효율적으로 사용하면서도 과거 데이터 보존 가능
detectRolling과 같은 순수 Java 로직은 파일 크기 변화, 시간 조건 등을 직접 제어할 수 있으므로 단위 테스트로 100% 커버리지를 확보하였다.
반면, 나머지 Log4j2 XML 설정에 의해 동작하는 영역은 분기 커버리지를 측정하는 것이 구조적으로 불가능하므로 위와 같은 결과가 나왔다.

