Spring/Spring

Spring Boot]로그,로깅,로그를 파일로 저장하기 (LogBack) [미완]

backend dev 2023. 1. 19.

[틀린 정보가 있을 수 있습니다.]

로그와 로깅에 대한 정보

 

8)★★★스프링 MVC - 기본기능, 로깅(logging)

초기설정 스프링부트 application 실행해서 동작 테스트 로깅(logging) 간단히 알아보기 스프링부트를 생성하면 자동으로 추가되는 스프링부트스타터 안에 스프링부트 스타터 로깅이라는 라이브러

keeeeeepgoing.tistory.com

 

 

LogBack(로그백) 정리 

[위에 링크된 게시글에서 정리한 내용은 제외]

LogBack은 SLF4J를 인터페이스로 사용한다 ( SLF4J의 편하게 구현체라고 생각하면 될듯하다)

 

Appender,Encoder,Layout

LogBack은 로그를 찍는 일에 대해 Appender라는 Components에 위임한다.

그러나 실제 로그의 formatting에 관해서는 Layout 또는 Encoder에 위임한다.

Appenders are named entities.

This ensures that they can be referenced by name, a quality confirmed to be instrumental in configuration scripts

 

 

ConsoleAppender

이름에서 나타내듯이, 콘솔에 로그를 붙이는(첨부하는)  Appender이다. (정확히는 System.out 또는 System.err이고 System.out이 기본설정)

 

LogBack 환경설정 중 appender 설정 예시

<configuration>

  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <!-- encoders are assigned the type
         ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
    <encoder>
      <pattern>%-4relative [%thread] %-5level %logger{35} - %msg %n</pattern>
    </encoder>
  </appender>

  <root level="DEBUG">
    <appender-ref ref="STDOUT" />
  </root>
</configuration>

<configuration>은 환경설정 태그

<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">

이 부분이 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>%-4relative [%thread] %-5level %logger{35} - %msg %n</pattern>
    </encoder>
</appender>

이렇게까지가 원하는 Appender를 가져와서 이름을 설정하고 

Appeder설정안에서 <encoder>를 이용하여 로그가 어떻게 찍힐지 설정한다.

즉 이 코드는 Console에 로그를 찍는 ConsoleAppender를 커스텀하고(<encoder>를 이용해서 포맷을 원하는대로 지정)

커스텀한 Appender의 이름을 지정했다.

<root level="DEBUG">
    <appender-ref ref="STDOUT" />
</root>
</configuration>

root ( 프로젝트 전체) 의 로그레벨을 DEBUG로 설정하고

프로젝트 전체에서 로그를 찍을때 참조할 appender로  커스텀한 appender를 부여했다. 

이렇게하면 프로젝트 전체에서 로거를 이용해서 콘솔로 로그를 찍을때 커스텀한 포맷대로 출력될것이다.

 <logger name="com.gaeyou.firstproject" level="DEBUG">
        <appender-ref ref="SAMPLE" />
</logger>

또는 이런식으로 로거마다 설정해줄 수 있다.

로거의 이름에 패키지를 적으면 그 패키지 포함 하위패키지의 로거를 의미하고

또는 패키지 + 클래스명을 적으면 그 클래스의 로거를 의미한다.

 

해당 로거에서 로그레벨설정과 Appender설정을 해줄 수 있다.

<logger> 태그는 0개 이상의 <appender-ref> 태그를 포함할 수 있다.

FileAppender

파일로 로그를 저장하는 Appender

 

Appender는 콘솔,파일 말고도 원격소켓서버, DB,SMTP등으로 다 로그를 보낼 수 있다.

 

 

LogBack 환경설정

 로거마다 appender 설정을 달리하던지, appender의 포맷을 바꾼다던지 

패키지마다 로그레벨을 달리한다던지 등

로그에 관련된 환경설정을 할 수 있다.

 

application.yml 이라던지 application.properties에서 간단한 설정은 할 수 있지만

상세한 설정은 xml에서 진행한다.

 

LogBack이 환경설정을 찾는 순서는 다음과 같다.

1. classpath에서 logback-test.xml을 찾는다. 

2. (1)에서 찾지 못했다면 classpath에서 logback.groovy를 찾는다.

3. (2)에서 찾지 못했다면 classpath에서 logback.xml를 찾는다.

4. (3)에서 찾지 못했다면 com.qos.logback.classic.spi.Configurator 인터페이스의 구현체를 찾습니다. 

탐색 위치는 classpath에서 META-INF\services\ch.qos.logback.classic.spi.Configurator 입니다.

