[springboot] Spring Boot project 시작하기, log4j2 + yml
이번 포스팅에서는 Spring Boot Project 에 log4j2 를 설정해보겠습니다. 프로젝트를 생성하는 방법은 이전 포스트를 참고해주시길 바랍니다.
구현 환경
종류 | 버전 |
---|---|
OS | M1 Mac(Monterey 12.4) |
IDE | Intellij(2022.1.2) |
Java | jdk17 (temurin) |
Spring | 2.7.5 |
Gradle | 7.6.1 |
라이브러리 가져오기
(선택)기존 logging 라이브러리 제외하기
log4j2 라이브러리를 가져오기 전, 스프링에서 제공하는 기본 라이브러리는 사용하지 않을 예정이므로 제외합니다. 선택 사항이지만 사용하지 않은 라이브러리를 굳이 남겨둘 이유는 없으니 제외시키는걸 추천드립니다.
configurations {
all{
exclude module: 'spring-boot-starter-logging'
}
}
log4j2 라이브러리 가져오기
다음으로는 log4j2와 slf4j를 위한 라이브러리를 가져오겠습니다. slf4j는 slf4j-impl에 포함되어있으므로 따로 가져오진 않겠습니다. 버전은 작성일 기준 2.17.1 이상을 가져오시길 바랍니다. log4j 취약점 논란이 있었기 때문에 maven repository에서 가져오실 땐 꼭 취약점이 발견되지 않은 버전을 가져오시길 바랍니다.
spring-boot-starter-log4j2
를 통해 가져오지 않는 이유는 maven repository 사이트의 표기와 달리 2.17.0 버전을 가져오기 때문입니다. 취약점 문제가 없다면 spring-boot-starter-logj4j2
로 가져오는게 깔끔하니 추천드립니다.
dependencies {
implementation group: 'org.apache.logging.log4j', name: 'log4j-core', version: '2.17.2'
implementation group: 'org.apache.logging.log4j', name: 'log4j-api', version: '2.17.2'
implementation group: 'org.apache.logging.log4j', name: 'log4j-slf4j-impl', version: '2.17.2'
}
yml 설정을 위한 jackson-dataformat-yaml 라이브러리 가져오기
log4j2 설정은 일반적으로 .xml 로 관리해왔지만 이번 프로젝트는 .yml 로 관리해보도록 하겠습니다. .yml 으로 log4j2 설정을 관리하기 위해선 관련 라이브러리를 가져올 필요가 있습니다. 아래 라이브러리를 dependencies 에 포함하도록 합니다.
implementation group: 'com.fasterxml.jackson.dataformat', name: 'jackson-dataformat-yaml', version: '2.13.1'
필요한 라이브러리를 전부 가져왔다면 이제 프로젝트 환경에 맞춰서 설정하는 일만 남았습니다.
log4j2.yml 생성 및 application.yml 설정
application.yml 설정
log4j2 파일을 생성하기 전에 application.yml 에 생성할 파일의 경로를 정의합니다. 파일을 생성한 후에 정의해도 상관없습니다.
logging:
config: classpath:log4j2.yml
log4j2.yml 파일 생성
log4j2.yml 파일을 생성합니다. 위치는 src/main/resources/log4j2.yml 입니다.
log4j2.yml 예시 (설명은 하단 참고)
생성한 파일에 예시 내용을 붙여넣습니다. 그대로 사용해도 상관없지만 본인의 상황에 맞게 커스텀하시길 바랍니다.
Configutation:
name: Default
status: warn
Properties:
Property:
- name: "log-path"
value: "./logs"
- name: "pattern"
value: "%highlight{[%-5level]} %d{yyyy-MM-dd HH:mm:ss.SSS} [%t][%F] %c{1} - %msg%n"
- name: "charset-UTF-8"
value: "UTF-8"
Appenders:
Console:
name: Console_Appender
target: SYSTEM_OUT
PatternLayout:
charset: ${charset-UTF-8}
pattern: ${pattern}
disableAnsi: false
RollingFile:
name: RollingFile_Appender
fileName: ${log-path}/rollingfile.log
filePattern: "logs/archive/rollingfile.log.%d{yyyy-MM-dd-hh-mm}_%i.gz"
PatternLayout:
charset: ${charset-UTF-8}
pattern: ${pattern}
Policies:
SizeBasedTriggeringPolicy:
size: "200KB"
TimeBasedTriggeringPolicy:
interval: "1"
DefaultRollOverStrategy:
max: "30"
fileIndex: "max"
Loggers:
Root:
level: debug
AppenderRef:
- ref: Console_Appender
- ref: RollingFile_Appender
Logger:
name: example.demospringboot
additivity: false
level: debug
AppenderRef:
- ref: Console_Appender
- ref: RollingFile_Appender
(참고) log4j2.yml 설정 구조
Configuration
로그를 설정하기 위한 최상위 태그입니다. 하위에는 다음과 같은 태그를 삽입할 수 있습니다.
항목 | 설명 |
---|---|
Properties | 해당 파일에서 사용할 수 있는 공통 변수를 정의합니다. name, log layout pattern 등을 정의하는 것이 추후 관리에 편합니다. |
Appenders | 로그의 패턴과 저장 패턴 등을 설정할 수 있습니다. |
Loggers | 출력하는 로그 범위를 지정할 수 있습니다. 설정에 따라 로그를 노출시키거나 생략할 수 있습니다. |
### Properties | |
```yaml | |
Properties: | |
Property: |
- name: "log-path"
value: "./logs"
| tag | description |
|:-----:|:---------------------------------|
| name | 호출할 때 사용할 수 있는 property 의 이름입니다. |
| value | 해당 property 를 호출했을 경우 실제 값입니다. |
### Layout Pattern
로그에 표시될 정보와 순서를 정의할 수 있습니다. 각 태그에 대한 설명은 다음과 같습니다.
```yaml
"%highlight{[%-5level]} %d{yyyy-MM-dd HH:mm:ss.SSS} [%t][%F] %c{1} - %msg%n"
Format | description |
---|---|
%c, %logger | 해당 로그를 쓰는 로거의 이름 |
%C, %Class | 해당 로그를 요청한 클래스 이름 |
%d, %date | 해당 로그가 발생한 시간 |
%enc, %encoding | 특정 언어에서의 출력을 위한 문자 인코딩 |
%ex, %exception, %throwable | 예외로그, 길이 설정이 가능 |
%F, %file | 해당 로그가 발생한 클래스 파일명 |
%l, %location | 해당 로그가 발생한 클래스명, 메소드명 |
%L, %line | 해당 로그가 발생한 라인 번호 |
%m, %msg, %message | 로그문에 전달된 메세지 |
%n | 줄바꿈 |
%p, %level | 로그 레벨 |
%r, %relative | 로그 처리시간 |
%t, %thread | 해당 로그가 발생한 스레드 명 |
%style{pattern}{ANSI style} | ANSI 를 사용하여 특정 패턴을 스타일링 |
%highlight{pattern}{style} | 로그 레벨명을 ANSI 색으로 하이라이트 |
logging level
지정한 로깅 레벨 이상의 로그만 출력 됩니다. INFO 로 지정할 경우 DEBUG 와 TRACE 레벨의 로그는 생략됩니다.
- FATAL
- ERROR
- WARN
- INFO
- DEBUG
- TRACE
Appenders
name | description |
---|---|
Console | 콘솔창에 출력될 로그를 설정 합니다. |
File | 파일 형태로 저장될 로그를 설정합니다. |
RollingFile | 특정 트러거에 따라 파일로 백업할 로그를 설정합니다. |
Appenders:
Console:
name: Console_Appender
target: SYSTEM_OUT
PatternLayout:
charset: ${charset-UTF-8}
pattern: ${pattern}
disableAnsi: false
- name: loggers 에서 호출할 이름을 정의합니다.
- target: 출력 방식입니다. Console 에서 사용됩니다.
- PatternLayout
- charset: 인코딩 방식입니다.
- pattern: 출력 레이아웃 방식입니다. 사용자 정의에 맞게 로그가 출력됩니다.
- disableAnsi: 색상 변경 여부를 지정합니다. true 일 경우 콘솔의 색이 변하지 않습니다.
패턴과 강조 색이 잘 반영되었다면 아래 화면과 같이 출력됩니다.
RollingFile:
name: RollingFile_Appender
fileName: ${log-path}/rollingfile.log
filePattern: "logs/archive/rollingfile.log.%d{yyyy-MM-dd-hh-mm}_%i.gz"
PatternLayout:
charset: ${charset-UTF-8}
pattern: ${pattern}
Policies:
SizeBasedTriggeringPolicy:
size: "200KB"
TimeBasedTriggeringPolicy:
interval: "1"
- fileName: 파일이 저장될 경로와 파일명입니다.
- filePattern: 트리거에 따라 백업될 파일의 경로와 이름입니다. layout pattern 을 적용하여 파일 중복을 예방합니다.
- Policies: RollingFile appender 에서 지정할 트리거 항목입니다.
- OnStartupTriggeringPolicy: jvm 을 시작할 경우 트리거가 발동합니다.
- TimeBasedTriggeringPolicy: 특정 시간마다 트리거가 발동합니다. filePattern 에 지정한 단위로 롤링됩니다. (mm: 분 단위)
- interval: 설정한 시간 간격마다 로그를 write 합니다. 기본값은 1입니다.
- SizeBasedTriggeringPolicy: 파일 사이즈를 트리거로 지정합니다.
- size: 설정한 파일의 용량을 초과할 경우 트리거가 발동합니다.
- CronTriggeringPolicy: 크론 표현식을 기반으로 트리거가 발동합니다.
DefaultRollOverStrategy:
max: "30"
fileIndex: "max"
- DefaultRolloverStrategy: 날짜 패턴과 파일 패턴을 이용하여 파일을 저장합니다.
- fileIndex: max 로 지정할 경우 값이 높은 index 가 최신 파일이 됩니다.(내림차순) min 으로 지정할 경우 작은 index 가 최신 파일이 되며 기존 파일들을 rename 하는 방식입니다.(오름차순)
- min: index count 의 최소값을 지정합니다. 기본값은 1 입니다.
- max: index count 의 최대값을 지정합니다. 최대값에 도달할 경우 오래된 파일을 삭제합니다. 기본값은 7 입니다.
- compressionLevel: 0~9까지의 정수값, 0은 압축하지않고, 1은 최고 속도, 9는 최고 압축 zip 파일만 가능합니다.
- tempCompressedFilePattern: 압축하는 동안의 파일 이름 패턴입니다.
Loggers
Loggers:
Root:
level: debug
AppenderRef:
- ref: Console_Appender
- ref: RollingFile_Appender
Logger:
name: example.demospringboot
additivity: false
level: debug
AppenderRef:
- ref: Console_Appender
- ref: RollingFile_Appender
- Root: 기본 설정값을 정의합니다. logger 에 따로 지정하지 않은 경우 Root 규칙을 따릅니다. 필수로 설정해야 합니다.
- level: 로그의 레벨을 지정합니다.
- AppenderRef: 해당 설정을 적용할 Appenders 를 지정합니다.
- Logger: Root 의 설정을 따르지 않는 logger 를 지정합니다. 하나 이상 설정할 수 있습니다.
- name: 설정한 logger name 이 호출한 logger 으로 시작한다면 정의한 level 규칙을 따릅니다.
- additivity: logger 중복 여부를 지정합니다. false 로 지정할 경우 중복되지 않습니다.
테스트
프로젝트에 log4j2 가 제대로 적용됐는지 간단하게 확인해보겠습니다. 실행 가능한 코드와 결과는 아래와 같습니다.
테스트 코드 전문
package org.acj.env;
import org.junit.jupiter.api.Test;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class Log4j2Test {
private final Logger logger = LoggerFactory.getLogger(this.getClass());
@Test
public void log4j2LoggerTest(){
System.out.println("안녕 난 println이야");
logger.info("안녕 난 logger야");
}
}
pacakage 는 실제 파일 경로로 설정하시면 됍니다.
결과
참고
https://logging.apache.org/log4j/2.x/manual/configuration.html