✏️ Logging

박상민·2023년 7월 26일
0

SpringMVC

목록 보기
5/11
post-thumbnail

⭐️ Logging?

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

운영 시스템에서는 System.out.println()같은 시스템 콘솔을 사용해서 필요한 정보를 출력하지 않고, 별도의 로깅 라이브러리를 사용해서 로그를 출력한다.


로깅 라이브러리는 스프링 부트 라이브러리를 사용하면 자동으로 포함된다.
로그 라이브러리는 Logback, Log4J, Log4J2 등 많은 라이브러리가 있는데, 이것들을 통합해서 인터페이스로 제공하는 것이 SLF4J 라이브러리다.

📌 로그 선언과 호출


✔︎ 로그 선언

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class LogTestController {
private final Logger log = LoggerFactory.getLogger(LogTestController.class);
}

또는

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class LogTestController{...}

로그를 선언하는 방법은 첫번째 코드처럼 private final Logger log = LoggerFactory.getLogger(LogTestController.class); 를 작성해주는 방법도 있지만 간단하게 @Slf4j 애노테이션을 추가하는 방법도 존재한다.

✔︎ 로그 호출

로그 호출은 다음과 같은 형식으로 할 수 있다.

log.info("hello")

그렇다면 System.out.println("hello)log.info("hello")의 차이는 무엇일까?
아래 코드를 실행해서 차이점을 알아보자

package hello.springmvc.basic;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@Slf4j
public class LogTestController {
    @RequestMapping("/log-test")
    public String logTest() {
        String name = "spring";
        
        System.out.println("name = " + name);
        log.info("info log={}", name);
 
        return "ok";
    }
}

출력

출력 결과의 차이가 분명하게 보인다. 로그는 시스템 출력과 다르게 쓰레드 정보, 클래스 이름, 시각 등 부가 정보를 볼 수 있다는 것을 알 수 있다. 또한 출력 결과에서는 알 수 없지만 성능도 System.out보다 좋다.

📌 로그의 여러가지 출력 방법

package hello.springmvc.basic;

import lombok.extern.slf4j.Slf4j;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
@Slf4j
public class LogTestController {
    @RequestMapping("/log-test")
    public String logTest() {
        String name = "spring";
        log.trace("trace log={}", name);
        log.debug("debug log={}", name);
        log.info("info log={}", name);
        log.warn("warn log={}", name);
        log.error("error log={}", name);

        return "ok";
    }
}

로그는 위 코드에서 보이는 것처럼 trace, debug, info, warn, error 출력이 존재한다. 한 번 출력 결과를 확인해보자.

출력

그런데 분명 나는 trace, debug, info, warn, error을 출력하였는데 출력 결과를 보니 trace, debug 출력이 보이지 않는다. 왜일까?
이를 해결하기 위해서는 로그 레벨을 설정해야한다.

✔︎ 로그 레벨 설정

로그 레벨 설정을 변경해서 원하는 출력 결과를 만들어보자.

  • 로그 레벨: TRACE > DEBUG > INFO > WARN > ERROR
  • 보통 개발 서버는 DEBUG 레벨에서 출력
  • 보통 운영 서버는 INFO 레벨에서 출력

로그 레벨을 설정하기 위해서는 application.properties를 변경해야한다.

application.properties에 다음과 같은 설정을 추가하자

#전체 로그 레벨 설정(기본 info)
logging.level.root = info

#hello.springmvc 패키지와 그 하위 로그 레벨 설정
logging.level.hello.springmvc=trace

가장 상위 레벨인 trace로 패키지와 하위 로그 레벨을 설정하였다. 이제 다시 출력 결과를 확인해보자

출력

trace, debug, info, warn, error 레벨이 모두 출력되는 것을 확인할 수 있다.

📌 올바른 로그 사용 방법

log.debug("data=" + data)
log.debug("data=", data)

위 두 줄의 코드는 모두 같은 출력 결과를 가질 것이. 그러나 log.debug("data=" + data)는 잘못된 로그의 사용방법이다. 이유를 알아보자!

  • log.debug("data=" + data)
    로그 출력 레벨이 info라면 위의 debug 로그는 출력되지 않을 것이다. 하지만 "data=" + data는 실제 실행이 된다. 이는 의미없는 연산을 발생시키고 불필요하게 리소스를 소모한다.

  • log.debug("data=", data)
    하지만 위의 코드는 로그 출력 레벨을 info로 설정해도 아무런 연산도 발생하지 않는다.

의미없는 연산을 하지 않는 log.debug("data=", data) 형식이 올바른 로그 사용법이다.

📌 로그 사용시 장점

  • 쓰레드 정보, 클래스 이름 같은 부가 정보를 함께 볼 수 있고, 출력 모양을 조정할 수 있다.
  • 로그 레벨에 따라 개발 서버에서는 모든 로그를 출력하고, 운영서버에서는 출력하지 않는 등 로그를 상황에 맞게 조절할 수 있다.
  • 시스템 아웃 콘솔에만 출력하는 것이 아니라, 파일이나 네트워크 등, 로그를 별도의 위치에 남길 수 있다. 특히 파일로 남길 때는 일별, 특정 용량에 따라 로그를 분할하는 것도 가능하다.
  • 성능도 일반 System.out보다 좋다.

출처
김영한님의 Spring MVC 강의
SLF4J - http://www.slf4j.org
Logback - http://logback.qos.ch

profile
스프링 백엔드를 공부중인 대학생입니다!

0개의 댓글