5. 위 과정에서 성공한경우가 없다면 , LogBack은 콘솔에 출력하는 BasicConfigurator로 설정한다.

SpringBoot에서 기본으로 가져오는 LogBack의 포맷(기본포맷을 이용하고, 콘솔에 출력하는)

logback-spring.xml로 로깅환경설정 파일을 생성해서 설정해주면된다.
SpringBoot에서 기본으로 가져오는 LogBack의 포맷

https://logback.qos.ch/manual/filters.html#levelFilter

 

Chapter 7: Filters

Have lots of ideas and throw away the bad ones. You aren't going to have good ideas unless you have lots of ideas and some sort of principle of selection. —LINUS PAULING Chapter 7: Filters In the preceding chapters, the basic selection rule, which lies a

logback.qos.ch

<configuration>

  <appender name="FILE" class="ch.qos.logback.core.FileAppender">
    <file>myApp.log</file>

    <encoder>
      <pattern>%date %level [%thread] %logger{10} [%file:%line] %msg%n</pattern>
    </encoder>
  </appender>

  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>%msg%n</pattern>
    </encoder>
  </appender>

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

위의 코드에는 FILE과 STDOUT이라는 appender를 확인할 수 있다.

FILE appender는 myApp.log라는 파일에 로그를 출력하고 

encoder로 PatternLayoutEncoder를 사용한다.  

 <!-- encoders are assigned the type ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->

 

STDOUT appender는 콘솔에 로그를 출력합니다.

두 개의 appender는 <appender-ref>를 통해 root 로거에 등록됩니다

 

<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>

  <logger name="chapters.configuration">
    <appender-ref ref="STDOUT" />
  </logger>

  <root level="debug">
    <appender-ref ref="STDOUT" />
  </root>
</configuration>
14:25:36.343 [main] INFO  chapters.configuration.MyApp3 - Entering application.
14:25:36.343 [main] INFO  chapters.configuration.MyApp3 - Entering application.
14:25:36.359 [main] DEBUG chapters.configuration.Foo - Did it again!
14:25:36.359 [main] DEBUG chapters.configuration.Foo - Did it again!
14:25:36.359 [main] INFO  chapters.configuration.MyApp3 - Exiting application.
14:25:36.359 [main] INFO  chapters.configuration.MyApp3 - Exiting application.

logger는 자신에게 부착된 appender 이외에 자신의 상위 logger의 appender에게 로그를 전달한다.

그렇기에 같은 appender를 다른 logger에 등록한다면 로그의 중복 출력에 주의하여야 한다.

<logger name="chapters.configuration.Foo" additivity="false"> <!-- 상위 로거로 전달 방지 -->

logger에는 additivity 속성이 존재

이 속성은 appender accumlate를 컨트롤하기 위한 속성

"additivity=false"로 설정된 경우 로깅이 발생할 때 상위 로거의 appender로 전달되지 않는다.

 

변수선언

configuration 파일에 변수를 선언하고 이를 태그 구성에 사용할 수 있다.

변수는 <property> 태그를 이용하여 선언 가능

 logback 1.0.7 이후로는 <property> 대신 <variable>이라는 이름으로 키워드가 대체되었지만 

현재 둘 다 태그명으로 사용 가능

선언한 변수 ${variable_name}으로 사용할 수 있다.

<configuration>

  <property name="USER_HOME" value="/home/seoul" />

  <appender name="FILE" class="ch.qos.logback.core.FileAppender">
    <file>${USER_HOME}/myApp.log</file>
    <encoder>
      <pattern>%msg%n</pattern>
    </encoder>
  </appender>

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

<property> 태그를 이용하여 "USER_HOME"이라는 변수에 "/home/seoul"값을 넣어주었다.

<file>${USER_HOME}/myApp.log</file> 에서 ${USER_HOME}이 /home/seoul로 치환되어

/home/seoul/myApp.log 파일에 로그가 쌓일것이다.

FileAppender

ch.qos.logback.core.FileAppender: 파일에 로그 이벤트를 append한다.
매 실행마다 Unique한 이름의 새로운 로그 파일을 만드는것이 좋기에 

아래와 같이 timestamp를 이용하여 타깃 파일을 동적으로 설정할 수 있다

간단하게 날짜타입을 가지는 변수 태그라고 생각한다 ( <Property> 처럼)

timestamp 는 시간을 나타낸다.
key가 변수의 이름이 되고, datePattern을 이용해서 년-월-일 시 등 시간패턴을 나타낼수있다.

