본 문서는 https://logback.qos.ch/manual/introduction.html을 번역/요약/정리/사견 추가한 글입니다.
1. Logback 설정
일반적으로 코드의 4%가 로깅에 쓰인다고 합니다. 그렇기 때문에 이런 로그 코드들을 관리하는 도구가 필요합니다!!
Logback은 코드 내에서 혹은 코드 밖에서 XML, Groovy 문법을 사용해 설정할 수 있습니다.
(참고 : https://logback.qos.ch/translator/ 로 log4j.properties를 logback.xml로 바꿀 수도 있답니다.)
2. 자동 설정
logback을 설정하는 가장 쉬운 방법은 기본 설정(BasicConfigurator)을 이용하는 것입니다. logback-test.xml이나 logback.xml이 존재하지 않으면 logback은 최소한의 설정만 하는 BasicConfigurator를 호출합니다. 여기서는 루트 로거에 ConsoleAppender만 붙입니다. 출력 포맷은 %d{HH:mm:ss.SSS} [%thread] %-5level %logger{36} - %msg%n 입니다. 루트 로거의 레벨은 DEBUG로 설정됩니다.
<출력 예>
16:06:09.031 [main] INFO chapters.configuration.MyApp1 - Entering application.
16:06:09.046 [main] DEBUG chapters.configuration.Foo - Did it again!
16:06:09.046 [main] INFO chapters.configuration.MyApp1 - Exiting application.
3. 설정 파일 기본 문법
문법은 매우매우 유연하지만 기본적인 구조는 <configuration> 요소 안에 0개 이상의 <appender> 요소와 0개 이상의 <logger> 요소, 최대 하나의 <root> 요소가 순서대로 나오는 구조입니다.
3.1. tag 이름의 대소문자 구분
tag이름에서 첫 글자를 제외한 나머지 글자는 대소문자를 구분합니다. 즉, <xyz>는 </Xyz>로는 닫을 수 있지만 </xYZ>로는 닫을 수 없습니다. 그리고 일반적인 tag의 이름은 camelCase를 따릅니다.
3.2. <logger> 요소
<logger>를 이용해 로거를 설정할 수 있습니다. name 속성은 필수이며 level, additivity는 옵션입니다. <logger>는 0개 이상의 <appender-ref>를 가질 수 있습니다. 여기에 참조되는 appender는 로거에 붙게 됩니다.
3.3. <root> 요소
<root> 요소로 루트 로거를 설정할 수 있습니다. level이라는 하나의 속성만 지원합니다. 루트 로거는 이미 "ROOT"라는 이름이 있기 때문에 name이 필요없고 계층 구조의 가장 상단에 있기 때문에 additivity flag가 필요 없습니다. <root>도 <appender-ref>를 가질 수 있습니다.
3.4. Appenders 설정하기
<appender>는 name, class가 필수 속성입니다. name은 appender의 이름이고 class는 appender class를 뜻합니다. <appender>는 0개 이상의 <layout>, <encoder>, <filter>를 가질 수 있습니다. 이 3개의 요소 말고도 appender class의 JavaBean 속성에 상응하는 어떤 요소도 가질 수 있습니다. (예를 들어, RollingFileAppender는 rollingPolicy라는 필드를 가지고 있는데 그렇기 때문에 <rollingPolicy> 요소도 가질 수 있습니다.
<layout>, <encoder>도 이를 객체화하는 class 속성이 필요합니다. 그리고 <appender>와 같이 클래스의 필드에 상응하는 요소도 가질 수 있습니다.
3.5. context 이름 설정하기
모든 로거는 하나의 logger context에 종속됩니다. 그리고 이러한 context는 <contextName>을 이용해 이름을 지정할 수 있습니다. Logger context는 같은 대상에 로깅을 하는 여러 어플리케이션이 있을 때 이를 구분하기 쉽게 해줍니다.
<configuration>
<contextName>myAppName</contextName>
<appender name="STDOUT" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>%d %contextName [%t] %level %logger{36} - %msg%n</pattern>
</encoder>
</appender>
<root level="debug">
<appender-ref ref="STDOUT" />
</root>
</configuration>
3.6. 파일 inclusion
<include file="src/main/java/chapters/configuration/includedConfig.xml"/>
와 같이 다른 설정 파일을 불러올 수도 있습니다. 단, 타겟이 되는 파일은 반드시 <included>안에 모든 요소들을 넣어야 합니다. file말고도 resource, URL로도 불러올 수 있습니다.
예)
<included>
<appender name="includedConsole" class="ch.qos.logback.core.ConsoleAppender">
<encoder>
<pattern>"%d - %m%n"</pattern>
</encoder>
</appender>
</included>
4. 변수 치환
Logback 설정 파일도 변수를 가질 수 있습니다. 변수는 범위(scope)를 가지고 설정 파일 내뿐만 아니라 외부에도 정의할 수 있습니다. 변수 치환은 유닉스 쉘의 방식과 비슷합니다. ${}를 쓰는 것이지용. 그리고 참고로 HOSTNAME과 CONTEXT_NAME은 자동으로 설정되는 변수입니다.
4.1. 변수 선언
변수는 설정 파일 자신에 정의되거나 외부 파일/자원으로부터 가져올 수 있습니다. 설정 파일에서 변수를 선언하기 위해서는 <property>가 필요합니다. 1.0.7 버전 이후로는 <variable>로도 가능합니다.
<configuration>
<variable name="USER_HOME" value="/home/sebastien" />
<appender name="FILE" class="ch.qos.logback.core.FileAppender">
<file>${USER_HOME}/myApp.log</file>
<encoder>
<pattern>%msg%n</pattern>
</encoder>
</appender>
<root level="debug">
<appender-ref ref="FILE" />
</root>
</configuration>
다양한 변수 선언 방법의 한 예로 system properties가 있습니다. 어플리케이션을 실행할 때,
java -DUSER_HOME="/home/sebastien" MyApp2
처럼 system properties를 설정해주면 위 설정 파일에서 선언한 변수와 같은 역할을 할 수 있습니다.
외부 파일에서 변수를 가져오는 방법은 다음과 같습니다.
<variable file="src/main/java/chapters/configuration/variables1.properties" />
// USER_HOME=/home/sebastien in variables1.properties
파일 대신에 클래스 경로에 있는 자원을 참조할 수도 있습니다.
<variable resource="resource1.properties" />
4.2. 범위
변수는 local, context, system 범위 중 하나에 정의됩니다. Local scope가 기본입니다.
- Local scope - 설정 파일의 정의 부분부터 끝까지 존재합니다. 설정 파일이 파싱되고 실행될 때마다 변수는 새롭게 다시 정의됩니다.
- Context scope - context에 삽입되어 context가 끝나거나 clear되기 전까지 존재합니다. 그래서 모든 로깅 이벤트에서 사용 가능합니다. 더군다나 직렬화되어 remote host로 전송되는 로깅 이벤트에도 유효합니다.
- System scope - JVM의 system properties에 삽입되어 JVM이 끝나거나 clear되기 전까지 존재합니다.
변수 치환이 일어나면 local, context, system 순으로 변수를 찾아본 뒤 마지막으로 운영체제의 환경변수를 찾아봅니다.
<property> 요소의 scope 속성, <define> 요소, <insertFromJNDI> 요소로 범위를 지정할 수 있습니다.
(범위의 차이가 딱히 와닿지가 않음..)
4.3. 변수의 기본값
변수 치환시 참조되는 변수가 선언되어있지 않을 때 사용되는 기본값을 지정할 수 있습니다. 예를 들어, ${id:-32}는 id란 변수가 없으면 32를 쓰라는 뜻입니다. ${id:-${userid}}와 같은 중첩도 가능합니다.
5. 조건부 처리
개발자는 종종 development, testing, production과 같은 다양한 환경을 위한 설정 파일을 만듭니다. 이러한 설정 파일들은 몇 군데만 다르고 대부분 동일합니다. 이럴 때 <if>, <then>, <else>를 사용할 수 있습니다.
<!-- if-then-else form -->
<if condition="some conditional expression">
<then>
...
</then>
<else>
...
</else>
</if>
조건식은 context properties와 system properties만 사용가능한 자바 표현식입니다. property(), p() 메소드는 인자로 주는 문자열에 해당하는 property를 반환합니다. 없으면 빈 문자열을 반환합니다. 그 외에도 isDefined(), isNull() 등의 메소드를 사용할 수 있습니다. 다음은 한 예입니다.
<if condition='property("HOSTNAME").contains("torino")'>
설정 파일 어디에서도 사용 가능하고 중첩으로도 사용할 수 있지만 XML 문법 특성상 이런 조건부 처리를 남발하면 파일이 읽기 힘들어질 수 있습니다.
'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 2: logback 구조 (0) | 2022.10.01 |
Chapter 1. logback 소개 (0) | 2022.09.29 |