Spring MVC : SLF4J를 활용한 로그 남기기

    로그 남기기


    로그 남기기는 개발 단계에서는 반드시 필요한 작업이다. 에러가 발생했을 때, 에러의 발생 지점을 Trace하는데 굉장히 유용한 도움을 주기 때문이다. 기본적으로 로그 남기는 라이브러리에 대해서 잘 모르는 상황이라면 System.out.println()을 적재적소에 넣으면서 사용했을 것이다. 그렇지만 앞으로는 로그 라이브러리를 사용해서 로깅하는 것을 해야한다.

    SLF4J는 로그 라이브러리의 인터페이스라고 볼 수 있다. SLF4J를 구현한 여러 구현체가 있는데, 주로 사용하는 구현체는 LogBack이 된다. 이번 포스팅에서는 LogBack을 사용해서 로깅하는 방법을 함께 찾아보려고 한다. 

     

    로그를 사용하기 위해서?


    1. 로거 만들기

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

    로그를 보기 위해서는 로그를 찍어주는 로거가 있어야 한다. 이런 로거는 SL4FJ 인터페이스의 LoggerFacotry에서 getLogger를 통해 현재 클래스를 넣어주면, 이에 대응되는 로거가 만들어진다. 그렇지만 이런 과정들이 매우 번거롭기 때문에 Spring에서는 @SLF4J라는 어노테이션을 지원해준다.

    @Slf4j // lombok임.
    public class LogTestController {
    //    private final Logger log = LoggerFactory.getLogger(LogTestController.class);
    
    }

    @SlF4J 어노테이션을 달게 되면 자동으로 이 클래스에 필요한 로거를 만들어준다. 따라서 사용자는 앞으로 @SLF4J를 붙여주면서, 편하게 로거를 쓸 수 있으면 된다. @SLF4J는 LOMBOK 라이브러리가 지원해준다.

    2. 로그 호출

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

    로거(log)를 통해서 여러가지 로그를 출력해볼 수 있다. 위의 trace / debug / info / warn / error는 로그에서 지정하는 레벨을 표현한다. 일반적으로는 다음과 같은 단계를 가진다.

    • 로그가 출력되는 포멧 확인
      • 시간 / 로그 레벨 / 프로세스 ID / 쓰레드명 / 클래스명 / 로그 메세지
    • 로그 레벨은 여러 형태로 나누어짐
      • LEVEL : trace > debug > info > warn > error
      • 개발 서버는 debug 출력 
      • 운영 서버는 info 출력 → 너무 많은 로그가 찍히면 성능이 느려지기 때문이다. 

    로그 레벨에 따라서 찍히는 형태가 달라진다. 예를 들어, 이번에 내가 선택한 로그가 debug라고 하면 debug를 포함한 윗 레벨의 모든 로그가 찍히는 방식이다. 

     

    로그 실습하기


    @RequestMapping("/log-test")
    public String logTest() {
        String name = "Spring";
    
        // 과거 로그 찍는 방식
        System.out.println("name = " + name);
    
        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";
    
    }

    위의 코드에 대한 로그를 찍어보자. 로그를 찍어보면 info 레벨 위의 모든 로그들이 찍히는 것을 알 수 있다. 이는 현재 보고 있는 로그의 default 레벨이 info로 설정되어있기 때문이다. 더 아랫단의 로그를 보고 싶다면, application properties에서 수정을 해주면 된다. 

     

    로그 출력 레벨 수정하기 (모든 영역 /특정 영역)


    logging.level.root=trace // default = info
    logging.level.hello.springmvc=debug

    application.properties에 위의 코드를 추가하면서 로그 출력 레벨을 수정할 수 있다. 

    root에 값을 넣게 되면, 모든 패키지에 동일하게 적용되는것이다. 그렇지만 특정 패키지에만 Log Level을 적용하고 싶다면, logging.level.특정경로 = 레벨로 설정해주면 된다. 

    위의 코드를 적용하게 될 경우, trace level부터 찍히는 것을 확인할 수 있었다! 

     

    올바른 Log 사용법


    Log를 사용할 때는 반드시 PathVariable 형태로 찍어주어야한다. 절대로 '+'연산으로 log를 찍어주면 안된다. 자바는 기본적으로 문자열에 '+'가 붙어있으면, 먼저 문자열을 생성하고 연산을 한다. 연산을 하게 되면 메모리, CPU가 사용되고 결정적으로 새로운 String이 하나 다시 만들어지게 된다.

     

    거기에 더해서 trace.log("trace my log = " + my_log)라고 해보자. 근데 나는 info 윗단계만 코드를 출력한다고 했다. 그렇다면 trace라서 이 코드가 실제로 출력되지는 않지만 '+' 연산자가 있기 때문에 이미 변수는 만들어지게 된다. 쓸모없는 일을 하게 된다.

     

    Log 사용 권장방법


    log를 사용할 때는 다음과 같은 형식으로 사용될 것이 권장된다.

    log.info("my log = {}, {}, {}", a,b,c)

     

     

    Log를 사용할 때 장점은?


    • 쓰레드 정보, 클래스 이름 같은 부가정보를 함께 볼 수 있고, 출력 모양을 조절할 수 있다.
    • 로그 레벨 설정에 따라 개발 서버와 운영 서버에서의 출력 로그 레벨을 다르게 가져갈 수 있음.
    • println은 콘솔에만 남음. 그렇지만 로그는 파일로 남길 수 있고, 네트워크로도 보낼 수 있따.
    • 성능도 println 보다 좋다.

    댓글

    Designed by JB FACTORY