<configuration>
  <timestamp key="bySecond" datePattern="yyyyMMdd'T'HHmmss"/>

  <appender name="FILE" class="ch.qos.logback.core.FileAppender">
    <file>log-${bySecond}.txt</file>
    <encoder>
      <pattern>%logger{35} - %msg%n</pattern>
    </encoder>
  </appender>

  <root level="DEBUG">
    <appender-ref ref="FILE" />
  </root>
</configuration>

이렇게 해두면 로그가 log-시간.txt 파일에 쌓이게 된다.

 

RollingFileAppender

ch.qos.logback.core.rolling.RollingFileAppender:
FileAppender를 상속하며 로그를 파일에 쌓는건 같고, RollingPolicy에 따라 로그 파일을 rollover한다.

여기서 rollover는 로그가 쌓이는 타겟파일을 바꾸는것으로 보면된다.
예를들어, log.txt를 타겟파일로 로그 메시지를 append하다가 

어느 조건(시간, 용량)에 다다르면, 이전파일을 저장하고, 타겟 파일을 바꾼다.

 

Rolling Policies

1. TimeBasedRollingPolicy

가장 많이 알려진 RollingPolicy 종류 중 하나
시간에 기반하여 rollover 정책을 정의할 수 있으며, 주로 일 또는 월 단위로 rollover한다.

rollover 뿐만 아닌 Trigger에 대한 책임도 지기 때문에 RollingPolicy와 TriggeringPolicy 인터페이스를

 모두 implements 해요. (Trigger = 촉발시키다,작동시키다  /  rollover 즉 타겟파일을 바꾸는것과 trigger 즉 rollover를 작동시키는 것 둘다에 책임이 있다.)

 

TimeBasedRollingPolicy는 필수적으로 fileNamePattern 속성을 가진다.

<configuration>
  <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>logFile.log</file>
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
      <!-- 하루 동안의 log를 남김 -->
      <fileNamePattern>logFile.%d{yyyy-MM-dd}.log</fileNamePattern>

      <!-- 30일동안, 총 최대 3GB의 log를 저장함-->
      <maxHistory>30</maxHistory>
      <totalSizeCap>3GB</totalSizeCap>

    </rollingPolicy>

    <encoder>
      <pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
    </encoder>
  </appender> 

  <root level="DEBUG">
    <appender-ref ref="FILE" />
  </root>
</configuration>

<fileNamePattern> : 파일 쓰기가 종료된  log파일명의 패턴을 지정한다.

logFile.log에 로그가 쌓이다가 rollover가 될때 파일의 이름을 fileNamePattern에서 지정한대로 바꾼다.

fileNamePattern에 명시된 dateTime 패턴의 최소 단위에 따라 rollover 단위가 달라진다.

아래의 예시를 통해 rollover가 trigger 되는 시점을 확인할 수 있다.

 

fileNamePattern에 명시된 dateTime 패턴의 최소 단위에 따라 rollover가 trigger되는 시점이 다르다.

아래의 예시를 통해 rollover가 trigger 되는 시점을 확인할 수 있다.

<fileNamePattern>의 내용에 따른 rollover가 trigger 되는 시점


<maxHistory>
: 최대 파일 생성 갯수를 정의한다.
maxHistory가 30이고, Rolling 정책을 일 단위로 하면 30일 동안만 저장되고, 월 단위로 하면 30개월간 저장된다.

예를들어 30일동안 30개의 파일이 유지됐다면 오래된 파일부터 삭제된다.

<totalSizeCap>: 저장소의 최대 크기를 지정해요. 

maxHistory와 함께 쓰일 경우 1순위로 maxHistory에 대하여 처리된 후 totalSizeCap 이 적용돼요.

https://logback.qos.ch/manual/appenders.html#TimeBasedRollingPolicy

 

 

2. SizeAndTimeBasedRollingPolicy

TimeBasedRollingPolicy에서 각각의 로그 파일에 대한 크기를 제한을 하는 부분이 추가됐어요.
fileNamePattern에서 %i와 %d가 필수적으로 포함돼야해요

  • %i: Integer Token , rollover가 되는 기간이 지나지않고 maxFileSize를 넘었다면 %i를 이용하여 인덱스를 붙여 로그를 저장하는데 시작 인덱스는 0부터이다.

 

https://logback.qos.ch/manual/appenders.html#SizeAndTimeBasedRollingPolicy

SizeAndTimeBasedFNATP 대신 SizeAndTimeBasedRollingPolicy를 쓰자.

 

예시코드

