로그백으로 로그 관리하기

1

Spring

목록 보기
3/12
post-thumbnail

로깅이 뭔데 ?

정보를 제공하는 일련의 기록인 로그(log)를 생성하도록 시스템을 작성하는 활동이다. 평소 우리는 콘솔 창에 일련의 정보를 나타내고 싶다면 System.out.println(”...”); 을 사용하였겠지만 실무에서는 저런 허접한 메서드를 사용하지 않는다. sout을 사용하지 않는 이유와 로그를 생성할 수 있는 다른 방법을 알아보자.

System.out.print .. 를 사용하면 안되는 이유 ?

콘솔창에 띄워서 정보를 제공하는데에 sout을 사용해도 상관없다고 생각할 수 있지만 실무에서 로그를 띄울 때 sout을 사용하지 않는데는 이유가 있다. → 물론 개발서버에서는 개발자가 이것저것 확인해본다는 가정하에 사용할 수 있지만 운영서버에서는 절대 사용하지 말자

우리가 운영서버에 sout으로 로그를 찍었다 → 사용자가 수십 수백명인 서비스에서는 큰 문제가 일어나지 않을 수 도 있지만 만약 사용자가 수십 수백만명이 있는 서비스에서 저런 로그를 찍으면 서버에 무리가 가고 성능 저하 이슈가 생길 수 있다.

그럼 우린 어떻게 로그를 사용해 하냐

로그 메서드를 사용하고 싶다면 Logger라는 클래스를 참조하는 변수를 만들어 사용해야한다.

private final Logger log = LoggerFactory.getLogger(getClass());

String name = "log";
log.trace("log trace {}" + name);

지금 시대가 어느 시대인데;;

“아니 우리가 어느 시대인데 저렇게 긴 코드를 맨날 쓰고 로그를 사용해야 하냐”와 같은 궁금증이 생길 수 있는데 당연히 해결책이 있다.

Log4j와 Slf4j

Log4j와 Slf4j는 Lombok이라는 라이브러리에서 지원하는 어노테이션이므로 build.gradle에서 lombok 라이브러리 의존성을 추가해주어야 한다.

compileOnly 'org.projectlombok:lombok'
	annotationProcessor 'org.projectlombok:lombok'

기본적으로 위와 같은 코드를 간단하게 대체할 수 있는 어노테이션이 Log4j이다.

@Log4j
public ...{

String name = "log";
log.trace("log trace {}" + name);
}

Slf4j = java.util.logging, logback + log4j 라고 보면 편하다. 결국 Slf4j는 Log4j보다 더 성능이 좋고 최적화 된 어노테이션이라는 뜻이다.

@Slf4j
public ...{

String name = "log";
log.trace("log trace {}" + name);
}

로그를 출력하는 방법은 ?

지금까지 로그와 Logfj, Slf4j에 대해서 알아보았다. 지금부터는 로그 출력 방법에 대해서 알아보자.

로그에는 5가지 레벨(Level)이 있다. 위험도를 나타내는 수준에 따라 로깅 레벨이 다르다.

  • log.trace - 가장 낮은 레벨의 로그이다
  • log.debug - 개발 단계에서 많이 사용하는 로그이다
  • log.info - 운영 시스템에서 많이 사용하는 로그이다
  • log.warn - 위험 수준의 로그이다.
  • log.error - 즉시 문제를 파악하고 에러를 잡아야한다.

Info 레벨부터는 콘솔에 로그가 찍힌다.

기본적인 로그 출력 방법은 sout과 비슷하다

String name = "Spring";
        String warn = "아 이건 좀 위험하다";
        String error = "아 큰일이다 빨리 고쳐야해";

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

        log.trace("trace log = {}", name);
        log.debug("debug log = {}", name);

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

로깅 최적화 방법과 주의점

위에서 Log4j → Slf4j가 되면서 어느정도의 성능의 최적화가 되긴했지만 아직 문제점이 있다. 우리가 sout을 사용하지 않는 이유가 사용자가 많아지고 그에 따라 로그의 수가 늘어나면 결국 성능 저하 이슈가 발생할 수 있기 때문이라고 말했는데, 위의 출력을 보면 결국 INFO, WARN, ERROR 3가지 레벨의 로그는 무조건 다 출력하고있다

그래서 스프링에서는 이런 문제의 해결방안을 제시하였는데 바로 properties 또는 yml 파일에서의 설정이다.

application.yml

logging.level.tobyAndSpring.studySpring.controller.LogTestController : WARN

경로 + 어느 레벨부터 콘솔에 로그를 출력할 것인지에 대한 설정을 해준 모습이다. 위와 같은 설정을 해주면 아래와 같이 설정해준 로그부터 그 윗단계 로그들을 출력해준다.

String name = "log";

// 두 개의 의미는 같을까 ?
log.info("info log = {}", name);
log.info("info log = " + name);

결론부터 말하자면 2개의 의미는 같다. 하지만 두 번째 출력 방식은 사용하면 안된다. 그 이유는 자바 언어 자체의 특징 때문에 그런데, 단계별로 풀어서 보자.

yml에서 WARN으로 설정해준 상태

log.info("info log = " + name);
log.info("info log = name");

아니 어차피 WARN으로 설정해서 출력되지 않음에도 불구하고 이미 JRE에서는 + 연산을 마치고 값을 가지고 있는 상태이다. 하지만 { } 를 사용하면 불필요한 연산이 일어나지 않으므로 성능면에서 더욱 강력한 최적화가 이루어진다.

로그의 장점

  • 스레드 정보, 클래스 이름 같은 부가 정보를 함께 볼 수 있고, 출력 모양을 조정할 수 있다.
  • 로그 레벨에 따라 개발 서버에서는 모든 로그를 출력하고, 운영 서버에서는 출력하지 않는 등 로그를 상황에 맞게 조절할 수 있다.
    • 콘솔에만 출력하는게 아니라 파일이나 네트워크 등, 로그를 별도의 위치에 남길 수 있다. 특히 파일로 남길 때는 용량이 넘치면 장애 이슈가 생길 수 있는데 당연히 파일을 분할해준다거나 스레드 풀 같이 개수를 지정해서 저장할 수 있는 기능을 제공한다
  • 성능이 sout보다 훨씬 좋다(내부 버퍼링 지원, 멀티 스레드 지원)

로그백 정리

  • 로깅이 무엇인가
  • 왜 sout대신 로깅을 사용해야하는가
  • slf4j가 무엇인가
  • 로깅의 사용법
  • 스프링에서 제공하는 로깅 최적화 방법
  • 로깅을 더 잘 사용하는 법
  • 로깅의 장점

0개의 댓글