본문 바로가기
Java

[SLF4J] slf4j 알고가기 + Logback

by bryan.oh 2021. 7. 3.
반응형

SLF4J
Simple Logging Facade For Java

 

SLF4J는 다양한 Logging Framework(java.util.logging, logback, log4j)의 추상화를 제공합니다.

SLF4J는 Compile 시 하나의 logging framework와 binding 해줍니다.

 

SLF4J의 이점

  • 가장 큰 것은 다양한 Logging Framework를 라이브러리만 추가해서 바인딩 할 수 있습니다.
  • Deployment Time 에 Log Library 와 동적으로 연결합니다. 이 말은 Log Library만 변경하면 로그 엔진을 바꿀수 있습니다.
  • 사용 시 약간의 이점도 있습니다.

아래의 코드는 string concat 연산을 하고나서, Logging Level 을 확인합니다.
만약 Level 이 Info 였다면 String 연산이 쓸데없는게 되겠죠.

logger.debug("Debug : " + msg);

 

그래서 아래와 같이 처리를 하곤했죠.

if(logger.isDebugEnabled()){
    logger.debug("Debug : " + msg);
}

로그를 찍을 때마다??

이때 slf4j 를 이용하면,

logger.debug("Debug : {}", msg);

logging level을 먼저 확인하고, 로그를 출력 해야한다면 String 연산을 수행합니다.

 

Log Library 의 선택 - Logback

제가 예전 ( 한 7년전 ?? ㅋ )에 개발할 때 java 의 로깅 하면 log4j 였죠.  그밖에 다른 언어에서도 log4xx 시리즈가 많았습니다.

“Logback“은 새롭게 개발된게 아니라, 오랫동안 검증된 “LOG4J”의 아키텍쳐 기반으로 재작성 되었습니다.
특히 성능은 약 10배 정도 빠르게 개선을 했고, 또한 메모리 점유도 보다 적게 사용을 합니다.

Logback 을 더 선호하는 이유는

  1. 더 빠른 구현 : Log4j보다 최대 10배 빠르다.
  2. Extensive battery of tests : Log4j보다 테스트가 많이되었다.
  3. logback-classic speaks SLF4J natively : SLF4J API를 바로 구현하여 오버헤드가 없음.
  4. 광범위한 문서 : Logback은 상세하고 지속적으로 업데이트되는 문서와 함께 제공됩니다.
  5. Log4j의 문제 수정 - Multi-process가 1개의 File에 로그를 남길 수 있다. / Log archive의 Backup 개수를 지정할 수 있다.
  6. StackTrace에 그 Class가 속한 Library정보도 보여준다.
  7. Log4j보다 다양한 종류의 Appender 제공
  8. Dynamic Reloading 기능을 지원

 

logback 설정 파일 찾는 과정

  1. resources 디렉토리에서 logback.groovy 
  2. resources 디렉토리에서 logback.xml 
  3. 기본설정 적용

스프링에서는 logback-spring.xml로 작성할 것을 권장한다. (특히 커스텀 할 경우)

 

 logback.xml  의 예제들

기본

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>
 
    <root level="debug">
        <appender-ref ref="STDOUT" />
    </root>
</configuration>

 

환경별

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>
 
    <root level="debug">
        <appender-ref ref="STDOUT" />
    </root>
    
    <!-- dev env -->
    <springProfile name="dev"> 
        <logger name="org.springframework.boot" level="WARN" /> 
        <logger name="org.springframework.web" level="DEBUG" /> 
    </springProfile>

    <!-- prod env --> 
    <springProfile name="prod"> 
        <logger name="org.springframework.*" level="info" /> 
    </springProfile>

</configuration>

- springProfile 은 application.properties 또는 yml 에 작성하면 됩니다.

spring.profiles.active = dev

- 위처럼 하나의 설정 파일안에 전부 작성할 수 도 있고, 아래처럼 각각 파일을 만들어서 관리할 수 있습니다.

spring.profiles.active=dev
logging.config=classpath:logback-${spring.profiles.active}.xml

- logback-dev.xml, logback-prod.xml 처럼 만들어 놔야겠죠.

 

기능별

<configuration debug="true">
    <property name="FILE_LOG_ROOT" value="." />
    <include resource="logback/logback-appender.xml"/>
 
    <logger name="org.springframework" level="INFO"/>
    <logger name="org.mybatis" level="INFO"/>
    <logger name="org.apache.http" level="INFO"/>
    <logger name="org.elasticsearch" level="INFO"/>
 
    <root level="DEBUG">
        <appender-ref ref="STDOUT"/>
    </root>
 
</configuration>

 

Rolling file

  • 콘솔에는 모든 log 출력
  • info  이상만 파일로 출력
<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="30 seconds">
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>%d{yyyy-MM-dd HH:mm:ss.SSS}[%-5level] : %msg%n</pattern>
        </encoder>
    </appender>
    <appender name="ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.ThresholdFilter">
            <level>INFO</level>
        </filter>
        <file>log.txt</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!-- rollover daily -->
            <fileNamePattern>log-%d{yyyy-MM-dd}.%i.txt</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy
                    class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <!-- or whenever the file size reaches 100MB -->
                <maxFileSize>100MB</maxFileSize>
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
        <encoder>
            <pattern>[%-5level] %d{HH:mm:ss.SSS} %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>
    <root level="debug">
        <appender-ref ref="STDOUT"/>
        <appender-ref ref="ROLLING"/>
    </root>
</configuration>

 

console 과 file 의 또 다른 예제

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
	<property name="LOG_DIR" value="/Users/user/logs"></property>
	<property name="LOG_PREFIX" value="preword"></property>

  <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>${LOG_DIR}/${LOG_PREFIX}.log</file>
    <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
      <Pattern>%d{yyyy-MM-dd HH:mm:ss}- %-5level - %msg%n</Pattern>
    </encoder>
    
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <fileNamePattern>${LOG_DIR}/archived/${LOG_PREFIX}.%d{yyyy-MM-dd}.%i.log</fileNamePattern>
      <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
        <maxFileSize>10MB</maxFileSize>
      </timeBasedFileNamingAndTriggeringPolicy>
    </rollingPolicy>
  </appender>
  
  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <!-- encoders are assigned the type
         ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
    <encoder>
      <pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
    </encoder>
  </appender>
  
  <root level="info">
    <appender-ref ref="FILE"></appender-ref>
    <appender-ref ref="STDOUT"></appender-ref>
  </root>
</configuration>

 

그 외

    <!-- logback 자체 로그를 출력하지 않음 -->
    <statusListener class="ch.qos.logback.core.status.NopStatusListener" />

 

 

- 기본 Appendar

  1. ConsoleAppender : 로그를 콘솔에 출력
  2. FileAppender : 로그를 지정 파일에 기록
  3. RollingFileAppender : FileAppender을 상속. 날짜와 용량등을 설정해서 패턴에 따라 로그가 각기 다른파일에 기록되게 할 수 있음.

 

- 로그 레벨 : TRACE > DEBUG > INFO > WARN > ERROR
  ( Fatal 이 없음
)

 

 

글이 너무 길어졌네요.

여기까지 하고, 다음엔

시리즈 포스팅인 SpringBoot project 에 Logback 적용하는걸로 정리해보겠습니다.

 

Spring Boot Tutorial 시리즈

Spring Boot Tutorial 부록

728x90
반응형

댓글