<configuration>
  <appender name="ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>mylog.txt</file>
    <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
      <!-- rollover daily -->
      <fileNamePattern>mylog-%d{yyyy-MM-dd}.%i.txt</fileNamePattern>
       <!-- each file should be at most 100MB, keep 60 days worth of history, but at most 20GB -->
       <maxFileSize>100MB</maxFileSize>    
       <maxHistory>60</maxHistory>
       <totalSizeCap>20GB</totalSizeCap>
    </rollingPolicy>
    <encoder>
      <pattern>%msg%n</pattern>
    </encoder>
  </appender>


  <root level="DEBUG">
    <appender-ref ref="ROLLING" />
  </root>

</configuration>

<file>에서 로그를 저장할 파일 이름과 형식이 보이고

<fileNamePatters>에서 rollover를 할 기간 설정과 , 기간이 끝났을때 로그를 저장한 파일의 이름의 수정이 어떻게 되는지 확인가능하다.

<maxFileSize>는 로그 파일 하나가 가질수있는 최대크기설정

<maxHistory>는 최대 저장되는 로그파일 갯수이다. 최대갯수를 넘으면 오래된순서대로 삭제한다.

<totalSizeCap>은 저장소의 최대 크기를 지정한다. 

 

저장되는 파일 이름 예시

<appender name="APP_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>logs/app.log</file>
    <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
        <fileNamePattern>logs/app.%d{yyyy-MM-dd}.%i.gz</fileNamePattern>

하루동안 logs라는 디렉토리 아래 app.log라는 파일에 로그가 쌓이기 시작한다.

하루가 지나고 logs라는 디렉토리 아래             app.날짜.인덱스.gz 로 저장된다.

 

또 다른 예시

<configuration>
  <appender name="ROLLING" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>mylog.txt</file>
    <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
      <!-- 하루 동안의 log를 남김 -->
      <fileNamePattern>mylog-%d{yyyy-MM-dd}.%i.zip</fileNamePattern>
      <!-- 각각의 파일은 100MB로 저장되고, 30일동안, 최대 3GB의 log를 저장함-->
       <maxFileSize>100MB</maxFileSize>    
       <maxHistory>30</maxHistory>
       <totalSizeCap>3GB</totalSizeCap>
    </rollingPolicy>
    <encoder>
      <pattern>%msg%n</pattern>
    </encoder>
  </appender>

  <root level="DEBUG">
    <appender-ref ref="ROLLING" />
  </root>

</configuration>

각각 appender를 생성해서 include해서 쓰는방식

 

GitHub - Livenow14/slf4j-logback-lab: Java & SpringBoot에서 slf4j, logback을 사용한 로깅 Lab

Java & SpringBoot에서 slf4j, logback을 사용한 로깅 Lab. Contribute to Livenow14/slf4j-logback-lab development by creating an account on GitHub.

github.com

 

파일에 출력하기 예제 + spring profile 별 다르게 설정

테스트환경에서는 콘솔로 찍어보고, 실제 프로덕션환경에서는 로그를 파일로 저장해야한다면 다음과 같이 설정

 

%green,%highlight는 색을 바꾸는 기능.

<?xml version="1.0" encoding="UTF-8"?>

