본문 바로가기
Develop/Spring+JPA

[Spring Boot] 기본 Logging Framework는 진짜 'Logback'일까?

by 연로그 2022. 10. 13.
반응형

😮 내 프로젝트에 Log4j 가 있다?

 현재 Spring Boot 2.7.1 버전을 사용하고 있다. 로깅 프레임워크에 대한 글을 작성하다가 라이브러리 의존성을 찾아보게 되었다. 그런데 예상 외의 의존성이 발견되었다. (아래 사진 참고) Spring Boot의 디폴트 로깅 프레임워크는 Logback이라고 알고 있는데 저 log4j는 뭘까?

 

gradle 의존성을 확인한 모습
https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-logging/2.7.1

 

 

혹시나 버전 업이 되면서 추가된걸까? 라는 의문에 다른 버전도 살펴봤다. 하지만 1.0.0 때부터 이미 존재해왔다.

https://mvnrepository.com/artifact/org.springframework.boot/spring-boot-starter-logging/1.0.0.RELEASE

 

 

 

😎 Spring Boot의 디폴트 Logging Framework

여지껏 log4j2를 적용하려면 spring-boot-starter-logging를 exclude하고 spring-boot-starter-logging-log4j2를 추가해야한다고 알고 있었는데 위에 있는 log4j는 뭘까? 사용할 수 없는걸까? 다음은 Spring Boot Document의 일부를 가져왔다.

 

Spring Boot uses Commons Logging for all internal logging but leaves the underlying log implementation open. Default configurations are provided for Java Util Logging, Log4J2, and Logback. (중략) By default, if you use the “Starters”, Logback is used for logging. Appropriate Logback routing is also included to ensure that dependent libraries that use Java Util Logging, Commons Logging, Log4J, or SLF4J all work correctly.

Spring Boot Document

 

위 내용을 읽어보니 디폴트 설정으로는 Java Util Logging, Log4J2, Logback이 주어지는데 Spring Boot Starters를 이용하는 경우에는 이 중에서도 Logback을 디폴트로 사용한다. 

 

 

 

😏 Logging Framework 변경하기

 Log4j도 이미 주입되어있는데 이걸 쓸 수 있는 방법을 없을까? Spring Boot Document에 관련 내용을 찾아보았다.

 

 Spring Boot의 외부 속성이나 기타 기능 들은 SpringApplication을 사용해 생성하는 경우에만 기본적으로 컨텍스트에 설치된다. 로깅 시스템도 이에 포함되며 ApplicationContext가 생성되기 전에 초기화된다와 같은 의미이다. 따라서 로깅 시스템을 변경하고 싶다면 System properties를 이용해야만 한다. 설정 파일은 기본적으로 classpath에서 각 로깅 시스템에 맞는 이름을 찾는다. (ex: Logback의 경우에는 logback.xml 또는 logback-spring.xml) 또는 Spring의 환경 속성에서 logging.config를 지정해 직접 설정 파일을 등록할 수도 있다.

 

 공식 문서에는 spring boot starters를 이용하는 경우 Logback을 제외한 뒤에 Log4j를 포함시키라고 한다. 또는 Gradle 이용 시 모듈을 교체하는 방법도 제공한다.

dependencies {
    implementation "org.springframework.boot:spring-boot-starter-log4j2"
    modules {
        module("org.springframework.boot:spring-boot-starter-logging") {
            replacedBy("org.springframework.boot:spring-boot-starter-log4j2", "Use Log4j2 instead of Logback")
        }
    }
}

 

 

 

🤔 그럼 종속되어 있던 Log4j는 뭐지?

 이 아래는 💥개인적인 추측💥이 섞인 글입니다.

 

Spring Boot에는 classpath의 내용을 기반으로 로깅을 구성하는 LoggingSystem이라는 추상 클래스가 존재한다. SpringFactoriesLoader에서 사용하는 설정 파일을 보면 여러 LoggingSystem 중에서도 Logback이 가장 먼저 선언되어 있다.

spring.factories

 

 이번에는 Log4J2LoggingSystem 클래스를 한번 보았다. org.apache.logging.log4j.core가 제대로 인식되지 않는 현상이 발견되었다. 따라서 Log4j의 로직들이 존재하는 클래스들은 따로 추가되지 않고 호환성을 위해 일부 클래스에 대한 의존성만 추가된 상태인가? 라는 생각을 했다.  (아시는 분이 계시다면 정정 부탁드립니다🙏) 따라서 동작이 가능한 Log4j에 대한 의존성이 완전한 형태의 라이브러리를 주입받아야만 동작 가능한게 아닐까라는 생각이 든다.

 


참고

반응형