Log4j 2 제대로 사용하기 - 개념

디디·2020년 7월 21일
5

Spring

목록 보기
2/2
post-thumbnail
<?xml version="1.0" encoding="UTF-8"?>
<Configuration status="INFO">
 <!--    해당 설정파일에서 사용하는 프로퍼티-->
    <Properties>
        <Property name="logNm">Spring Log4j2 Test</Property>
        <Property name="layoutPattern">%style{%d{yyyy/MM/dd HH:mm:ss,SSS}}{cyan} %highlight{[%-5p]}{FATAL=bg_red, ERROR=red,
            INFO=green, DEBUG=blue}  [%C] %style{[%t]}{yellow}- %m%n -</Property>
    </Properties>
  <!--    LogEvent를 전달해주는 Appender-->
    <Appenders>
        <Console name="Console_Appender" target="SYSTEM_OUT">
            <PatternLayout pattern="${layoutPattern}"/>
        </Console>
        <RollingFile name="File_Appender" fileName="logs/${logNm}.log" filePattern="logs/${logNm}_%d{yyyy-MM-dd}_%i.log.gz">
            <PatternLayout pattern="${layoutPattern}"/>
            <Policies>
                <SizeBasedTriggeringPolicy size="200KB"/>
                <TimeBasedTriggeringPolicy interval="1"/>
            </Policies>
            <DefaultRolloverStrategy max="10" fileIndex="min"/>
        </RollingFile>
    </Appenders>
  <!--    실제 Logger-->
    <Loggers>
        <Root level="INFO" additivity="false">
            <AppenderRef ref="Console_Appender"/>
            <AppenderRef ref="File_Appender"/>
        </Root>
        <Logger name="org.springframework" level="DEBUG"
                additivity="false">
            <AppenderRef ref="Console_Appender" />
            <AppenderRef ref="File_Appender"/>
        </Logger>
        <Logger name="com.fucct" level="INFO" additivity="false">
            <AppenderRef ref="Console_Appender" />
            <AppenderRef ref="File_Appender"/>
        </Logger>
        <Logger name="com.fucct.springlog4j2.loggertest" level="TRACE" additivity="false">
            <AppenderRef ref="Console_Appender" />
        </Logger>
    </Loggers>
</Configuration>

log4j2.xml

이전 글에서 log4j 2 설정파일을 보여드렸는데요, 각각의 요소가 뭘 의미하는지 알아보도록 할게요

Configuration

<Configuration status="INFO">

Configuration은 로그 설정의 최상위 요소입니다. 일반적으로 Configuration은 Properties, Appenders, Loggers요소를 자식으로 가집니다.
status 속성은 log4j의 내부 이벤트에 대한 로그 레벨을 의미합니다. 또한 Configuration의 추가 속성은 링크에서 확인하실 수 있습니다.!

Properties

<Properties>
    <Property name="logNm">Spring Log4j2 Test</Property>
    <Property name="layoutPattern">%style{%d{yyyy/MM/dd HH:mm:ss,SSS}}{cyan} %highlight{[%-5p]}{FATAL=bg_red, ERROR=red,
            INFO=green, DEBUG=blue}  [%C] %style{[%t]}{yellow}- %m%n -</Property>
</Properties>

Properties는 해당 Configuration 파일에서 사용할 프로퍼티를 의미합니다. 변수라고 생각하시면 편해요😊. 저는 logNm으로 로그 이름을 설정했고, layoutPattern으로 로그의 패턴을 설정해 놓았습니다. name 속성의 값이 key, 태그 내의 값이 value가 됩니다.

Layout

Appender는 로그 이벤트를 Layout을 통해 포매팅합니다. Appender가 받은 로그 이벤트를 Layout에게 전달하면, byte 배열을 반환합니다. Charset을 지정해주면 확실한 값을 얻을 수 있습니다.

PatternLayout

%style{%d{yyyy/MM/dd HH:mm:ss,SSS}}{cyan} %highlight{[%-5p]}{FATAL=bg_red, ERROR=red,
            INFO=green, DEBUG=blue}  [%C] %style{[%t]}{yellow}- %m%n -


