(spring) logback, log4j2 로깅 적용 과정과 xml 파일 차이점 정리
logback, log4j2 로깅 적용 과정과 xml 파일 차이점 정리
해당 포스팅은 스프링 프로젝트에서 로깅 시 사용되는 라이브러리인 'logback(+ logback.xml)'과 'log4j2(+ log4j2.xml)'을 적용하는 각각의 방법과 차이점을 정리한 내용입니다.
logback, log4j2 차이점(+ slf4j)
먼저 자바 기반 애플리케이션에서 사용되는 로깅 관련 프레임워크는 'log4j', 'logback', 'log4j2'가 있는데요.
logback과 log4j2는 둘 다 log4j를 기반으로 하고 있으며, log4j는 2015년 지원이 중단되었기 때문에 logback과 log4j2가 많이 사용되고 있습니다.
(각각의 차이점에 대한 내용은 포스팅 맨 하단 관련 자료를 링크해 두었으니 필요하신 경우 참고하시면 될 것 같습니다.)
logback과 log4j2는 log4j에 비해 향상된 성능과 필터링 옵션, 자동 리로드 기능을 지원한다는 공통점이 있으며, logback이 나온 이후 log4j2가 나왔습니다.
'log4j2'의 경우 이미지에서 볼 수 있는 것처럼 상대적으로 비동기 로깅에서의 성능적 강점을 가지고, 다중 스레드 환경에서 높은 성능을 제공합니다.
(공식 문서에 따르면 동기 처리 속도 또한 logback 및 log4j에 비해 빠르다고 합니다.)
'slf4j(Simple Logging Facade For Java)'는 로깅 프레임워크 구현체에 대한 추상 레이어(= 인터페이스) 역할을 합니다.
slf4j를 사용하면 코드 수정 없이 로깅 프레임워크 구현체를 바꿀 수 있는데요.
자세한 내용은 이어지는 라이브러리 적용 과정에서 실제 코드를 통해 살펴보도록 하겠습니다.
logback(+ logback.xml) 적용하는 방법
<dependency>
<groupId>ch.qos.logback</groupId>
<artifactId>logback-classic</artifactId>
<version>1.4.14</version>
</dependency>
(ch.qos.logback dependency)
pom.xml 파일에 'logback-classic' 의존성을 추가하고 저장해 주면 Maven Dependencies에서 아래 이미지와 같이 logback-classic, slf4j-api, logback-core 라이브러리가 추가된 것을 확인할 수 있습니다.
(logback-classic 의존성은 내부적으로 logback-core와 slf4j-api 라이브러리를 포함하고 있으며, 해당 내용은 mvnrepository에서 확인할 수 있습니다.)
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
<!-- property 값 설정 -->
<property name="LOG_PATH" value="/Users/jianchoi/Desktop/logtest" />
<property name="LOG_FILE_NAME" value="logback" />
<property name="LOG_PATTERN" value="[%d{yyyy-MM-dd HH:mm:ss}:%-3relative][%thread] %-5level %logger{35} - %msg%n" />
<!-- Console Appender -->
<appender name="ConsoleAppender" class="ch.qos.logback.core.ConsoleAppender">
<!-- 출력 패턴 설정 -->
<encoder>
<pattern>${LOG_PATTERN}</pattern>
<charset>UTF-8</charset>
</encoder>
</appender>
<!-- File Appender -->
<appender name="FileAppender" class="ch.qos.logback.core.rolling.RollingFileAppender">
<!-- 파일경로 설정 -->
<file>${LOG_PATH}/${LOG_FILE_NAME}.log</file>
<!-- 출력 패턴 설정 -->
<encoder>
<pattern>${LOG_PATTERN}</pattern>
<charset>UTF-8</charset>
</encoder>
<!-- Rolling 정책 -->
<rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
<!-- .gz .zip 등을 넣으면 자동 일자별 로그 파일 압축 -->
<fileNamePattern>${LOG_PATH}/${LOG_FILE_NAME}.%d{yyyy-MM-dd}_%i.gz</fileNamePattern>
<timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
<!-- 파일당 최고 용량 kb, mb, gb -->
<maxFileSize>10MB</maxFileSize>
</timeBasedFileNamingAndTriggeringPolicy>
<!-- 일자별 로그 파일 최대 보관주기(~일), 해당 설정일 이상된 파일은 자동으로 제거 -->
<maxHistory>7</maxHistory>
</rollingPolicy>
</appender>
<root level="INFO">
<appender-ref ref="ConsoleAppender"/>
<appender-ref ref="FileAppender" />
</root>
</configuration>
(logback.xml)
'/src/main/resources/' 경로에 위 내용과 같은 logback 설정 파일 'logback.xml'을 생성합니다.
설정 파일의 각 요소에 대해서는 주석의 내용을 통해 대략적으로 예측하실 수 있으며 'log4j2' 적용 이후 각 요소에 대한 간단한 설명 및 비교 부분이 있습니다.
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
@RestController
public class LogTestController {
private static final Logger logger = LoggerFactory.getLogger("LogTestController.class");
@RequestMapping(value="test")
public String test() {
logger.info("info log!");
logger.warn("warn log!");
logger.error("error log!");
return "test";
}
}
// [2024-02-26 22:57:44:5467][http-nio-8080-exec-1] INFO LogTestController.class - info log!
// [2024-02-26 22:57:44:5474][http-nio-8080-exec-1] WARN LogTestController.class - warn log!
// [2024-02-26 22:57:44:5474][http-nio-8080-exec-1] ERROR LogTestController.class - error log!
// logback.xml 파일에 적용한 설정대로 로깅이 동작되는 것을 확인
(LogTestController)
다음으로 로깅이 정상적으로 동작하는지 확인하기 위해 다음과 같은 컨트롤러를 생성하고 api 요청을 보내봅니다.
이때 위 코드에서 주목해야 하는 부분은 바로 'org.slf4j' 패키지의 'Logger'와 'LoggerFactory'를 사용했다는 것입니다.
포스팅 상단에서 이야기했던 것처럼 slf4j는 로깅 프레임워크 구현체에 대한 인터페이스 역할을 하기 때문에 해당 라이브러리를 사용하면 코드 수정 없이 로깅 프레임워크 구현체를 바꿀 수 있는데요.
Controller의 코드를 그대로 유지한 채 로깅 구현체를 'log4j2'로 바꿔보겠습니다.
log4j2(+ log4j2.xml) 적용하는 방법
<dependency>
<groupId>org.apache.logging.log4j</groupId>
<artifactId>log4j-slf4j-impl</artifactId>
<version>2.18.0</version>
</dependency>
(org.apache.logging.log4j)
pom.xml 파일에 'log4j-slf4j-impl' 의존성을 추가해 주면 아래 이미지와 같이 Maven Dependencies에 log4j-slf4j-impl, slf4j-api, log4j-api, log4j-core 라이브러리가 추가되는 것을 확인할 수 있습니다.
(작업 전 pom.xml 파일에 기존에 적용했던 logback 의존성이 있다면 먼저 제거해 줍니다.)
(log4j2는 log4j의 2.x 버전을 의미하며, log4j-slf4j-impl 의존성 역시 내부적으로 slf4j-api, log4j-api, log4j-core 라이브러리를 포함하고 있습니다.)
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
<!-- property 값 설정 -->
<Properties>
<Property name="LOG_PATH" value="/Users/jianchoi/Desktop/logtest" />
<Property name="LOG_FILE_NAME" value="log4j2" />
<Property name="LOG_PATTERN" value="[%d{yyyy-MM-dd HH:mm:ss}:%-3relative][%thread] %-5level %logger{35} - %msg%n" />
</Properties>
<Appenders>
<!-- Console Appender -->
<Console name="ConsoleAppender" target="SYSTEM_OUT">
<PatternLayout pattern="${LOG_PATTERN}"/>
</Console>
<!-- File Appender -->
<RollingFile name="FileAppender" fileName="/Users/jianchoi/Desktop/logtest/${LOG_FILE_NAME}.log" filePattern="/Users/jianchoi/Desktop/logtest/${LOG_FILE_NAME}_%d{yyyy-MM-dd}_%i.log.gz">
<PatternLayout pattern="${LOG_PATTERN}"/>
<Policies>
<SizeBasedTriggeringPolicy size="10MB"/>
<TimeBasedTriggeringPolicy interval="1"/>
</Policies>
<DefaultRolloverStrategy max="7" fileIndex="min"/>
</RollingFile>
</Appenders>
<Loggers>
<Root level="INFO" additivity="false">
<AppenderRef ref="ConsoleAppender"/>
<AppenderRef ref="FileAppender"/>
</Root>
</Loggers>
</Configuration>
(log4j2.xml)
'/src/main/resources/' 경로에 log4j2 설정 파일인 'log4j2.xml'을 생성합니다.
설정 정보는 이전의 'logback.xml'과 거의 비슷하게 하였으며, 각 요소에 대한 차이점은 이어서 바로 살펴보겠습니다.
log4j2.xml 파일 생성 후 logback에서 테스트했던 LogTestController를 그대로 사용하여 로깅이 정상적으로 되는지 확인해 볼 수 있는데요.
로깅 구현체를 logback에서 log4j2로 바꿨지만 로깅 구현체를 추상화하는 'slf4j'를 사용하기 때문에 코드를 수정하지 않아도 된다는 것을 확인할 수 있습니다.
위에서 사용된 xml 파일 요소에 대한 차이점과 간략한 내용
logback.xml | log4j2.xml | 설명 |
<configuration> | <Configuration> | xml 파일 설정 시작 |
<property> | <Properties><Property> | 파일 내부에서 사용할 속성 설정 |
<root> | <Loggers><Root> | 루트 로거 설정 |
<appender> | <Appenders><Console> or <Appenders><RollingFile> |
로그 메시지가 출력될 대상 및 세부 내용 설정 |
<encoder><pattern> | <PatternLayout> | 로그 출력 패턴 설정 |
(위 xml 설정 파일에서 사용된 요소들에 대한 차이 및 간단한 설명)
보시는 것처럼 'logback.xml'과 'log4j2.xml'의 설정에는 비슷하지만 구문 및 요소에 대한 차이점이 명확하게 존재하는데요.
때문에 로깅 구현체를 교체할 때는 xml 파일명 외에도 각 구현체에 맞는 설정이 필요합니다.
< 로깅 구현체 비교 내용 >
2021.08.25 - [Programming/Spring Boot] - Spring Boot Logging 이란? (log4j, logback, log4j2)
< 참고 자료 >