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