<configuration>
    <timestamp key="BY_DATE" datePattern="yyyy-MM-dd"/>
    <property name="LOG_PATTERN"
              value="[%d{yyyy-MM-dd HH:mm:ss}:%-4relative] %green([%thread]) %highlight(%-5level) %boldWhite([%C.%M:%yellow(%L)]) - %msg%n"/>

    <springProfile name="!prod">
        <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
            <encoder>
                <pattern>${LOG_PATTERN}</pattern>
            </encoder>
        </appender>

        <root level="INFO">
            <appender-ref ref="CONSOLE"/>
        </root>
    </springProfile>

    <springProfile name="prod">
        <appender name="FILE-INFO" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <file>./log/info/info-${BY_DATE}.log</file>
            <filter class = "ch.qos.logback.classic.filter.LevelFilter">
                <level>INFO</level>
                <onMatch>ACCEPT</onMatch>
                <onMismatch>DENY</onMismatch>
            </filter>
            <encoder>
                <pattern>${LOG_PATTERN}</pattern>
            </encoder>
            <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
                <fileNamePattern> ./backup/info/info-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
                <maxFileSize>100MB</maxFileSize>
                <maxHistory>30</maxHistory>
                <totalSizeCap>3GB</totalSizeCap>
            </rollingPolicy>
        </appender>

        <appender name="FILE-WARN" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <file>./log/warn/warn-${BY_DATE}.log</file>
            <filter class = "ch.qos.logback.classic.filter.LevelFilter">
                <level>WARN</level>
                <onMatch>ACCEPT</onMatch>
                <onMismatch>DENY</onMismatch>
            </filter>
            <encoder>
                <pattern>${LOG_PATTERN}</pattern>
            </encoder>
            <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
                <fileNamePattern> ./backup/warn/warn-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
                <maxFileSize>100MB</maxFileSize>
                <maxHistory>30</maxHistory>
                <totalSizeCap>3GB</totalSizeCap>
            </rollingPolicy>
        </appender>

        <appender name="FILE-ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
            <file>./log/error/error-${BY_DATE}.log</file>
            <filter class = "ch.qos.logback.classic.filter.LevelFilter">
                <level>ERROR</level>
                <onMatch>ACCEPT</onMatch>
                <onMismatch>DENY</onMismatch>
            </filter>
            <encoder>
                <pattern>${LOG_PATTERN}</pattern>
            </encoder>
            <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
                <fileNamePattern> ./backup/error/error-%d{yyyy-MM-dd}.%i.log</fileNamePattern>
                <maxFileSize>100MB</maxFileSize>
                <maxHistory>30</maxHistory>
                <totalSizeCap>3GB</totalSizeCap>
            </rollingPolicy>
        </appender>

        <root level="INFO">
            <appender-ref ref="FILE-INFO"/>
            <appender-ref ref="FILE-WARN"/>
            <appender-ref ref="FILE-ERROR"/>
        </root>
    </springProfile>

</configuration>

 

내 프로젝트 logback-spring.xml 버전1

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <timestamp key="BY_DATE" datePattern="yyyy-MM-dd"/> <!--시간패턴을 저장한 변수-->
  <property name="LOG_PATTERN"
    value="[%d{yyyy-MM-dd HH:mm:ss}:%-4relative] %green([%thread]) %highlight(%-5level) %cyan([%C.%magenta(%M):%yellow(%L)]) - %msg%n"/>
  <!--
  로그 패턴을 저장한 변수 , %d{}는 로그 기록시간 관련, %-4relatevie는 밀리세컨드를 최대 4칸까지 출력, %green([%thread])는 현재 쓰레드이름을 초록으로 출력,
  %highlight는 로그레벨 마다 색이 다르게 해주는것이고, %-5level은 로그레벨을 출력해주는데 왼쪽정렬이고 5칸고정 , %C는 로깅이 발생한 클래스명, %M은 로깅이 발생한 메소드명,
  %L은 로깅이 발생한 호출지의 라인이다.  %msg는 로그메시지이고 , %n은 줄바꿈을 의미한다.
  -->

  <!--콘솔출력 appender-->
  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>${LOG_PATTERN}</pattern>
    </encoder>
  </appender>
  <!--WARN레벨  로그 파일 저장 appender-->
  <appender name="FILE-WARN" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>./logs/warn-${BY_DATE}.log</file><!--최상위폴더/logs 디렉토리에 warn-날짜.log 파일에 로그가 쌓인다. -->
    <filter class="ch.qos.logback.classic.filter.LevelFilter">
      <level>WARN</level> <!--WARN 로그레벨에 대해서만 작동한다.-->
      <onMatch>ACCEPT</onMatch>
      <onMismatch>DENY</onMismatch>
    </filter>
    <encoder>
      <pattern>${LOG_PATTERN}</pattern>
    </encoder>
    <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
      <fileNamePattern>./logs/backup/warn/warn-%d{yyyy-MM-dd}.%i.gz</fileNamePattern>
      <!--%d{yyyy-MM-dd}로 rollover되는 시간을 매일 자정으로 설정했고, 로그파일이 logs/backup/warn 폴더에 gz압축파일형식으로 저장된다.-->
      <maxFileSize>10MB</maxFileSize> <!--로그파일 최대 크기는 10MB로 설정-->
      <maxHistory>30</maxHistory> <!--쌓이는 로그파일 최대 갯수는 30개로 설정-->
      <totalSizeCap>500MB</totalSizeCap> <!--로그파일이 저장되는 저장소의 최대 크기는 500MB로 설정-->
    </rollingPolicy>
  </appender>
  <!--ERROR레벨  로그 파일 저장 appender-->
  <appender name="FILE-ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>./logs/error-${BY_DATE}.log</file>
    <filter class="ch.qos.logback.classic.filter.LevelFilter">
      <level>ERROR</level>
      <onMatch>ACCEPT</onMatch>
      <onMismatch>DENY</onMismatch>
    </filter>
    <encoder>
      <pattern>${LOG_PATTERN}</pattern>
    </encoder>
    <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
      <fileNamePattern>./logs/backup/error/error-%d{yyyy-MM-dd}.%i.gz</fileNamePattern>
      <maxFileSize>10MB</maxFileSize>
      <maxHistory>30</maxHistory>
      <totalSizeCap>500MB</totalSizeCap>
    </rollingPolicy>
  </appender>

  <!--
  루트 로그레벨(프로젝트 전체 로그레벨)을 INFO로 설정해둔다. DEBUG,TRACE 로그레벨이 필요할경우 application.yml에서 따로 설정하면된다.
  루트레벨에서 WARN,ERROR 로그를 파일로 저장한다. 너무 내용이 많아질 경우 프로젝트 패키지포함 하위패키지에서의 WARN,ERROR로그만 파일로 저장하도록 수정한다.
  -->
  <root level="INFO">
    <appender-ref ref="STDOUT"/>
    <appender-ref ref="FILE-WARN"/>
    <appender-ref ref="FILE-ERROR"/>
  </root>

