

Log4j는 Java 영역에서 로그를 쉽고 편리하게 기록할 수 있도록 도와주는 라이브러리이다.
Log4j2는 Log4j의 2 이상의 버전을 부르고, 이전에 발생한 Log4j 보안 이슈 때문에 Java 7 이하인 경우에는 2.13.3, Java 8 이상인 경우에는 2.17 이상의 버전을 사용하는 것이 좋다.
2.14 버전에서 문제가 발생했기에 못해도 2.15 이상의 버전을 사용하는 것이 좋고, 왠만하면 최신 버전을 사용하자.
Logback은 현재 Spring에서 기본으로 지원하는 Logger이다. Log4j 이후에 개발되어 Logback이 기본으로 등록되었지만, 이후에 Log4j2가 나오면서 Log4j2가 더 선호되는 경향이 있다.
Log4j2는 대부분의 상황에서 Logback보다 더 빠른 속도를 가지고 있다고 한다.
Slf4j는 다양한 Logger 구현체들 대신 호출되는 인터페이스 역할을 하는 라이브러리이다.
Slf4j를 사용하면 직접 Logback이나 Log4j2를 호출하지 않고 Slf4j를 호출하는 것 만으로도 간단하게 로그를 찍을 수 있다. 일종의 Bridge 역할이다.
Log4j2와 Slf4j, lombok 조합이면 클래스에 @Slf4j 어노테이션 하나 붙이는 것 만으로도 로그를 사용할 수 있다.
Log4j를 사용하기 위해서는 dependency를 추가해야 한다. 본 글에서는 Gradle 기준으로 설명한다.
SpringBoot를 사용중이라면 SpringBoot에서 지원해주는 Log4j2 라이브러리가 존재한다. build.gradle에 해당 라이브러리를 추가해주면 된다.
dependencies {
...
// log4j2
implementation 'org.springframework.boot:spring-boot-starter-log4j2'
...
}
Spring boot를 사용하지 않는다면, log4j-api와 log4j-core를 추가해주면 된다.
dependencies {
...
// log4j2
implementation 'org.apache.logging.log4j:log4j-core:2.23.1'
implementation 'org.apache.logging.log4j:log4j-api:2.23.1'
...
}
Spring에서 기본적으로 사용하는 logback을 의존성 제거를 해줘야 한다. 그렇지 않으면 Slf4j에 구현체가 2개 이상이 등록되어 오류가 발생한다.
configurations {
all {
exclude group: 'org.springframework.boot', module: 'spring-boot-starter-logging'
}
...
}
build.gradle을 설정하는 김에 slf4j도 추가해준다.
dependencies {
...
// slf4j
implementation 'org.slf4j:slf4j-api:2.0.13'
...
}
아래에서 log4j2 설정파일을 yaml 파일로 만든 예정인데, 이를 위한 의존성도 추가해준다.
dependencies {
...
// log4j2-yaml
implementation 'com.fasterxml.jackson.dataformat:jackson-dataformat-yaml:2.16.1'
...
}
그리고 buid.gradle reload를 시켜준다.
보통 log4j2 설정을 할 때, xml로 주로 설정을 한다.
하지만 나는.. xml 태그가 귀찮으므로 yaml 파일로 만들어서 설정하려고 한다.
resources 폴더 바로 아래에 log4j2.yml이라고 파일을 만든다.

