본문 바로가기
✨ Back-end/etc

로깅(Logging) 에 대해서, 왜 써야하는지? @Slf4j 어노테이션

by 환풍 2023. 8. 27.
728x90
반응형

 

로깅(Logging) 이란?

실행 동작을 일련의 기록인 로그(Log)의 생성을 통해 남겨놓는 일이다. 로그는 재현하기 힘든 버그나 성능에 대한 통계 등, 프로그램 동작에 있어서 유용한 정보를 제공하기 때문에 로깅 작업은 실제 서비스 개발에 필수적이다.

 

보통 데이터를 넘겨주고 받는 과정에서 컨트롤러에서 System.out.Println( ) 메서드를 이용해 컨트롤러에 데이터가 왔는지 체크를 하게 된다. 간편해서 이렇게 늘 사용해왔는데, 치명적인 단점이 존재한다.

 

System.out.println( ) 메서드를 사용했을 때의 문제점

1. 성능 저하

System.out.println( ) 메서드는 내부적으로 newLien( ) 메서드를 호출하는데, 이는 sysnchronized 가 사용된다.

sysnchronized는 메서드나 블록 코드에 동기화 영역을 표시하는 것으로, 동기화된 블록은 한 시점에 1개의 스레드만 접근 가능하다. 이때 블록에 접근 시도하는 다른 스레드들은 블록 안의 스레드가 실행을 마치고

블록을 벗어날 때 까지 블록 상태(멀티 스레드의 동시 접근 방지)가 된다.

즉, System.out.println( ) 메서드를 여러 스레드가 사용한다면 오버헤드가 발생해 프로세스 처리가 늦어지게 된다.

*오버헤드(Overhead) : 어떤 처리를 하기 위해 추가로 들어가는 처리 시간, 메모리 등의 컴퓨터 자원

 

2. 로그 출력레벨 사용 불가.

System.out.println( ) 을 사용하면  단순히 문자열만 찍는 메서드이기 때문에, 로깅시 필요한 날짜, 시각, 문제 수준, 위치 등 정보를 따로 표시할 수 없다.

 

3. 휘발성

System.out.print()는 표준 출력으로만 사용되고 따로 기록되지 않는다. 로그 파일로서 관리 할 수 없기 때문에 사후 처리시 로그 확인이 불가능하다.

 

로그 사용시 장점

1. 쓰레드 정보, 클래스 이름 같은 부가 정보를 함께 볼 수 있고, 출력모양 조정 가능

2. 로그 레벨에 따라 개발 서버에서 모든 로그를 출력하고, 운영서버에서는 출력하지 않는 등 로그 상황에 맞게 조절 가능

3. 시스템 아웃 콘솔에만 출력하는 것이 아니라, 파일이나 네트워크 등, 로그를 별도의 위치에 남길 수 있다.

특히 파일로 남길 때는 일별, 특정 용량에 따라 로그를 분할하는 것도 가능하다.

4. 성능도 일반 System.out 보다 좋다.


 

사용 방법

로그 레벨

TRACE > DEBUG > INFO > WARN > ERROR

로그 레벨은 위와 같은 계층 구조를 가지고 있다. 로거에 설정한 레벨보다 낮은 로거의 레벨은 기록되지 않는다.

만약 TRACE로 로그 레벨을 설정했다면, TRACE, DEBUG, INFO, WARN, ERROR 모두 출력될 것이다.

 

위와 같이 프로젝트를 생성하고, application.properties 파일에 로그 레벨을 지정해준다.

logging.level.root 

루트 패키지는 어떤 패키지도 명시적으로 설정되어 있지 않은 경우 해당하는 모든 로그를 의미하므로,

모든 패키지에 있는 로그 레벨을 설정한 것이다. 로그 레벨이 INFO 로 설정되면, INFO, WARN, ERROR 로그가 출력된다.

 

하지만, 밑에 있는

logging.level.test.ttt = trace

이 설정으로 인해, test.ttt 패키지의 로그레벨만 TRACE로 지정된다. 이 패키지에 해당하는 클래스들의 로그 레벨은 TRACE부터 ERROR까지 모든 레벨의 로그가 출력되는 것이다.

 

위 컨트롤러는 test.ttt.basic에 있는 컨트롤러이므로, logging.level.test.ttt = trace 의 영향을 받는다.

따라서 이렇게 모든 로그의 값이 찍히는 것을 확인해볼 수 있다.

 

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

이 코드를 해석해보자면,

1. Logger 인스턴스를 생성한다.
2. private final :

이 변수는 해당 클래스 내에서만 접근 가능하며, 변경이 불가능하다.

3. Logger log :

이 변수의 이름은 log로 설정되어있다.

4. LoggerFactory.getLogger(getClass()) :

LoggerFactory는 Spring 프레임워크의 로깅을 관리하는 클래스다. getLogger() 메서드는 로그를 생성하기 위한 팩토리 메서드이다. getClass()는 현재 클래스의 Class 객체를 반환한다. 따라서 현재 클래스에 대한 로그 레퍼런스가 생성된다.

 

이렇게 만들어진 객체를 이용해 로그 메시지를 log.trace(...), log.debug(..)와 같이 기록할 수 있다.

 

 

private final Logger log = LoggerFactory.getLogger(getClass());   생략코드.

클래스에 어노테이션으로 @Slf4j 을 주면, Logger 객체를 생성해주지 않아도 log로 찍어 사용가능하다.

728x90
반응형

댓글