Logback은 많이 사용됟는 log4j 프로젝트의 후속 프로젝트로, log4j가 중단되는 부분부터 시작한다.
Logback은 기존의 모든 로깅 시스템보다 빠르고 설치 공간도 더 작다.
Logback은 다른 로깅 시스템에 없는 고유하고 유용한 기능을 제공한다.
Logback-classic 모듈은 classpath에 logback-classic.jar뿐만 아니라 slf4j-api.jar와 logback-core.jar도 필요하다.
spring-boot-starter-logging 스타터에는 로깅을 위한 여러 라이브러리들이 추가되어 있어서 따로 추가할 필요가 없다. spring-boot-starter-logging 스타터도 spring-boot-starter-web 스타터에 포함되어있다.
<dependency>
<groupId>org.springframework.boot</groupId>
<artifactId>spring-boot-starter-web</artifactId>
</dependency>
SLF4J API 라이브러리에 정의한 Logger와 LoggerFactory 클래스들을 Import하여 시작한다.
package chapters.introduction;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class HelloWorld1 {
public static void main(String[] args) {
Logger logger = LoggerFactory.getLogger("chapters.introduction.HelloWorld1");
logger.debug("Hello world.");
}
}
LoggerFactory 클래스의 getLogger 전역 매서드로 Logger 인스턴스를 반환하여 사용한다.
Logback은 3가지의 주요 클래스들(Logger, Appender, Layout)로 구성된다. 이 3가지의 클래스들은 함께 작동되어, 메시지 유형과 수준에 따라 메시지를 기록할 수 있게 하고 운영중에 메시지들이 어떻게 표현되고 어디에 보고될지 제어한다. Logger 클래스는 logback-classic 모듈에 속하며, Appender와 Layout 인터페이스들은 logback-core에 속한다.
일반적인 System.out.println에 반해 로깅 API의 가장 중요한 장점은 다른 로그문장을 아무런 제약없이 기록하면서 특정 로그 문장을 비활성화 시킬 수 있다는 점이다. 이 기능은 모든 로깅 문장들의 공간이 개발자가 선택한 일부 기준에 따라 분류된다고 가정한다. logback-classic 모듈에서 이 분류는 로거의 고유한 부분이다. 모든 로거는 로거를 생성하고 로거들을 계층같은 트리로 배치하는 LoggerContext에 연결되어 있다.
Logger는 이름있는 객체이며, 대소문자를 구분하고 계층 이름 지정 규칙을 따른다.
Logger rootLogger = LoggerFactory.getLogger(org.slf4j.Logger.ROOT_LOGGER_NAME);
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);
}
로거를 기반으로 로깅 요청을 선택적으로 활성화하거나 비활성화하는 기능은 일부일 뿐이다. Logback을 사용하면 로깅 요청을 여러 대상으로 기록할 수 있다. 출력 대상을 "Appender"라고 하며 console, file, 원격 소켓 서버, MySQL, PostgreSQL, Oracle, 기타 데이터베이스, JMS 그리고 원격 UNIX Syslog 데몬이 있다. 하나의 로거에 둘 이상의 Appender를 연결 할 수 있다.
사용자는 출력 대상뿐만 아니라 출력 형식도 커스텀화하기를 원한다. Layout과 Appender를 연결하여 이를 수행할 수 있다. "Layout"은 사용자의 희망에 따라 로깅 요청을 포맷하고 "Appender"는 포맷된 출력을 목적지로 보내는 역활을 담당한다. 표준 Logback 분배 방식의 일부인 PatternLayout을 사용하면 C언어 printf함수와 유사한 변환 패턴에 따라 출력 형식을 지정할 수 있다.
logback-test.xml이나 logback.xml 구성 파일이 없다면, Logback 은 최소한의 구성으로 설정하는 BasicConfigurator를 기본적으로 주입할 것이다. 이 최소 구성은 Root Logger에 연결된 ConsoleAppender로 구성된다. 출력은 PatternLayoutEncoder를 사용하여 '%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n' 패턴으로 설정된다. 또한, 기본적으로 Root Logger가 DEBUG 수준으로 할당된다.
Logback은 classpath에서 logback-test.xml이나 logback.xml 파일을 찾을 수 있다면 이 파일로 구성하려고 한다. 다음은 BasicConfigurator가 구성하는 내용과 동일한 구성이다.
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<!-- encoders are assigned the type
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="debug">
<appender-ref ref="STDOUT" />
</root>
</configuration>
Logger의 수준을 설정하려면 다음과 같이 구성한다.
<configuration>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<logger name="chapters.configuration" level="INFO" />
<logger name="chapters.configuration.Foo" level="DEBUG" />
<root level="DEBUG">
<appender-ref ref="STDOUT" />
</root>
</configuration>
출력을 파일로 하고 싶다면 FileAppender을 추가하면 된다.
<configuration>
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>testFile.log</file>
<append>true</append>
<!-- set immediateFlush to false for much higher logging throughput -->
<immediateFlush>true</immediateFlush>
<!-- encoders are assigned the type
ch.qos.logback.classic.encoder.PatternLayoutEncoder by default -->
<encoder>
<pattern>%-4relative [%thread] %-5level %logger{35} - %msg%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="FILE" />
</root>
</configuration>
FileAppender를 상속하는 RollingFileAppender는 로그 파일들을 rollover한다. RollingFileAppender는 특정 조건이 만족되면 log 파일을 다른 파일로 바꾼다.
<configuration>
<appender name="FILE" class="ch.qos.logback.core.RollingFileAppender">
<file>testRollingFile.log</file>
<rollingPolicy class="ch.qos.logback.core.rolling.SizeAndTimeBasedRollingPolicy">
<!-- rollover daily -->
<fileNamePattern>mylog-%d{yyyy-MM-dd}.%i.txt</fileNamePattern>
<maxFileSize>100MB</maxFileSize>
<maxHistory>30</maxHistory>
<totalSizeCap>20GB</totalSizeCap>
</rollingPolicy>
<encoder>
<pattern>%msg%n</pattern>
</encoder>
</appender>
<root level="DEBUG">
<appender-ref ref="FILE" />
</root>
</configuration>