</configuration>

로그패턴에 색을 넣으니까 , 콘솔에 띄워질때는 이쁜데

로그에 적힐때는 색넣은 부분앞에 이상한문자가 생긴다.

그래서 파일용 로그에는 색넣는것을 빼고, 전체적으로 로그패턴을 좀 더 간소화 하였다.

 

버전2

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <timestamp key="BY_DATE" datePattern="yyyy-MM-dd"/> <!--시간패턴을 저장한 변수-->
  <property name="LOG_PATTERN"
    value="[%d{yyyy-MM-dd HH:mm:ss}] %green([%thread]) %highlight(%-5level) [File:%cyan(%F)] [Func:%magenta(%M)] [Line:%yellow(%L)] [Message : %blue(%m)] - %msg%n"/>
  <!--
  로그 패턴을 저장한 변수 , %d{}는 로그 기록시간 관련, %-4relatevie는 밀리세컨드를 최대 4칸까지 출력, %green([%thread])는 현재 쓰레드이름을 초록으로 출력,
  %highlight는 로그레벨 마다 색이 다르게 해주는것이고, %-5level은 로그레벨을 출력해주는데 왼쪽정렬이고 5칸고정 , %C는 로깅이 발생한 클래스명, %M은 로깅이 발생한 메소드명,
  %L은 로깅이 발생한 호출지의 라인이다.  %msg는 로그메시지이고 , %n은 줄바꿈을 의미한다.
  -->
  <property name="FILE_LOG_PATTERN"
    value="[%d{yyyy-MM-dd HH:mm:ss}] [%thread] %-5level [File:%F] [Func:%M] [Line:%L] [Message : %m] - %msg%n"/>

  <!--콘솔출력 appender-->
  <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
    <encoder>
      <pattern>${LOG_PATTERN}</pattern>
    </encoder>
  </appender>
  <!--WARN레벨  로그 파일 저장 appender-->
  <appender name="FILE-WARN" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>./logs/warn-${BY_DATE}.log</file><!--최상위폴더/logs 디렉토리에 warn-날짜.log 파일에 로그가 쌓인다. -->
    <filter class="ch.qos.logback.classic.filter.LevelFilter">
      <level>WARN</level> <!--WARN 로그레벨에 대해서만 작동한다.-->
      <onMatch>ACCEPT</onMatch>
      <onMismatch>DENY</onMismatch>
    </filter>
    <encoder>
      <pattern>${FILE_LOG_PATTERN}</pattern>
    </encoder>
    <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
      <fileNamePattern>./logs/backup/warn/warn-%d{yyyy-MM-dd}.%i.gz</fileNamePattern>
      <!--%d{yyyy-MM-dd}로 rollover되는 시간을 매일 자정으로 설정했고, 로그파일이 logs/backup/warn 폴더에 gz압축파일형식으로 저장된다.-->
      <maxFileSize>10MB</maxFileSize> <!--로그파일 최대 크기는 10MB로 설정-->
      <maxHistory>30</maxHistory> <!--쌓이는 로그파일 최대 갯수는 30개로 설정-->
      <totalSizeCap>500MB</totalSizeCap> <!--로그파일이 저장되는 저장소의 최대 크기는 500MB로 설정-->
    </rollingPolicy>
  </appender>
  <!--ERROR레벨  로그 파일 저장 appender-->
  <appender name="FILE-ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
    <file>./logs/error-${BY_DATE}.log</file>
    <filter class="ch.qos.logback.classic.filter.LevelFilter">
      <level>ERROR</level>
      <onMatch>ACCEPT</onMatch>
      <onMismatch>DENY</onMismatch>
    </filter>
    <encoder>
      <pattern>${FILE_LOG_PATTERN}</pattern>
    </encoder>
    <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
      <fileNamePattern>./logs/backup/error/error-%d{yyyy-MM-dd}.%i.gz</fileNamePattern>
      <maxFileSize>10MB</maxFileSize>
      <maxHistory>30</maxHistory>
      <totalSizeCap>500MB</totalSizeCap>
    </rollingPolicy>
  </appender>

  <!--
  루트 로그레벨(프로젝트 전체 로그레벨)을 INFO로 설정해둔다. DEBUG,TRACE 로그레벨이 필요할경우 application.yml에서 따로 설정하면된다.
  루트레벨에서 WARN,ERROR 로그를 파일로 저장한다. 너무 내용이 많아질 경우 프로젝트 패키지포함 하위패키지에서의 WARN,ERROR로그만 파일로 저장하도록 수정한다.
  -->
  <root level="INFO">
    <appender-ref ref="STDOUT"/>
    <appender-ref ref="FILE-WARN"/>
    <appender-ref ref="FILE-ERROR"/>
  </root>

