본문 바로가기

Spring

[Spring] Spring Boot 로그 - slf4j 와 Logback, Log4j2 의 차이점

반응형

 

Spring Boot의  로그

2021-11-11 11:10:58.789  INFO 40789 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet engine: [Apache Tomcat/9.0.48]
2021-11-11 11:10:59.074  INFO 40789 --- [           main] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2021-11-11 11:10:59.075  INFO 40789 --- [           main] w.s.c.ServletWebServerApplicationContext : Root WebApplicationContext: initialization completed in 4081 ms

 


 

출력 항목

  • 2021-11-11 11:10:58.789 - 날짜, 시간
  • INFO - 로그 레벨: ERROR > WARN > INFO > DEBUG > TRACE
    • 설정을 통해 표시할 출력 레벨을 지정 가능
  • 40789 - 프로세스 Id
  • --- 실제 로그 메세지의 시작을 구분하는 구분 기호
  • [    main] - 스레드 이름 
  • org.apache.catalina.core.StandardEngine - 로거 이름: 로그를 남긴 클래스 이름(길이가 길면 축약됨)
  • Starting Servlet engine: [Apache Tomcat/9.0.48] - 이후 남긴 로그 메세지

* Logback 에는 FATAL 레벨이 없고 ERROR에 포함됨

 


 

로그 레벨

로그 출력은 기본적으로 ERROR, WARN, INFO 레벨만 출력된다.

DEBUG 레벨의 출력을 확인하기 위해서는 디버그모드를 활성화 해야한다. 

$ java -jar appname.jar --debug

* 또는 application.properties 에 bebug = true 지정

DEBUG레벨과 같이 TRACE 레벨도 같은 방식으로 옵션을 주면 된다. ( trace = true / --trace )

 

- 기본적인 설정은 application.yml/properties 파일을 통해 설정이 가능하다 (로그 파일 출력, 출력 레벌 설정 등)

하지만 SpringBoot의 설정만으로는 제약사항(일자별 분류, 자동 삭제 등)이 있으므로  더 디테일한 설정을 하기 위해 logback 설정 파일을 직접 작성해해주는걸 추천한다.

 


 

slf4j란

facade 패턴을 적용한 로깅 추상화 라이브러리이다. 이러한 slf4j의 특징을 통해 원하는 로깅 라이브러리를 코드 수정없이 쉽고 간단하게 선택, 교체할 수 있게 된다. 

https://kanoos-stu.tistory.com/76

 

[구조패턴] 퍼사드(fasade) 패턴과 slf4j

퍼사드(fasade) 패턴이란 - 여러 라이브러리, 프레임워크 또는 클래드들의 복합한 집합을 단순화시켜주는 인터페이스를 제공하는 구조의 디자인 패턴 대표적인 예로는 스프링 부트의 slf4j 가 있다

kanoos-stu.tistory.com

 

스프링에서 slf4j 를 활용하여 로그를 남길 수 있는 대표적인 라이브러리로 logback, log4j2 가 있다.

 

slf4j 사용 시 주의점

사용시에는 logback, log4j2 등 로깅라이브러리들 중 하나만 사용해야하며 두개 이상의 라이브러리를 사용할 경우 스프링에서는 다음과 같은 에러 로그를 발생시킨다.

 


 

Logback

spring-boot-starter-web 종속성이나 spring-boot-starter-loggin 종속석을 추가하면 Logback 및 slf4j 의 라이브러리가 추가된다.

* spring-boot-starter-web 라이브러리에 spring-boot-starter-logging 라이브러리가 포함되어있음

implementation("org.springframework.boot:spring-boot-starter-web")
or
implementation("org.springframework.boot:spring-boot-starter-logging")

 

resources 폴더 밑에 logback-spring.xml, logback.xml (logback용) 의 Spring Boot에서 정의해놓은 이름의 파일에 설정할 수 있다. (SpringBoot 공식문서에는 logback.xml 대신 logback-spring.xml 을 권장함)

추가로 파일 경로나 파일명 등은 properties파일(이름은 자유)로 분류해주는게 수정에 용의하다.

 

 

 

반응형

 

 

logback의 로그 출력을 위한 파일 설정

- logback-burger.properties

logPath=/log/dir

maxFileSize=10MB

 

- logback.xml

