Java Spring Boot에서 로깅을 위한 가장 인기있는 라이브러리는 Logback
, Log4j2
, 그리고 Java Util Logging (JUL)입니다.
이 중에서는 Logback
이 가장 많이 사용되며, Spring Boot에서도 기본적으로 Logback을 지원합니다.
순서
log4j (보안 취약점 발견) > Logback > Log4j2 ( 2.15 버전 이후 업데이트해야 취약점 방지가능)
스프링의 Logging Framework에서 가장 유명한 라이브러리가 바로 slf4j(Simple Logging Facade For Java)
입니다.
slf4j는 다양한 자바 로깅 시스템을 사용할 수 있도록 해주는 파사드 패턴의 인터페이스
라고 생각하시면 될 것 같습니다.
즉, 위 그림과 같이 slf4j를 사용하면 logback
, log4j
, log4j2
와 같은 구현체를 어플리케이션에 영향 없이 손쉽게 교체
할 수 있습니다.
그래서 @Sl4j 어노테이션
으로 logback
이니 log4j2
같은 라이브러리로 구현이 가능해집니다.
spring-boot-starter-web
에는 기본적으로 logback
로깅 모듈이 포함되어 있지만, 성능 상 log4j2
가 logback 보다 우수하기 때문에 이를 제외하고 log4j2
를 추가해주는 작업을 해줄 것입니다.
implementation 'org.springframework.boot:spring-boot-starter-log4j2'
// log4j2 의존성을 추가해주고, spring-boot-starter-logging을 제외시켜주어야 한다.
configurations {
compileOnly {
extendsFrom annotationProcessor
}
all {
//logback과의 충돌 방지
exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'
}
}
실제 jar는 이런데 log4j... 이건 건너뛰시고
resources/log4j2.xml을 만들어줍니다.
<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
<!-- 해당 설정파일에서 사용하는 프로퍼티-->
<Properties>
<property name="LOGS_PATH">C:\test_logs</property>
</Properties>
<Appenders>
<!-- 콘솔 -->
<Console name="console" target="SYSTEM_OUT">
<PatternLayout pattern="[%d{yyyy-MM-dd HH:mm:ss}:%-3relative] %-5level %logger{35} - %msg%n" />
</Console>
<!-- 파일 -->
<RollingFile name ="RollingFile">
<FileName>${LOGS_PATH}/log4j2.log</FileName>
<FilePattern>${LOGS_PATH}/log4j2.%d{yyyy-MM-dd}.%i.log.gz</FilePattern>
<PatternLayout>
<Pattern>%d{yyyy-MM-dd HH:mm:ss} %5p [%c] %m%n</Pattern>
</PatternLayout>
<Policies>
<SizeBasedTriggeringPolicy size="100MB"/>
<TimeBasedTriggeringPolicy interval = "1" modulate = "true"/>
</Policies>
</RollingFile>
</Appenders>
<Loggers>
<!-- Application Loggers -->
<!-- Root 보다 우선 순위가 높습니다. -->
<logger name="com.test.api.controller" level="INFO" additivity="false">
<AppenderRef ref="console" />
<AppenderRef ref="RollingFile" />
</logger>
<logger name="com.test.api.service" level="INFO" additivity="false">
<AppenderRef ref="console" />
<AppenderRef ref="RollingFile" />
</logger>
<!-- FATAL, ERROR, WARN, INFO, DEBUG, TRACE -->
<Root level="INFO">
<AppenderRef ref="console" />
<AppenderRef ref="RollingFile" />
</Root>
</Loggers>
</Configuration>
실제 로그가 이렇게 남긴다.
@Log4j2 // -> @Sl4j로 해도 상관x
@RestController
public class TestController {
@GetMapping(value = "/log")
public void log() throws Exception {
//FATAL, ERROR, WARN, INFO, DEBUG, TRACE
log.fatal("FATAL");
log.error("ERROR");
log.warn("WARN");
log.info("INFO");
log.debug("DEBUG");
log.trace("TRACE");
}
}
최근에 log4j2 취약점이 등장했습니다. 2.15 버전 미만인 경우 아래의 링크로 접속해 버전 업데이트 해야 합니다.
https://veneas.tistory.com/entry/Spring-Boot-스프링-부트-Log4J2-취약점-조치-Log4J2-버전-업데이트
기존것은 주석처리하고 log4j 의존성들을 2.15버전으로 업데이트해줍니다.
// implementation 'org.springframework.boot:spring-boot-starter-log4j2'
// 추가
implementation group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.15.0'
implementation group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.15.0'
implementation group: 'org.apache.logging.log4j', name: 'log4j-jul', version: '2.15.0'
implementation group: 'org.apache.logging.log4j', name: 'log4j-slf4j-impl', version: '2.15.0'
implementation group: 'org.slf4j', name: 'slf4j-api', version: '1.7.32'
implementation group: 'org.slf4j', name: 'jul-to-slf4j', version: '1.7.32'