</configuration>

 

 

버전3

Spring Profile마다 로깅방법을 다르게하였다.

Profile 마다 root레벨, logger 레벨, appender를 다르게 할 수 있다.

아래 설정은 dev가 아니면 콘솔에 로그를 찍어주고,

dev라면 콘솔에 로그를 찍지않고, WARN이상의 레벨로그들을 파일에 저장한다.

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
  <timestamp key="BY_DATE" datePattern="yyyy-MM-dd"/> <!--시간패턴을 저장한 변수-->
  <property name="LOG_PATTERN"
    value="[%d{yyyy-MM-dd HH:mm:ss}] %green([%thread]) %highlight(%-5level) [File:%cyan(%F)] [Func:%magenta(%M)] [Line:%yellow(%L)] [Message : %blue(%m)] - %msg%n"/>
  <property name="FILE_LOG_PATTERN"
    value="[%d{yyyy-MM-dd HH:mm:ss}] [%thread] %-5level [File:%F] [Func:%M] [Line:%L] [Message : %m] - %msg%n"/>

  <springProfile name="!dev">
    <!--콘솔출력 appender-->
    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
      <encoder>
        <pattern>${LOG_PATTERN}</pattern>
      </encoder>
    </appender>

    <root level="INFO">
      <appender-ref ref="STDOUT"/>
    </root>
  </springProfile>

  <springProfile name="dev">
    <!--WARN레벨  로그 파일 저장 appender-->
    <appender name="FILE-WARN" class="ch.qos.logback.core.rolling.RollingFileAppender">
      <file>./logs/warn-${BY_DATE}.log</file><!--최상위폴더/logs 디렉토리에 warn-날짜.log 파일에 로그가 쌓인다. -->
      <filter class="ch.qos.logback.classic.filter.LevelFilter">
        <level>WARN</level> <!--WARN 로그레벨에 대해서만 작동한다.-->
        <onMatch>ACCEPT</onMatch>
        <onMismatch>DENY</onMismatch>
      </filter>
      <encoder>
        <pattern>${FILE_LOG_PATTERN}</pattern>
      </encoder>
      <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
        <fileNamePattern>./logs/backup/warn/warn-%d{yyyy-MM-dd}.%i.gz</fileNamePattern>
        <!--%d{yyyy-MM-dd}로 rollover되는 시간을 매일 자정으로 설정했고, 로그파일이 logs/backup/warn 폴더에 gz압축파일형식으로 저장된다.-->
        <maxFileSize>10MB</maxFileSize> <!--로그파일 최대 크기는 10MB로 설정-->
        <maxHistory>30</maxHistory> <!--쌓이는 로그파일 최대 갯수는 30개로 설정-->
        <totalSizeCap>500MB</totalSizeCap> <!--로그파일이 저장되는 저장소의 최대 크기는 500MB로 설정-->
      </rollingPolicy>
    </appender>
    <!--ERROR레벨  로그 파일 저장 appender-->
    <appender name="FILE-ERROR" class="ch.qos.logback.core.rolling.RollingFileAppender">
      <file>./logs/error-${BY_DATE}.log</file>
      <filter class="ch.qos.logback.classic.filter.LevelFilter">
        <level>ERROR</level>
        <onMatch>ACCEPT</onMatch>
        <onMismatch>DENY</onMismatch>
      </filter>
      <encoder>
        <pattern>${FILE_LOG_PATTERN}</pattern>
      </encoder>
      <rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
        <fileNamePattern>./logs/backup/error/error-%d{yyyy-MM-dd}.%i.gz</fileNamePattern>
        <maxFileSize>10MB</maxFileSize>
        <maxHistory>30</maxHistory>
        <totalSizeCap>500MB</totalSizeCap>
      </rollingPolicy>
    </appender>

    <root level="WARN">
      <appender-ref ref="FILE-WARN"/>
      <appender-ref ref="FILE-ERROR"/>
    </root>
  </springProfile>


