본문 바로가기

Back-End

Logback 아키텍처

Logback 아키텍처

Logback 아키텍처는 다른 환경에도 적용할 수 있도록 아주 일반적으로 설계되어 있다. logback은
  1. logback-core : 다른 두 모듈의 기본이다.
  2. logback-classic : logback-core를 extend 하였다. log4j을 개선한 것이다. SLF4J API를 기본적으로 구현하여  JDK 1.4에 소개된 log4j 또는 java.util.logging과 같은 다른 로깅 시스템과 로그백간에 쉽게 전환을 할 수 있다.
  3. logback-access : 서블릿 컨테이노와 통합되어 HTTP-access 로그 기능을 제공한다.
Logback 아키텍처의 기본 요소들에 좀더 자세히 알아보자.

logback image에 대한 이미지 검색결과


Logback 아키텍처 - Logger, Appenders, Layouts

 Logback 아키텍처에서 Logback은 이 3가지 클래스로 동작한다. 이 세가지 요소를 통해 개발자가 메시지 타입,레벨에 따라 로그를 남기고 이 로그가 어떤 형식으로 출력할 것인지 어떤 형태로 출력할 것인지 정할 수 있게 해준다.

Logger 클래스는 logback-classic 모듈에 있지만,  Appender와 Layout은 logback-core 모듈에 있다. 범용으로 사용하기 위해 logback-core에는 로거 개념이 들어있지 않다.


Logger context

로깅 API가 System.out.println보다 좋은 점은 출력문을 마음대로 설정할 수 있는 것이다.  모든 로거는 LoggerContext에 추가된다. LoggerContext는 로거를 조작하고 트리 구조로 로거들을 배치한다. 

Logger들은 모두 이름을 가지고 있다. 이 이름에 따라 parent-child구조를 가진다. 예를 들어, "com.overnodes" 로거가 "com.overnodes.util" 로거의 부모 로거가 되는 것이다. 

루트 로거는 로거 계층에서 가장 위에 존재한다. 

Logger rootLogger = LoggerFactory.getLogger(Logger.ROOT_LOGGER_NAME);

다른 로거들도 위와 같이 org.slf4j.LoggerFactory 클래스에 이름을 넘겨주면 로거를 가져 올 수 있다.


Logging level

package org.slf4j;
public interface Logger {

// Printing methods:
public void trace(String message);
public void debug(String message);
public void info(String message);
public void warn(String message);
public void error(String message);
}

로깅 레벨에는 다음과 같이 5가지 단계가 있다.


로거에 level을 설정하지 않으면, 부모의 로깅 레벨을 사용한다. 아래 예제를 살펴보자.


Logger nameAssigned levelEffective level
rootDEBUGDEBUG
XnoneDEBUG
X.YnoneDEBUG
X.Y.ZnoneDEBUG
 
Logger nameAssigned levelEffective level
rootDEBUGDEBUG
XINFOINFO
X.YnoneINFO
X.Y.ZERRORERROR


Basic Selection Rule

'요청한 로깅 레벨 >= 실제 로거의 로깅 레벨' 이어야 로그가 동작한다.

TRACE < DEBUG < INFO < WARN < ERROR

Appenders

Logback에 또 다른 기능은 로깅 요청을 다양한 곳에서 출력할 수 있는 것이다. logback에서는 output하는 곳을 Appender라고 부른다. Appender의 종류에는 Console, 파일, 원격 소켓 서버, MySQL, PostgresSQL, JSM, UNIX syslog dameon이 있다. 


로거에는 하나 이상의 Appender를 설정 할 수 있다.


addAppender라는 함수가 주어진 로그에 Appender를 설정해준다. Appender가 L이라는 로그에 설정되면, L 하위에 있는 로거에 로깅 요청이 온 경우, 모두 이 Appender를 호출한다. 


예 ) com.overnodes.util에서 로깅 요청을 한 경우, 부모 로거에 설정된 console, file appender가 모두 실행 된다.


root looger <- console appender

com

com.overnodes <- file appender

com. overnodes.util 


물론 하위 로거에서 호출되지 않기를 바라면, additivity flag = false 로 설정해주면 된다.


Layout

로그 출력 형식을 설정할 수도 있다. Pattern Layout에 정해진 규칙대로 설정해주면 우리는 출력 형식을 마음대로 바꿀 수 있다.

( 형식 설정 방법 : https://logback.qos.ch/manual/layouts.html )

변수 로깅에 출력하기


logger.debug("The new entry is {}. It replaces {}.", entry, oldEntry);


Logback 아키텍처 -logback 동작과정

logger.info() 함수를 실행시켰을 때, logback framework에서 어떠한 단계로 이루어지는지 살펴보자.




1. Filter chain 결과 가져오기

TurboFilter가 있다면, chain 이 실행된다. Turbo filter는 context 전역적으로 선언되기 때문에 모든 로그 이벤트 요청에 필터가 적용된다. 
필터 체인의 결과에 따라 동작이 다르다. 로깅 요청과 관련된  Marker, Level, Logger, message, Throwable정보를 보고 특정 이벤트를 filter 할 수 있다.
  • FilterReply.DENY : logging request는 끝난다.
  • FilterReply.NEUTRAL : 2번째 단계로 넘어간다.
  • FilterReply.ACCEPT : 2번째 단계를 건너뛰고, 3번째 단계로 넘어간다.

2. Basic Selection rule 적용하기

logback이 요청의 logging level과 실제 로거의 level을 비교한다. 로거 레벨이 INFO인데 요청 로깅 레벨이 DEBUG인 경우 다음 단계로 넘어가지 않고 끝난다.

3. LoggingEvent 객체 생성

Request가 이전 필터를 통과하면, logback은 현재시간, 현재 쓰레드, 요청, 요청레벨, 메시지 등 정보를 담고 있는 ch.qos.logback.classic.LoggingEvent 객체를 생성한다. 몇몇 정보는 실제로 필요할 때 초기화된다. MDC는 추가 정보로 로깅 요청을 꾸미는데 사용된다. ( 자세한 내용은 https://logback.qos.ch/manual/mdc.html 을 참고 )

4. Appenders 실행

LoggingEvent 객체가 생성된 후, logback context를 상속받은 Appenders의 doAppend() 함수를 logback이 실행시킨다. 

5. Output 형식 맞추기

로깅 이벤트를 형식화하는 것은 호출된 Appender의 책임이다. 그러나, 몇몇 Appender는 로깅 이벤트를 형식화하는 작업을 Layout에게 위임한다. Layout이 로깅이벤트를 형식화하여 String으로 리턴해준다. 

SocketAppender와 같은 것들은 로깅 이벤트를 string으로 변환하지 않고 직렬화한다. 그러므로, Layout 객체도 필요없다. 

6. Appender에게 Logging Event 보내기

loggin event가 완전히 format 되고 나면, 각각의 Appender에게 보내진다.  


'Back-End' 카테고리의 다른 글

서버 개발자의 SPA 적용기 - NHN FORWARD  (0) 2019.11.27
Spring - Unable to acquire JDBC Connection 이슈  (1) 2019.08.02
백앤드 개발자 면접 준비 리스트  (0) 2019.03.31
2.logback Appender란  (0) 2018.09.19
서버 아키텍처  (0) 2018.03.06