설정파일에 주어진 패턴대로 로그를 출력한 결과입니다. 날짜 포맷, 색깔, 출력 요소 등을 결정할 수 있죠. C언어의 printf 문 처럼 PatternLayout은 Format문자를 사용합니다. 각 의미는 다음과 같습니다.

  • %c, %logger : 해당 로그를 쓰는 로거의 이름.
  • %C, %class : 해당 로그를 요청한 클래스 이름
  • %d, %date : 해당 로그가 발생한 시간
  • %enc, %encode : 특정 언어에서의 출력을 위한 문자 인코딩
  • %ex, %exception, %throwable : 예외 로그. 길이를 설정할 수 있음.
  • %F, %file : 해당 로그가 발생한 클래스 파일명
  • %l, %location : 해당 로그가 발생한 클래스명.메소드명(파일:라인)
  • %L, %line : 해당 로그가 발생한 라인 번호
  • %m, %msg, %message : 로그문에 전달된 메시지
  • %n : 줄바꿈
  • %p, %level : 로그 레벨
  • %r, %relative : 로그 처리시간
  • %t, %thread : 해당 로그가 발생한 스레드명
  • %style{pattern}{ANSI style} : ANSI를 사용해 특정 패턴을 스타일링함
  • %highlight{pattern}{style} : 로그 레벨명을 ANSI 색깔로 하이라이트

정말 많지만..😭 한 번쯤 공부해봐야 깔끔한 로그를 작성하실 수 있을거에요. 필요한게 생길때마다 링크에 들려서 익숙해지시면 될 거에요!
그 밖에 HTML Layout과 JSON Layout 등 여러 레이아웃이 있지만 우선 PatternLayout만 알고 넘어가도 됩니다! 궁금하시다면 위 링크에서 찾아보실 수 있을거에요!

Appenders

Appender는 log 메세지를 특정 위치에 전달해주는 역할을 하는 녀석입니다. Appender는 layout을 통해 로그를 formatting 하고, 어떤 방식으로 로그를 제공할지 결정합니다.
Appender에는 여러 종류가 있습니다.

  • ConsoleAppender
  • RollingFileAppender
  • AsyncAppender
  • FileAppender
  • JDBCAppender
  • SMTP
  • ...

저는 여기서 ConsoleAppender와 RollingFileAppender에 대해 설명드리겠습니다.

ConsoleAppender

<Console name="Console_Appender" target="SYSTEM_OUT">
    <PatternLayout pattern="${layoutPattern}"/>
</Console>

Console Appender는 말 그대로 Console에 system.out 으로 로그를 출력하는 Appender입니다. 로그 출력 포매팅은 PatternLayout 방식으로 위에서 제가 설정한 Pattern 대로 로그를 출력합니다.
ConsoleAppender가 갖는 속성은 다음과 같습니다.

  • layout : 출력 레이아웃 양식
  • name : Appender 이름
  • target : 출력 방식. 기본값은 SYSTEM_OUT, SYSTEM_ERR로 출력가능

RollingFileAppender

<RollingFile name="File_Appender" fileName="logs/${logNm}.log" filePattern="logs/${logNm}_%d{yyyy-MM-dd}_%i.log.gz">
    <PatternLayout pattern="${layoutPattern}"/>
    <Policies>
         <SizeBasedTriggeringPolicy size="200KB"/>
         <TimeBasedTriggeringPolicy interval="1"/>
    </Policies>
    <DefaultRolloverStrategy max="10" fileIndex="min"/>
</RollingFile>

로그가 한 파일에 계속 저장된다면, 파일이 너무 커져서 실행이 불가능해질 수도 있고, 파일에 문제가 생기면 로그 전부를 날려버릴 수도 있습니다. RollingFileAppender는 이런 문제를 해결해 줍니다. 파일에 로그를 기록하고, 특정 기준에 따라 압축하여 저장하는 방식의 Appender입니다. Console Appender와 대표적으로 다른 부분은 File과 관련된 속성, Policy와 관련된 속성, Strategy와 관련된 속성 입니다.

1. Policy