만약 실행 환경, 프로필 별로 설정 파일을 별도로 만들거나, log4j2.yml을 resources 바로 아래가 아닌 다른 곳에 위치시키던가 하려면 application.yml에 해당 위치를 명시시켜줘야 한다.
logging:
config: classpath:log4j2.yml
일단 내가 설정한 log4j2.yml 내용을 아래와 같다.
Configutation:
name: Default
status: warn
Properties:
Property:
- name: log-path
value: "logs"
- name: pattern
value: "%d %highlight{[%-5level]} [%style{%t}{bright,blue}] %style{%C}{bright,yellow}: %msg%n%throwable"
- name: charset-UTF-8
value: "UTF-8"
Appenders:
Console:
name: Console_Appender
target: SYSTEM_OUT
PatternLayout:
charset: ${charset-UTF-8}
pattern: ${pattern}
disableAnsi: false
File:
name: File_Appender
fileName: ${log-path}/logfile.log
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}.gz"
PatternLayout:
charset: ${charset-UTF-8}
pattern: ${pattern}
disableAnsi: false
Policies:
SizeBasedTriggeringPolicy:
size: 200 KB
DefaultRollOverStrategy:
max: 30
Loggers:
Root:
level: warn
AppenderRef:
- ref: Console_Appender
- ref: RollingFile_Appender
Logger:
- name: com.demo.example
additivity: "false"
level: debug
AppenderRef:
- ref: Console_Appender
- ref: RollingFile_Appender
설정 파일을 구분하는 이름
내부 이벤트에 대한 로그 레벨
로그 설정의 속성을 정의
해당 설정에서 속성을 미리 정의해서 변수처럼 사용 가능
name 속성이 키, value 속성이 값으로 생각하면 되고, 예시처럼 - 를 사용해서 여러 개를 지정할 수 있다.
Appenders는 로그 메세지를 출력하는 방법을 정의하는 곳이다.
Appender의 종류로는 Console, File, RollingFile 등이 있다. 주로 Console, RollingFile이 많이 사용된다.
PatternLayout은 출력 결과 포맷을 지정하는 값이다.
자세한 문법은 공식 홈페이지를 참조
클래스 별로 로그를 찍을지 설정하는 곳이다.
Root는 필수이다. 기본 설정을 이곳에 한다.
추가적으로 설정하는 곳이다.
추가적인 정보는 공식 홈페이지 매뉴얼을 참고하자.
YAML 작성 시 주의 할 점
yaml 1.2 버전에서는 기존 1.1 버전에 의해 boolean 타입이 엄격하게 허용된다고 한다.
따라서 boolean 타입은 따옴표로 감싸서 'true' / 'false' 로 작성해야 한다.
만약 log level을 OFF 로 지정하고 싶은 경우에도 "OFF"로 적어줘야 오류가 발생하지 않는다.
설정을 다 하고 나면 Java Class에 @Slf4j 어노테이션을 사용한 후에 로그 사용이 가능하다.
log.debug("로그내용");
log.info("변수 사용 {}", stringVal);
위와 같은 형식으로 사용 가능하다.
간단한 컨트롤러를 만들어서 로그가 정상적으로 찍히는지 테스트를 해보려고 한다.
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Controller;
import org.springframework.web.bind.annotation.GetMapping;
@Controller
@Slf4j
public class LogTest {
@GetMapping("/log")
public String logTest() {
log.trace("logtest - trace");
log.debug("logtest - debug");
log.info("logtest - info");
log.warn("logtest - warn");
log.error("logtest - error");
log.error("logtest - {}", "ERROR");
return "index";
}
}

Mybatis를 통해 DB 연결을 하면 기본적으로 로그는 나온다.
하지만
SELECT * FROM USER WHERE USER_ID = ? AND USER_NAME = ?
이런식으로 찍히기 때문에 정확한 쿼리를 보기가 어렵다. 이를 위해 Log4jdbc를 사용한다.
일단 Log4jdbc 설정에 앞서, db 설정이 되어 있는 상태에서 시작한다.
build.gradle에 dependency를 추가하자.
dependencies {
...
// log4jdbc
implementation 'org.bgee.log4jdbc-log4j2:log4jdbc-log4j2-jdbc4.1:1.16'
...
}
DB 접속 정보가 적힌 application.yml (또는 properties) 파일에서 driver-class-name와 url을 수정해준다.
spring:
datasource:
driver-class-name: org.mariadb.jdbc.Driver
url: jdbc:mariadb://localhost:8080/test?CharacterEncoding=UTF-8
username: user
password: 1111
spring:
datasource:
driver-class-name: net.sf.log4jdbc.sql.jdbcapi.DriverSpy
url: jdbc:log4jdbc:mariadb://localhost:8080/test?CharacterEncoding=UTF-8
username: user
password: 1111
resources 폴더 아래에 log4jdbc.log4j2.properties 파일을 추가하고 안에 아래와 같이 내용을 추가한다.
log4jdbc.spylogdelegator.name=net.sf.log4jdbc.log.slf4j.Slf4jSpyLogDelegator
log4jdbc.dump.sql.maxlinelength=0
log4j2가 정상적으로 log4jdbc의 쿼리 로그를 출력할 수 있도록, loggers 부분에 아래와 같이 logger 내용을 추가한다.
Loggers:
Root:
level: "warn"
AppenderRef:
- ref: Console_Appender
- ref: RollingFile_Appender
Logger:
- name: com.demo.example
additivity: "false"
level: "debug"
AppenderRef:
- ref: Console_Appender
- ref: RollingFile_Appender
# 이 아래 부분부터 추가
- name: jdbc.connection
additivity: "false"
level: "warn"
AppenderRef:
- ref: Console_Appender
- ref: RollingFile_Appender
- name: jdbc.audit
additivity: "false"
level: "off"
AppenderRef:
- ref: Console_Appender
- ref: RollingFile_Appender
- name: jdbc.resultset
additivity: "false"
level: "warn"
AppenderRef:
- ref: Console_Appender
- ref: RollingFile_Appender
- name: jdbc.sqlonly
additivity: "false"
level: "off"
AppenderRef:
- ref: Console_Appender
- ref: RollingFile_Appender
- name: jdbc.resultsettable
additivity: "false"
level: "off"
AppenderRef:
- ref: Console_Appender
- ref: RollingFile_Appender
- name: jdbc.sqltiming
additivity: "false"
level: "debug"
AppenderRef:
- ref: Console_Appender
- ref: RollingFile_Appender

참고
https://adjh54.tistory.com/388
https://velog.io/@osh8242/SpringBoot에-Log4jdbc-사용하기