Web/팁

로깅(Logging)을 알아보자

보통 디버깅할때 System.out.prinln("")을 사용해왔다.

 

하지만 실무에서는 이런식으로 로깅을 하지 않는다!

 

 

 

 

로깅 라이브러리

SLF4J : http://www.slf4j.org 

 

SLF4J

Simple Logging Facade for Java (SLF4J) The Simple Logging Facade for Java (SLF4J) serves as a simple facade or abstraction for various logging frameworks (e.g. java.util.logging, logback, log4j) allowing the end user to plug in the desired logging framewor

www.slf4j.org

Logback : http://logback.qos.ch 

 

Logback Home

Logback Project Logback is intended as a successor to the popular log4j project, picking up where log4j leaves off. Logback's architecture is sufficiently generic so as to apply under different circumstances. At present time, logback is divided into three

logback.qos.ch

 

스프링 실무에서는 보통 SJF4J 인터페이스를 구현한 라이브러리 Logback을 사용한다.

 

 

 

 

 

사용방법

package hello.springmvc.basic;

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

@RestController
public class LogTestController {

    private final Logger log = LoggerFactory.getLogger(getClass());
    
    @RequestMapping("log-test")
    public String logTest() {

        String name = "Spring";

        System.out.println("name = " + name);

        log.info(" info log={}", name);

        return "ok";
    }
}

slf4j의 LoggerFactory에서 getLogger(getClass()); 로 slf4j의 Logger를 가져온다.

 

log.info(" info log={}", name) 를 실행하면

위와같이 날짜, 시간, log level, 쓰레드, 컨트롤러이름, 전달한 내용(string, name) 같이 여러 정보가 함께 나온다.

 

 

반면에 System.out.println으로 출력하면

이렇게만 나온다.

크나큰 차이

 

 

 

 

 

Log Level

  • log.trace
  • log.debug
  • log.info
  • log.warn
  • log.error
...
	@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.warn(" warn log={}", name);
        log.info(" info log={}", name);
        log.error(" error log={}", name);

        return "ok";
    }
...

 

위와 같이 작성 하고 application.properties 에서 

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

= trace로 해놓으면 trace ~ error 까지 전부 출력이 된다.

 

 

 

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

debug로 설정해놓으면

 

debug ~ error 까지 출력이 된다.

 

로그레벨을 지정해 놓으면 그 하위레벨들을 출력한다

 

 

그래서 보통

  • 개발 서버 : debug
  • 로컬 서버 : trace
  • 운영서버 : info

로 세팅한다.

 

 

추가정보

  • application.properties에서 로그레벨을 설정하지 않으면 info부터 로그가 나온다
  • logging.level.root = debug : 이런식으로 패키지 이름을 root로 지정하면 모든 패키지의 로그레벨을 지정할 수 있다.
  • 클래스 위에 @Slf4j 를 적어주면 private final Logger log = LoggerFactory.getLogger(getClass());를 생략할 수 있다
  • 성능도 println보다 log가 좋다

 

log.trace("trace log = " + name) 이런식으로 사용하지 않는 이유

 

log는 설정에따라 특정 레벨이 출력되지 않을 가능성이 높다. 

Java에서 "abc" + "abc" 는 실행되지 않더라도 연산이 들어간다.

출력되지 않을 가능성이 높은 곳에 쓸모없는 연산이 무조건 들어가는것은 심각한 자원낭비가 될 가능성이 높다.

 

그런데

 

log.trace("trace log = {}", name) 이렇게 사용하면 실행할때 parameter가 들어가기 때문에 자원낭비가 발생하지 않는다.