</configuration>

테스트

Profile이 local이라면

콘솔에 로그는 찍히지만, 파일에 로그는 쌓이지않는다.

콘솔에 로그는 찍히지않지만, 파일에 로그는 쌓인다.

 

 

서버시작시 logback-spring.xml이 적용되지만 application.yml에 로깅설정을 적는다면 그 설정값으로 덮어씌워진다.

<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
  <encoder>
    <pattern>${LOG_PATTERN}</pattern>
  </encoder>
</appender>

<root level="INFO">
  <appender-ref ref="STDOUT"/>
</root>

현재  logback-spring.xml의 내용이 이렇다고 할때

info 레벨 이상은 콘솔출력이 되어야한다. 

 

하지만 application.yml을 다음과 같이 수정하면

logging:
  level:
    root: warn

warn이상의 로그만 보이게된다.


 

LogBack Extension 중 Environment Properties

<springProperty>는 spring 환경설정 특성을 Logback 안에서 드러내게끔하는 태그이다.

그러니까 application.properties나 application.yml과 같은 스프링 환경설정 값들을 logback환경설정 파일 (xml)안에서 접근하고 싶을때 사용한다.

<springProperty>는 logback의 변수를 만드는 태그인 <Property>와 유사한 동작방식을 가진다.

그러나 Property는 값을 지정하지만, springProperty는 스프링 환경설정에서 값을 가져온다. 

 

<springProperty name="filePath" source="logging.file.path"/>

이렇게 되어있다면 .

#application.yml
logging:
  file:
    path: /server/myapp/logs

application.yml 이나 application.properties에 설정된 logging.file.path의 설정을 가져와 변수명 filePath에 저장한다는 뜻이다.

 

Spring Boot Features

If you need to call remote REST services from your application, you can use the Spring Framework’s RestTemplate class. Since RestTemplate instances often need to be customized before being used, Spring Boot does not provide any single auto-configured Res

docs.spring.io

 

Spring profile 마다 다르게 로깅, appender를 따로 xml로 만들고 불러와서 사용하기

 

 

[Spring] profile로 서버 환경에 맞는 Context 적용하기(-Dspring.profiles.active)

복수 이상의 WAS를 사용하는 상황에서 같은 Spring Application을 사용하지만 각 Sever에 맞게 의 Context를 설정해야 하는 경우가 있다. 예를 들자면 아래와 같은 상황이다.

velog.io

 

SpringBoot logback 더 쉽게 설정하기(application.properties와 logback-spring.xml)

include하여 logback 설정을 더 쉽게!

velog.io

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

 

[Logging] SLF4J란?

블로그를 작성하고, 테코톡을 진행했어요. 더 쉽게 이해하고 싶다면 아래 영상을 시청해주세요! [10분 테코톡] ☂️ 검프의 Logging(로깅) #1 SLF4J(Simple Logging Facade for Java)는 이름에서 확인할 수 있듯

livenow14.tistory.com

 

[Logging] Logback이란?

블로그를 작성하고, 테코톡을 진행했어요. 더 쉽게 이해하고 싶다면 아래 영상을 시청해주세요! [10분 테코톡] ☂️ 검프의 Logging(로깅) #2 Logback 로깅 프레임워크 중 하나로, SLF4J의 구현체에요. SL

livenow14.tistory.com

 

Logback - 1. 소개

logback 홈페이지의 매뉴얼을 읽으며 내용들을 정리한 글입니다. Logback 이란? Logback은 Java 커뮤니티에서 가장 널리 사용되는 로깅 프레임워크 중 하나입니다. 이전에 로깅에 사용되던 Log4j의 설립

ckddn9496.tistory.com

https://www.baeldung.com/logback 

https://logback.qos.ch/manual/appenders.html

 

댓글