policy는 File Rolling Up 기준입니다. 하나의 RollingFileAppender에는 여러 Policy를 적용할 수 있습니다.

  • OnStartupTriggeringPolicy : jvm start시 trigger
  • TimeBasedTriggeringPolicy : time에 따른 trigger
  • SizeBasedTriggeringPolicy : file size에 따른 trigger
  • CronTriggeringPolicy : Cron Expression(시간에 관한 표현)에 따른 trigger

이름처럼 각각의 policy들은 특정 조건에 따라 trigger됩니다. 주어진 예제는 로그파일이 200KB가 되는 시점과 하루 마다 logs/${logNm}%d{yyyy-MM-dd}%i.log.gz 패턴으로 압축되어 저장됩니다.
여기서 재밌는 점은 TimeBasedTriggeringPolicy의 interval은 파일 패턴의 날짜 단위의 최소값으로 계산된다는 점입니다. 만약 파일패턴의 날짜 포맷이 초단위까지 있다면, interval을 1로하면 1초에 한번씩 압축이 되는 셈입니다.

2. DefaultRolloverStrategy

DefaultRolloverStrategy는 datetime 패턴과 파일패턴의 int값을 받아서 결정됩니다. datetime은 현재 시간으로 대체되고, 파일 패턴 숫자는 db의 autoincrement처럼 rollover 마다 1씩 증가합니다. 예제의 filePattern을 보시면 %d{yyyy-MM-dd} 가 날짜 패턴, %i가 파일패턴의 int입니다. 각각 rollover 이후에는 다음과 같이 저장됩니다.

해당 Strategy에는 다음 속성을 부여할 수 있습니다.

  • fileIndex : max로 설정 시 높은 index가 더 최신 파일이 됩니다. min으로 설정 시 작은 index가 최신 파일이 됩니다. 기존의 파일들을 rename하는 방식으로 동작합니다.

  • min : counter 최소값. 기본값은 1입니다.

  • max : counter 최대값. 만약 최대값에 도달하면 오래된 파일을 삭제합니다. 기본값은 7입니다.

  • compressionLevel : 0~9까지 정수값. 0은 압축하지 않고, 1은 최고 속도, 9는 최고 압축입니다. ZIP파일만 가능합니다.

  • tempCompressedFilePattern : 압축하는 동안의 파일 이름 패턴.

    사실 다른 전략도 있으니, 궁금하시다면 한 번 찾아보세요!

Logger

<Logger name="com.fucct.springlog4j2.loggertest" level="TRACE" additivity="false">
    <AppenderRef ref="Console_Appender" />
</Logger>

로거는 로깅을 직접 하는 요소입니다. 로거는 패키지 별로 설정할 수 있습니다.
Root패키지의 로거는 필수적이고, 추가적인 로거는 Logger로 설정할 수 있습니다. 해당 로거는 loggertest 패키지에 해당하는 파일들에 대해서 TRACE이상의 로그를 Console에 남기는 로거입니다. 만약 RollingFileAppender를 추가하고 싶다면 다음과 같이 설정해주면 됩니다.

<Logger name="com.fucct.springlog4j2.loggertest" level="TRACE" additivity="false">
    <AppenderRef ref="Console_Appender" />
    <AppenderRef ref="File_Appneder" />
</Logger>

Additivity값은 중복된 로그를 남길 지에 대한 속성입니다.
로거 계층 구조를 아신다면 logger가 어떻게 할당하는 지 알 수 있습니다. 링크를 참고해주시면 로거에 대한 좀 더 깊은 이해를 하실 수 있습니다.

마치며

전달할 내용은 많은데, 재미가 없는 부분이 많아서 어떻게 전달할 지 고민이 되는 글이었네요. 어느 정도 내용까지 전달할 지 고민하다가, 우선 전 글의 예제에 대한 설명이 가능할 정도의 내용을 전달해 드렸습니다. 부족하다 싶은 부분은 공식 문서를 통해 보충하신다면, 로깅에 대해 완벽히 학습하실 수 있을 것 같아요! 글에 오류가 있다면 지속적으로 수정하겠습니다. 긴 글 읽어주셔서 감사합니다.

profile
식빵 고양이 디디

2개의 댓글

comment-user-thumbnail
2020년 10월 27일

잘 정리된 글 잘 보고 갑니다.^^

답글 달기
comment-user-thumbnail
2020년 11월 5일

잘보고 갑니다~

답글 달기