<?xml version="1.0" encoding="UTF-8"?>
<configuration sacn="true" scanPeriod="60 seconds">
    <!-- 60초마다 설정 파일의 변경을 스캔 -->
    <springProfile name="burger">
        <property resource="logback-burger.properties"/>
    </springProfile>
    <!--logback-burger.properties 의 설정 파일을 profile 별로 다르게 설정 가능-->

    <springProfile name="release">
        <property resource="logback-release.properties"/>
    </springProfile>
        
    <property name="CONSOLE_LOG_PATTERN"
              value="%d{MM-dd HH:mm:ss.SSS} %highlight(%-5level) %magenta(%-4relative) --- [ %thread{10}] [%logger{36}]: %msg%n"/>
    <!--로그 패턴 정의-->
    <property name="FILE_NAME" value="burger-logs"/>
    <!--상수 값 정의-->

    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <!--CONSOLE 이라는 이름의 로그 형태 정의, class - 콘솔에 로그를 찍음-->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <!--출력할 로그 인코더 설정 (PatternLayoutEncoder 는 default 설정이라 생략가능) -->
            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
            <!--위의 property 로 정의한 콘솔 로그 패턴으로 출력-->
        </encoder>
    </appender>

    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <!--FILE 이라는 이름의 로그 형태 정의, class - 특정 시간 또는 크기를 기준으로 로그 파일을 생성 -->
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>error</level>
            <onMatch>ACCEPT</onMatch>
            <onMismatch>DENY</onMismatch>
        </filter>
        <!--error 레벨만 필터링 다른 레벨은 무시-->
        <file>${logPath}/${FILE_NAME}-json.log</file>
        <!--생성할 로그 파일 경로 + 이름-->
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${CONSOLE_LOG_PATTERN}</pattern>
        </encoder>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <!--파일 생성 정책 - 시간 기준 -->
            <fileNamePattern>${logPath}/${FILE_NAME}_%d{yyyy-MM-dd}.%i.log</fileNamePattern>
            <maxHistory>90</maxHistory>
            <!--파일 최대 보관 기간 (90일) -->
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <!-- 크기별 로그 파일 생성 -->
                <maxFileSize>${maxFileSize}</maxFileSize>
                <!-- logback-burger.properties 에 정의한 최대 maxFileSize(10Mb) 만큼 마다 로그파일을 생성-->
            </timeBasedFileNamingAndTriggeringPolicy>
        </rollingPolicy>
    </appender>

    <!-- 프로필별 로그 출력 설정 -->
    
    <springProfile name="burger">
        <root level="ERROR">
            <appender-ref ref="CONSOLE"/>
        </root>
        <!--전체 로그의 ERROR 레벨을 Appender "CONSOLE" 의 설정대로 출력-->
        <logger name="com.패키지명" level="ERROR" additivity="false">
            <appender-ref ref="CONSOLE"/>
            <appender-ref ref="FILE"/>
        </logger>
        <!--root 로그에 오버라이딩 하지 않고(additivity=false) ERROR 레벨의 name 패키지를 CONSOLE, FILE appender 설정대로 적용 -->
    </springProfile>

    <springProfile name="release">
        <root level="INFO">
            <appender-ref ref="FILE"/>
            <appender-ref ref="CONSOLE"/>
        </root>
        <logger name="com.패키지명" level="INFO">
            <appender-ref ref="CONSOLE"/>
        </logger>
    </springProfile>
</configuration>

* profile 별 properties 파일을 설정해 주려면 꼭 xml파일의 최상단에 명시해줘야 아래 코드들에 반영됨! 

 


 

logback의 출력된 콘솔 로그 및 로그 파일

logback 을 통해 출력된 에러 로그
출력된 로그 파일
출력된 로그파일의 내용

 


 

Log4j2

 

spring-boot-starter-log4j2 종속성을 추가하고 spring-boot-starter-web 에 포함되어있는 logging 라이브러리(logback) 을 log4j2 로 교체해주는 코드를 입력해준다.

* slf4j 는 하나의 로깅 라이브러리만 활성화 되어야 사용할 수 있음

implementation("org.springframework.boot:spring-boot-starter-web")
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")
    }
}

 

위와같이 종속성을 추가하면 log4j2 라이브러리가 추가되고 logback 라이브러리는 제거된다.

 

resources 폴더 밑에 log4j2.xml 의 Spring Boot에서 정의해놓은 이름의 파일에 설정할 수 있다.

 

log4j2.xml

<?xml version="1.0" encoding="UTF-8"?>
<Configuration>
    <Appenders>
        <File name="File" fileName="/Users/[유저이름]/Desktop/logs/log4j2.log">
            <PatternLayout pattern="%d{yyyy-MM-dd HH:mm:ss} %-5p %c{1}:%L - %m%n"/>
        </File>
        
        <Console name="Console">
            <PatternLayout disableAnsi="false" pattern="%d${LOG_DATEFORMAT_PATTERN} %highlight${LOG_LEVEL_PATTERN}"/>
        </Console>
    </Appenders>
    <Loggers>
        <Root>
            <AppenderRef ref="File" level="error"/>
            <AppenderRef ref="Console" level="error"/>
        </Root>
    </Loggers>
</Configuration>

 

위의 간단한 코드를 통해 에러로그를 fileName 에 입력된 경로와 파일이름으로 출력이 된다.

 


 

log4j2의 출력된 콘솔 로그 및 로그 파일

log4j2 를 통해 출력된 로그

 

출력된 로그 파일

 

출력된 로그파일의 내용

 

 


 

 

Logback 과 Log4j2 의 차이점

 

logback 과 log4j2 는 모두 java 애플리케이션용 로깅 라이브러리이다.

 

 

둘의 차이점은 logback 은 순수 java 로 작성되는 반면 log4j2 java 로 작성되고 다른 언어로 작성된 플러그인도 지원된다.

이 차이로 인해 log4j2 가 다른 언어 및 기술과 유연하게 통합할 수 있다.

 

 

반면 logback 이 log4j2에 비해 간단하고 직관적은 구문을 가지고 있어 작성하기 쉽고, 비동기 로깅을 지원해 처리량이 많은 프로그램에서 성능을 향상될 수도 있다. 또 필터링 및 형식 지정 옵션등을 제공한다.

 

 

 

 

 

반응형