slf4j - logback 설정 정리

slf4j - logback 설정 정리

@ 스프링은 자체적으로 JCL을 사용 -> slf4j + logback으로 셋팅

  • spring-core는 내부적으로 JCL을 사용하는데, 문제는 JCL이 실제 로거를 선택하는 시점이 런타임 시점이라서 대상 클래스를 불러오거나 오버헤드가 발생할 수 있다고 한다. 그런데 slf4j는 이런 문제들을 해결해준다.

1. slf4j + logback 디펜던시를 추가한다.

  • logback-classic 안에는 logback-core와 slf4j-api가 포함되어있다.

    <dependency>
        <groupId>ch.qos.logback</groupId>
        <artifactId>logback-classic</artifactId>
        <version>1.1.11</version>
    </dependency>
    

2. slf4j로 전환하기 위해서 spring과 jcl의 의존성을 제거한다.

  • spring-core에서 jcl 디펜던시를 제거

    <dependency>
        <groupId>org.springframework</groupId>
        <artifactId>spring-webmvc</artifactId>
        <version>4.3.14.RELEASE</version>
        <exclusions>
            <exclusion>
                <groupId>commons-logging</groupId>
                <artifactId>commons-logging</artifactId>
            </exclusion>
        </exclusions>
    </dependency>
    
  • spring 내부의 jcl을 사용하는 로깅을 slf4j로 라우트 해줄 디펜던시도 추가해주어야한다.

    • jcl-over-slf4j 안에는 jcl의 LoggerFactory.java와 같은 클래스가 있는데, LoggerFactory loggerFactory = new SLF4JLogFactory();으로 구현해놓고 slf4j로 라우트 하도록 되어있다.

    • 이 디펜던시가 없으면 기존의 spring에서 사용하던 jcl 의존성을 끊었기 때문에, java.lang.NoClassDefFoundError가 발생한다.

     
    <dependency>
        <groupId>org.slf4j</groupId>
        <artifactId>jcl-over-slf4j</artifactId>
        <version>1.7.25</version>
    </dependency> 
    

3. logback.xml 설정

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <appender name="console" class="ch.qos.logback.core.ConsoleAppender"> // 콘솔로고 설정
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder"> // 로그 패턴 지정
            <pattern>
                [LOG] %-5level %d{HH:mm:ss.SSS} [%thread] %logger[%method:%line] - %msg%n
            </pattern>
        </encoder>
    </appender>

    <logger name="org" level="debug"> // name: 대상 패키지 지정, level: 로그레벨 설정
        <appender-ref ref="console"/>
    </logger>

    <root level="debug">
        <appender-ref ref="console"/>
    </root>
</configuration>

4. 주의 사항

  • 추가적으로 jcl-over-slf4j / log4j-over-slf4j 디펜던시 등을 추가할 때, 기존에 slf4j-jcl / slf4j-log4j 디펜던시 등이 있는지 확인 해봐야 한다.

  • 그 이유는 StackOverflowError가 발생할 수 있기 때문이다.

  • 예를들어 slf4j-log4j와 log4j-over-slf4j가 같이 있으면, 무한순환이 일어난다.

    • slf4j-log4j는 slf4j가 log4j의 로깅 처리를 호출하고

    • log4j-over-slf4j는 log4j 로깅을 slf4j로 라우트한다.

    • 이 과정이 무한으로 순환하게 되면서 StackOverflowError가 발생한다.


  • 또한, slf4j-log4j와 logback-classic이 함께 있는 경우, slf4j에 바인딩 될 대상이 2개 중 하나만 바인딩 되어 원하는 로깅 구현체로 바인딘 되지 않는 멀티바인딩 이슈가 일어 날 수 있다.

    • 이런 경우에는 사용하지 않는 로깅 구현체는 exclusion해야한다.

댓글