본문 바로가기
빅데이터 부트캠프/Spring boot

빅데이터 부트캠프 97일차

by Mecodata 2022. 11. 23.

logging

- 로깅(logging) = 시스템 동작시 시스템의 상태와 작동 정보를 시간의 경과에 따라 기록하는 것
- Log = 로깅된 기록

logging Level

- Log는 위험도에 따라 6가지의 레벨로 나뉘어져 있음
- Logging Level은 src/main/resource에 있는 application.properties에서 설정해줄 수 있음
- 로그 레벨 설정지정한 로그 레벨 이상의 로그만을 수집하도록 설정하는 것

logger 생성방법

- private final Logger logger = LoggerFactory.getLogger(this.getClass());로 입력하여 Logger 수동으로 생성하여 사용 (LoggerFactory 이용)
- Controller에 @Slf4j 적용 => Controller의 메소드에서 log라는 변수명으로 Logger 자동 생성되어 바로 사용가능 (lombok @Slf4j 이용)
@Slf4j컨트롤러에서만 적용 가능하고 @RestControllerAdvice나 @ControllerAdvice에서는 적용해도 log 사용 불가능
SLF4J(Simple Logging Facade for Java) = logback을 사용하기 위한 인터페이스

logger의 메소드

- 각 Log Level에 따른 log 출력값에 대한 설정을 할 수 있음 (trace, debug, info, warn, error) -> fatal은 X

- 출력할 텍스트를 입력할 때 {}을 이용하면 받아온 인자값을 적용할 수 있음 (여러개일 경우 입력한 순서에 맞게 적용) 

ex) logger.error("RuntimeException : {}", RuntimeException.getMessage());

logback

- logback 사용을 위해서는 Spring의 기본 로그 라이브러리인 commons-logging를 제외시켜야함
- pom.xml 파일의 Dependencies에서 logback-core, logback-classic추가해야 사용가능
- logback을 import 하고난 후 src/main/resource logback-spring.xml 생성 => logging에 대한 설정 입력
- logback-spring.xml 예시

<?xml version="1.0" encoding="UTF-8"?>
<configuration scan="true" scanPeriod="60 seconds"> <!-- 60초마다 설정 파일의 변경을 확인 하여 변경시 갱신 -->
    <springProperty scope="context" name="LOG_LEVEL" source="logging.level.root"/>

    <!-- log file 경로설정 -->
    <property name="LOG_PATH" value="C://files"/>
    <!-- log file 이름설정 -->
    <property name="LOG_FILE_NAME" value="log"/>
    <!-- 에러 log file 이름설정 -->
    <property name="ERR_LOG_FILE_NAME" value="err_log"/>
    <!-- pattern -->
    <property name="LOG_PATTERN" value="%-5level %d{yy-MM-dd HH:mm:ss}[%thread] [%logger{0}:%line] - %msg%n"/>

    <!-- Console Appender = 콘솔창에 어떻게 출력될지 설정 -->
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${LOG_PATTERN}</pattern>
        </encoder>
    </appender>

    <!-- File Appender -->
    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>${LOG_PATH}/${LOG_FILE_NAME}.log</file> <!-- 파일경로 설정 -->

        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${LOG_PATTERN}</pattern> <!-- 출력패턴 설정-->
        </encoder>

        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_PATH}/${LOG_FILE_NAME}.%d{yyyy-MM-dd}_%i.log</fileNamePattern> <!-- 파일명 패턴 설정 -->
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>10MB</maxFileSize> <!-- 파일당 최고 용량 -->
            </timeBasedFileNamingAndTriggeringPolicy> 
            <maxHistory>30</maxHistory> <!-- 일자별 로그파일 최대 보관주기 => 해당 설정일 이상된 파일은 자동으로 제거-->
        </rollingPolicy>
    </appender>
	
	<!-- 에러의 경우 파일에 로그 처리 -->
    <appender name="Error" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <filter class="ch.qos.logback.classic.filter.LevelFilter">
            <level>error</level>
        </filter>
        <file>${LOG_PATH}/${ERR_LOG_FILE_NAME}.log</file>
        <encoder class="ch.qos.logback.classic.encoder.PatternLayoutEncoder">
            <pattern>${LOG_PATTERN}</pattern>
        </encoder>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>${LOG_PATH}/${ERR_LOG_FILE_NAME}.%d{yyyy-MM-dd}_%i.log</fileNamePattern>
            <timeBasedFileNamingAndTriggeringPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedFNATP">
                <maxFileSize>10MB</maxFileSize> <!-- 파일당 최고 용량 -->
            </timeBasedFileNamingAndTriggeringPolicy>
            <maxHistory>60</maxHistory> <!-- 일자별 로그파일 최대 보관주기 => 해당 설정일 이상된 파일은 자동으로 제거-->
        </rollingPolicy>
    </appender>

    <root level="${LOG_LEVEL}">
        <appender-ref ref="CONSOLE"/>
        <appender-ref ref="FILE"/>
        <appender-ref ref="Error"/>
    </root>

</configuration>

 

예외 처리 어노테이션

- @RestControllerAdvice = @RestController의 여러 메소드에서 전역적으로 발생할 수 있는 예외를 처리할 수 있도록 설정
- @ExceptionHandler(예외 클래스) = 메서드에 선언하고 특정 예외 클래스를 지정해주면 해당 예외가 발생했을 때의 실행문 정의 가능

- @ExceptionHandler를 설정한 메소드의 반환타입은 String이나 ResponseEntity를 사용

=> String = 간단히 지정한 텍스트만 반환하고 싶을때, ResponseEntity = logger의 상세한 정보를 반환하고 싶을 때 
- @ExceptionHandler@RestControllerAdvice나 @ControllerAdvice로 지정된 클래스에서 정의한 메소드에만 적용 가능
※ ResponseEntity에서 Status만 필수 입력이고 body나 header는 선택적으로 입력
- ex)

package com.spring.diary.common.exception;

import java.util.NoSuchElementException;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.http.ResponseEntity;
import org.springframework.web.bind.annotation.ExceptionHandler;
import org.springframework.web.bind.annotation.RestControllerAdvice;

@RestControllerAdvice
public class ApiException {
	
	private final Logger logger = LoggerFactory.getLogger(this.getClass());
    
	// NoSuchElementException 예외처리
	@ExceptionHandler(NoSuchElementException.class)
	public ResponseEntity<String> handlerNoSuchElementException(NoSuchElementException e) {
		logger.error(e.getMessage());
        return ResponseEntity
                .status(ExceptionEnum.NOT_FOUND.getStatusCode())
                .body(ExceptionEnum.NOT_FOUND.getMsg());  
	}
}

'빅데이터 부트캠프 > Spring boot' 카테고리의 다른 글

MyBatis 세팅  (0) 2022.12.13
빅데이터 부트캠프 96일차  (0) 2022.11.22
빅데이터 부트캠프 95일차  (0) 2022.11.21
빅데이터 부트캠프 94일차  (0) 2022.11.18

댓글