본 문서는 https://logback.qos.ch/manual/introduction.html을 번역/요약/정리/사견 추가한 글입니다.
1. 기본 구조
logback은 3개의 모듈로 이뤄져있습니다. logback-core, logback-clssic, logback-access이며 logback-core가 다른 모듈들의 기반이 됩니다. classic은 core를 확장해 slf4j api를 구현합니다. access는 HTTP-access 로그 기능을 지원합니다.
2. 기본 클래스들 (Logger, Appenders, Layouts)
logback의 기본 클래스인 logger, appenders, layouts는 서로 협력해 메시지 타입과 레벨에 맞게 로그를 남길 수 있게 해주고 포맷 방식, 로그 기록 방식 등을 런타임에 제어해줍니다.
2.1. Logger
로깅 API가 System.out.println에 비견해 가지는 가장 큰 장점은 메시지의 분류입니다. 구체적으로 개발자가 정한 특정 조건에 따라 메시지를 카테고리화할 수 있습니다. logback classic에서 이런 역할을 Logger가 합니다.
모든 로거들은 LoggerContext에 종속되는데 여기서 로거들은 계층을 이룹니다. 계층을 이루는 방식은 패키지 경로의 계층 구조를 이루는 방식과 같습니다. 예를 들어, com.foo는 com.foo.Bar의 부모(parent)이며 java는 java.util의 부모이며 java.util.Vector의 조상(ancestor)입니다. 다만 로거의 이름은 이 로거를 쓰는 클래스의 fully qualified name을 쓰는게 지금까지의 국룰입니다.
로거들은 LoggerFactor.getLogger(String name)으로 얻을 수 있습니다. 이 때 반환되는 클래스는 slf4j의 Logger 인터페이스입니다.
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);
}
2.1.1 Effective Level
모든 로거는 자신만의 레벨을 가집니다. 레벨은 TRACE, DEBUG, INFO, WARN, ERROR 중 하나가 될 수 있으며 레벨을 지정하지 않으면 가장 가까운 자신의 조상의 레벨을 따릅니다. 루트 로거의 기본 레벨은 DEBUG이므로 이를 따로 바꾸지 않으면 모든 하위 로거들은 DEBUG가 됩니다.
로거의 메소드로 로그를 남길 때, info(), debug() 등의 메소드를 사용하는데 이 메소드들의 레벨과 로거의 레벨을 비교해 메시지의 레벨이 더 높거나 같을 때만 로그를 남기게 됩니다. 레벨의 순서는 TRACE < DEBUG < INFO < WARN < ERROR입니다.
2.2 Appenders and Layouts
Logback에서 로그의 출력 목적지는 appender로 불립니다. 콘솔, DB, 소켓 서버, 파일 등등 Appender가 존재합니다. 하나의 로그엔 하나 이상의 appender가 달라붙을 수 있습니다. 기본적으로 로거로 온 로깅 요청은 로거에 붙은 appender와 그 로거의 조상들에 붙은 appender 모두에게 전달됩니다. 옵션으로 조상 로거의 appender에는 보내지 않게 할 수도 있습니다. (로거의 additivity flag를 false로 하자)
Logback에서 layout은 로그를 포맷팅해줍니다. layout은 appender에 붙어 그 역할을 수행합니다. 표준 logback에 들어있는 PatternLayout은 사용자가 로그 포맷을 C언어의 printf와 비슷하게 정할 수 있게 해줍니다.
"%-4relative [%thread] %-5level %logger{32} - %msg%n"
//-> 176 [main] DEBUG manual.architecture.HelloWorld2 - Hello world.
3. Parameterized logging
다음과 같은 쓰기 방식은 비효율적입니다. 특히 레벨에 따라 비활성화된 로그의 경우에도 항상 문장을 생성해야 하므로 성능이 떨어집니다.
logger.debug("Entry number: " + i + " is " + String.valueOf(entry[i]));
logback-classic은 더 나은 방법을 제공합니다.
logger.debug("The new entry is {}. It replaces {}.", entry, oldEntry);
4. 로깅을할 때 내부에선 어떤 일이 일어날까?
사용자가 com.wombat이라는 로거의 info()를 호출했다고 가정해보자~
5. 성능
로깅에 대해 가장 많은 말이 오가는 주제 중 하나는 성능 문제입니다. 수천 개의 로그를 매 초마다 남긴다면 시간이 오래걸릴 수도 있을 것이에요. Logback에선 포맷팅하고 로그를 쓰는 작업이 그렇게 오래 걸리지 않습니다. 로컬 머신의 파일에 로그를 쓰느 경우 9~12 μs, 원격 DB에 저장하는 경우 X ms정도가 걸린다고 합니다.
'Log > Logback Manual' 카테고리의 다른 글
Chapter 6. logback layouts (0) | 2022.10.03 |
---|---|
Chapter 5. logback encoders (0) | 2022.10.03 |
Chapter 4. logback appenders (0) | 2022.10.02 |
Chapter 3. logback 설정 (0) | 2022.10.02 |
Chapter 1. logback 소개 (0) | 2022.09.29 |