게임 옥션 서버 프로젝트를 개발하며 어떠한 API에서 서버 장애, 개발자의 오타 혹은 잘못된 파라미터 사용 등 다양한 상황에서의 Exception이 발생하였으며 이에 대한 기록을 남기기위해 로깅을 하는 방법에 대해 알아보게 되었습니다.
로깅 라이브러리는 Log4j, Logback, Log4j2등의 다양한 로깅 라이브러리들이 있었으며 각각의 특징들 중 가장 퍼포먼스 성능이 높다고 확인된 Log4j2를 사용하게 되었습니다.
이번 포스팅에서는 Log4j2를 사용한 로깅에 대해서 알아보겠습니다.
Log4j, Logback, Log4j2
- Log4j
- 스프링 프레임워크 초기에 등장한 로깅 라이브러리이며 XML 기반의 설정 파일을 통해 로깅을 구성할 수 있다.
- 현재는 개발이 중단되었으며, 특정 메시지를 입력하여 컴퓨터 권한을 탈취당할 수 있는 취약점이 발견되어 사용을 권장하지 않는다.
- Logback
- SLF4J(Simple Logging Facade for Java)와 통합되어 사용할 수 있다.
- Logger 객체를 사용하여 동적으로 로깅 이벤트를 관리하며 런타임시에도 실시간으로 변경할 수 있다.
- XML외에도 Groovy를 사용하여 작성할 수 있다.
- Log4j2
- 비동기 로깅을 지원하여 멀티스레드 환경에서 로깅작업이 기존의 Log4j,Logback보다 처리량이 높다.
- 다양한 Appender, Layouts, Filter를 통해 로깅 형식 및 출력을 유연하게 구성할 수 있다.
- 자바의 람다식을 활용할 수 있는 메서드도 정의되어 있다.
해당 그래프는 초당 몇개의 파일을 쓰는지에 대한 성능 비교 그래프입니다.
쓰레드의 개수가 1~2의 경우는 비동기성을 사용하기에 부적합하여 성능에 대한 차이가 크게 나지않습니다.
하지만 멀티스레드의 개수가 늘어날수록 Log4j2의 성능이 Log4j와 Logback보다 퍼포먼스가 높게 출력되었습니다.
이로인해 Log4j2 를 사용한 로깅을 사용하였습니다.
Log4j2 적용하기
[사용 환경]
Spring Boot : 3.1.3
BuildTool : Gradle
build.gradle
configurations {
configureEach {
exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'
}
}
dependencies {
implementation 'org.springframework.boot:spring-boot-starter-log4j2'
}
- configurations
- Spring에서는 기본적으로 Logback을 사용하며, 다른 라이브러리 Log4j2를 추가하면 로깅 라이브러리끼리 충돌할 가능성이 있기때문에 Logback을 사용하지 않게 설정합니다.
- dependencies
- Log4j2 의존성을 주입합니다.
log4j2.xml
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="info">
<Properties>
<Property name="logPath">./logs</Property>
<Property name="logPattern">[%-5level] %d{yyyy-MM-dd HH:mm:ss} [%t] %c{1} - %msg%n</Property>
<Property name="serviceName">game-auction-server</Property>
</Properties>
<Appenders>
<Console name="console">
<PatternLayout pattern="${logPattern}"/>
</Console>
<RollingFile
name="file"
append="true"
fileName="${logPath}/${serviceName}.log"
filePattern="${logPath}/${serviceName}.%d{yyyy-MM-dd}.%i.log.zip">
<PatternLayout pattern="${logPattern}"/>
<Policies>
<SizeBasedTriggeringPolicy size="5MB"/>
<TimeBasedTriggeringPolicy/>
</Policies>
<DefaultRolloverStrategy>
<Delete basePath="${logPath}" maxDepth="5">
<IfFileName glob="${serviceName}.*.log"/>
<IfLastModified age="15d"/>
</Delete>
</DefaultRolloverStrategy>
</RollingFile>
</Appenders>
<Loggers>
<Logger name="consolelog" level="info" additivity="false">
<AppenderRef ref="console"/>
<AppenderRef ref="file"/>
</Logger>
</Loggers>
</Configuration>
- Property
- xml 파일 내부의 변수로 사용하기위해 정의하는 부분
- Appender
- 로그 이벤트를 콘솔과 파일에 출력하는데 사용한다.
- <Console> : 콘솔에 로그를 출력하는 appender를 정의한다.
- <PatternLayout> : 콘솔에 출력되는 로그의 패턴을 정의한다.
- RollingFile
- 파일에 로그를 기록하는 appender를 정의한다.
- appender="true" : 기존의 파일에 덮어씌우기를 할것인지 정의한다.
- fileName : 로그 파일의 경로와 이름을 정의한다.
- Policies
- RollingFile의 행동을 결정한다.
- <SizeBasedTriggeringPolicy size ="5MB"/> : 파일 크기가 5MB 이상일 시 새로운 파일로 롤 오버 한다.
- DefaultRolloverStrategy
- RollingFile이 발생 시 사용할 기본 롤 오버의 전략을 정의한다.
- <Delete basePath= > : 일정 조건에 따라 로그 파일을 삭제한다.
- Logger
- 로그 레벨과 로깅 이벤트를 특정 appender에 연결한다.
- level : 해당 로거의 로그 레벨을 정의한다
- TRACE < DEBUG < INFO < WARN < ERROR
- level=INFO 설정시, 하위의 DEBUG,TRACE는 기록하지 않는다.
- TRACE : 어플리케이션의 내부 동작을 상세하게 추적하고 문제해결에 도움이 되는 정보를 제공한다.
- DEBUG : 어플리케이션의 상태와 흐름에 관한 세부 정보를 기록하며, 문제 해결에 도움을 준다.
- INFO : 일반적인 정보를 나타내며 주요 이벤트 또는 실행 상태에 대한 정보를 기록한다.
- WARN : 어플리케이션의 경고나 예상치 못한 상황에 대한 로그를 나타낸다.
- ERROR : 프로덕션 환경에서 발생한 심각한 오류나 예외 상황에 대한 로그를 나타낸다.
예시)
if (bidItem == null || !(bidItem.getBidStatus().equals(BidStatus.SALE))) {
log.info(ErrorCode.ITEM_FORBIDDEN.getMessage());
throw new CustomException(ErrorCode.ITEM_FORBIDDEN);
입찰 API과정에서 예외처리에 대한 결과를 로깅한다.
결과)
로그파일에 설정한 포맷형태의 HH:mm:ss, level, method:line, message가 출력된다.
느낀점
Log4j, Logger, Log4j2의 각각의 특징을 알 수 있었으며,그 중 Log4j2를 왜 사용해야하는지에 대해 알 수 있었습니다.
또한 Log4j2를 사용하여 Exception 발생시 해당 내용을 로그파일로 기록하여 에러 발생시 해결 시간을 단축할 수 있었으며 이는 곧 유지보수성이 향상되었다고 볼 수 있습니다.
또한 AWS CloudWatch를 사용하여 모니터링 연동을 하였는데, 'ca.pjer:logback-awslogs-appender:1.6.0' 라이브러리를 사용하여 Log4j2 라이브러리와 충돌이 있었습니다. 이로 인해 라이브러리 간의 충돌시 발생하는 문제점 및 해결법을 알 수 있었으며, 이에 관한 내용은 AWS CloudWatch를 사용한 모니터링 포스트글에서 작성하겠습니다.
출처
https://medium.com/@201924576/spring-boot-log4j2-%EC%84%A4%EC%A0%95-21f3b6da38c6
https://logback.qos.ch/performance.html
'게임 옥션 서버' 카테고리의 다른 글
모니터링을 위한 AWS CloudWatch와 Logback.xml연동 (0) | 2024.01.31 |
---|---|
Spring JUnit을 사용한 단위테스트 (0) | 2024.01.23 |
Locust를 사용한 API 성능테스트 (0) | 2024.01.23 |
젠킨스(Jenkins)연동을 위한 정의 및 특징 (0) | 2024.01.23 |
SpringBoot에서 MyBatis 연동하기 (0) | 2024.01.15 |