[SPRING #4] 로깅 처리하기 + 배너

eunseo·2021년 8월 21일
0

SPRING

목록 보기
4/14

💡 로깅 [logging]
시스템을 작동할 때 시스템의 작동 상태의 기록과 보존, 이용자의 습성 조사 및 시스
템 동작의 분석 등을 하기 위해 작동중의 각종 정보를 기록해둘 필요가 있다. 이 기록
을 만드는 것을 로깅이라 한다. 즉 로그 시스템의 사용에 관계된 일련의 「사건」을
시간의 경과에 따라 기록하는 것이다.

Java Logging Framework

  • java.util.logging
  • Apache Commons logging
  • Log4J
  • Logback
  • SLF4J(Simple Logging Facade for Java)

SLF4J

@Slf4j 어노테이션 사용법 편리 : https://programmer93.tistory.com/64

SLF4J(Simple Logging Façade For Java)란 Logging Framework들을 추상화해 놓은 것입니다. Facade Pattern을 이용한 Logging Framework입니다.

Logger


주의! Logger 설정은 이렇게 메인 메서드 위에서 설정한다.

public class OrderTester {
    private static final Logger log = LoggerFactory.getLogger(OrderTester.class);

    public static void main(String[] args) throws IOException {
        var customerId = UUID.randomUUID();

        var applicationContext = new AnnotationConfigApplicationContext(AppConfiguration.class);

        var environment = applicationContext.getEnvironment();
        var version = environment.getProperty("kdt.version");
        var minimumOrderAmount = environment.getProperty("kdt.minimum-order-amount", Integer.class);

        log.info("version -> {}", version);
        log.info("minimumOrderAmount -> {}", minimumOrderAmount);


        var resource = applicationContext.getResource("application.yaml");

        var resource2 = applicationContext.getResource("file:sample.txt");


        log.info(resource2.getClass().getCanonicalName());

    }
}

logback 설정하기

logback 설정파일 찾는 순서
1. logback-test.xml 파일을 먼저 찾습니다.
2. 없다면 logback.groovy 을 찾습니다.
3. 그래도 없다면 logback.xml을 찾습니다.
4. 모두 없다면 기본 설정 전략을 따릅니다. BasicConfiguration

logback configuration
http://logback.qos.ch/manual/configuration.html

Basic configuration file (main > java > org.prgms > resources > logback.xml)

<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>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
    </encoder>
  </appender>

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

debug로 설정을 해서 로그가 다 찍히는 것을 볼 수 있다.

<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>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
        </encoder>
    </appender>

    <logger name = "org.prgms" level="info"/>

    <root level="warn">   <!-- debug 보다 높은 레벨 출력 -->
        <appender-ref ref="STDOUT" />
    </root>
</configuration>

이렇게 org.prmgs는 info level이다, 라고 따로 설정도 가능하다.

orderProperties 안에 log는 debug 라고 함

package org.prgms.order;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.text.MessageFormat;

@Component
public class OrderProperties implements InitializingBean {

    private final static Logger logger = LoggerFactory.getLogger(OrderProperties.class);

    @Value("${kdt.version:v0.0.0}") // kdt.version 값을 못읽으면 v0.0.0 default 값
    private String  version;

    @Value("3")
    private Integer minimumOrderAmount;

    @Override
    public void afterPropertiesSet() throws Exception {
        logger.debug(MessageFormat.format("version -> {0}", version));
        logger.debug(MessageFormat.format("minimumOrderAmount -> {0}",  minimumOrderAmount));
    }

}

log가 어떻게 나올까?

debug는 info보다 낮은 레벨이기 때문에 찍히지 않는 것을 볼 수 있다!

orderProperties 안에 log를 info로 설정한다면?

package org.prgms.order;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.InitializingBean;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import java.text.MessageFormat;

@Component
public class OrderProperties implements InitializingBean {

    private final static Logger logger = LoggerFactory.getLogger(OrderProperties.class);

    @Value("${kdt.version:v0.0.0}") // kdt.version 값을 못읽으면 v0.0.0 default 값
    private String  version;

    @Value("3")
    private Integer minimumOrderAmount;

    @Override
    public void afterPropertiesSet() throws Exception {
        logger.info(MessageFormat.format("version -> {0}", version));
        logger.info(MessageFormat.format("minimumOrderAmount -> {0}",  minimumOrderAmount));
    }

}

이렇게 부분별로 나눌 수 있다!

PatternLayout
Logback이 기본적으로 제공한는 패턴레이아웃을 이용하면 우리가 로거에서 만든 로깅 이벤트를 가지고 문자열을 변환할 수 있습니다. 이때 문자열로 변환될때 conversion specifiers 라는걸 이용한다.
http://logback.qos.ch/manual/layouts.html

  1. %d - 로깅 이벤트의 날짜를 출력합니다. %date{ISO8601}, %date{HH:mm:ss.SSS} 이렇게 자바에서 제공하는 데이트 타임 페턴을 이용할 수 있습니다.
    https://docs.oracle.com/javase/8/docs/api/java/text/SimpleDateFormat.html
  2. %logger{length} - Logger name의 이름을 축약할 수 있습니다. {length}는 최대 차릿수입니다.
  3. %thread - 현재 Thread name
  4. %-5level - log level -5는 출력 고정폭 값
    a. -를 주면 오른쪽에 스페이스로 주어진 숫자보다 작은 문자열이 오면 공백을 채웁니다. 즉 INFO와 같이 4자리면 오른쪽에 1칸 공백 패딩처리가 됩니다.
    => 왼쪽 정렬!!
  5. %msg - log message %message은 alias
  6. %n - new line 개행처리 이걸 안하면 모든 로그들이 쭉 이어진다.
<configuration>
    <property name="LOG_PATTERN" value = "%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n" />

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

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

    <appender name="FILE" class="ch.qos.logback.core.FileAppender">
        <file>logs/kdt_${bySecond}.log</file>
        <append>false</append>
        <encoder>
            <pattern>${LOG_PATTERN}</pattern>
        </encoder>
    </appender>


    <logger name = "org.prgms" level="debug">
        <appender-ref ref = "FILE"/>
    </logger>


    <root level="warn">   <!-- debug 보다 높은 레벨 출력 -->
        <appender-ref ref="STDOUT" />
    </root>
</configuration>

FILE appender를 추가하면 kdt_20210822T003648.log가 생성된다(오늘 기준 8/22)

<configuration>
    <property name="LOG_PATTERN" value = "%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n" />

    <appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
        <encoder>
            <pattern>${LOG_PATTERN}</pattern>
        </encoder>
    </appender>
    
   <appender name="ROLLING_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>logs/access.log</file>
        <rollingPolicy class = "ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>logs/access-%d{yyyy-MM-dd}.log</fileNamePattern>
        </rollingPolicy>
        <encoder>
            <pattern>${LOG_PATTERN}</pattern>
        </encoder>
    </appender>
    
    <logger name = "org.prgms" level="debug">
        <appender-ref ref = "ROLLING_FILE"/>
    </logger>
    
    <root level="debug">
        <appender-ref ref="STDOUT" />
    </root>
</configuration>
    

롤링파일을 이용하면 현재 날짜 기준으로 파일은 access.log가 생성되며, 만약 하루가 지나면 이 access.log 파일이 access-2021-8-22.log파일로 바뀌게 된다.
장점은 현재 날짜 폴더는 access이기 때문에 날짜를 몰라도 된다는 장점을 가지고 있다!

스프링 프레임워크 이용하여 logging 처리

https://docs.spring.io/spring-boot/docs/2.5.1/reference/htmlsingle/#howto.logging.logback
10.7.1 base.xml 참고

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <property name="LOG_PATTERN" value = "%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n" />
    <include resource="org/springframework/boot/logging/logback/defaults.xml"/>
    <include resource="org/springframework/boot/logging/logback/console-appender.xml" />

    <appender name="ROLLING_FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>logs/bokzip.log</file>
        <rollingPolicy class = "ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>logs/bokzip-%d{yyyy-MM-dd}.log</fileNamePattern>
        </rollingPolicy>
        <encoder>
            <pattern>${LOG_PATTERN}</pattern>
        </encoder>
    </appender>

    <root level="WARN">
        <appender-ref ref="CONSOLE" />
    </root>

    <logger name="org.springframework" level="warn">
        <appender-ref ref = "ROLLING_FILE"/>
    </logger>

</configuration>

(+) 배너 추가하기

SpringBoot Banner 제너레이터
https://patorjk.com/software/taag/#p=testall&f=Graffiti&t=bokzip

profile
backend developer

0개의 댓글

관련 채용 정보