Java 로깅 라이브러리 종류 / lombok 및 slf4j를 이용한 log4j2 사용 방법

System.out.println 대신 Logger 사용 이유
System.out.println은 IO 자원을 사용하기 때문에 리소스를 많이 사용하여 성능 저하가 올 수 있습니다.
그래서 System.out.println는 운영 반영 시 직접 전부 삭제하고 올려야 하기 때문에,
로그 레벨에 따라 출력 여부를 설정할 수 있고 로깅 성능이 좋은 Logger를 사용하여 개발하는 것이 좋습니다.


Java 로깅 라이브러리 종류

log4j

초기에 많은 Java 어플리케이션에서 사용되었으나, 보안 취약점 문제로 인해 사용이 줄어들고 있습니다.

log4j2

log4j의 보안 취약점 문제를 보완하고 성능을 향상시킨 log4j2 사용이 권장되고 있습니다.
Spring, SpringBoot, egovFramework 모두 log4j2 사용이 가능합니다.

logback

log4j의 후속 프로젝트로 개발되어 향상된 성능을 제공합니다.
Spring Boot는 기본적으로 logback을 사용하여 로깅을 구성합니다.


log4j 사용 예시

import org.apache.log4j.Logger;

public class 클래스명 {
  Logger log = Logger.getLogger(this.getClass());

  public void 함수명() {
    log.info("test");
  }

이렇게 log4j를 직접 import 하면, 다른 로깅 라이브러리로 변경 시 모든 Java 파일을 수정해줘야 합니다.
특정 로깅 라이브러리에 종속되는 것을 방지하기 위해서 slf4j를 통해 사용하는 것이 좋습니다.


slf4j를 통해 log4j2 사용 방법

slf4j란?
slf4j는 다양한 로깅 라이브러리들과의 인터페이스입니다.

log4j2 추가

implementation 'org.bgee.log4jdbc-log4j2:log4jdbc-log4j2-jdbc4.1:1.16'

build.gradle 파일에 log4j2 라이브러리 의존성을 추가합니다.

slf4j 추가

Gradle 사용 시

implementation 'org.slf4j:slf4j-api:1.7.32'
implementation 'org.slf4j:slf4j-simple:1.7.32'

build.gradle 파일에 slf4j 라이브러리 의존성을 추가합니다.

Maven 사용 시

<dependency>
    <groupId>org.slf4j</groupId>
    <artifactId>slf4j-api</artifactId>
    <version>1.7.25</version>
</dependency>

pom.xml 파일에 slf4j 라이브러리 의존성을 추가합니다.

slf4j 사용 예시

import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

public class 클래스명 {
  Logger log = LoggerFactory.getLogger(this.getClass());

  public void 함수명() {
    log.info("test");
    log.debug("디버깅 메세지 ::: " + 변수);
  }

slf4j를 통해서 log를 작성하면, 다른 로깅 라이브러리로 변경 시 코드 변경 작업이 필요 없습니다.


lombok으로 slf4j 사용 방법

lombok이란?
lombok은 코드를 더 간결하게 만들어주는 라이브러리입니다.

lombok 추가

Gradle 사용 시

compileOnly 'org.projectlombok:lombok'
annotationProcessor 'org.projectlombok:lombok'

build.gradle 파일에 lombok 라이브러리 의존성을 추가합니다.

Maven 사용 시

<dependency>
  <groupId>org.projectlombok</groupId>
  <artifactId>lombok</artifactId>
  <version>1.18.24</version>
  <scope>provided</scope>
</dependency>

pom.xml 파일에 lombok 라이브러리 의존성을 추가합니다.

lombok으로 slf4j 사용 예시

import lombok.extern.slf4j.Slf4j;

@Slf4j
public class 클래스명 {

  public void 함수명() {
    log.info("test");
    log.debug("디버깅 메세지 ::: " + 변수);
  }

lombok을 사용하여 클래스에 @Slf4j 어노테이션을 달아주면,
Logger 객체를 직접 생성하지 않아도 롬복이 자동으로 생성하니까 사용이 간결해집니다.


SpringBoot logback 사용 방법

logback.xml 파일 생성

<?xml version="1.0" encoding="UTF-8"?>
<!--
jdbc.sqlonly    : Logs only SQL
jdbc.sqltiming  : Logs the SQL, post-execution, including timing execution statistics
jdbc.audit      : Logs ALL JDBC calls except for ResultSets
jdbc.resultset  : all calls to ResultSet objects are logged
jdbc.connection : Logs connection open and close events
-->
<configuration>
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <!-- By default, encoders are assigned the type ch.qos.logback.classic.encoder.PatternLayoutEncoder -->
        <encoder>
            <pattern>%d{yyyyMMdd HH:mm:ss.SSS} [%thread] %green(%-3level) %blue(%logger{5}) - %msg %n</pattern>
        </encoder>
    </appender>

    <appender name="FILE" class="ch.qos.logback.core.rolling.RollingFileAppender">
        <file>/tmp/access.log</file>
        <rollingPolicy class="ch.qos.logback.core.rolling.TimeBasedRollingPolicy">
            <fileNamePattern>/tmp/access-%d{yyyy-MM-dd}.log</fileNamePattern>
            <maxHistory>30</maxHistory>
        </rollingPolicy>

        <encoder>
            <Pattern>%d{HH:mm} %-5level %logger{36} - %msg%n</Pattern>
        </encoder>
    </appender>

    <logger name="org.springframework" level="INFO"/>
    <logger name="org.mybatis.spring" level="INFO"/>
    <logger name="kr.co.chunjae" level="DEBUG"/>

    <logger name="kr.co.chunjae.menu" level="OFF"/>
    <logger name="kr.co.chunjae.code" level="INFO"/>


    <logger name="jdbc" level="OFF" /> <!-- 커넥션 open close 이벤트를 로그로 남긴다. -->
    <logger name="jdbc.connection" level="OFF" /> <!-- SQL문만을 로그로 남기며, PreparedStatement일 경우 관련된 argument 값으로 대체된 SQL문이 보여진다. -->
    <logger name="jdbc.sqlonly" level="OFF" /> <!-- SQL문과 해당 SQL을 실행시키는데 수행된 시간 정보(milliseconds)를 포함한다. -->
    <logger name="jdbc.sqltiming" level="OFF" /> <!-- ResultSet을 제외한 모든 JDBC 호출 정보를 로그로 남긴다. 많은 양의 로그가 생성되므로 특별히 JDBC 문제를 추적해야 할 필요가 있는 경우를 제외하고는 사용을 권장하지 않는다. -->
    <logger name="jdbc.audit" level="OFF" /> <!-- ResultSet을 포함한 모든 JDBC 호출 정보를 로그로 남기므로 매우 방대한 양의 로그가 생성된다. -->
    <logger name="jdbc.resultset" level="OFF" /> <!-- SQL 결과 조회된 데이터의 table을 로그로 남긴다. -->
    <logger name="jdbc.resultsettable" level="OFF" />
    <logger name="log4jdbc.debug" level="INFO" />


    <!--   <logger name="jdbc.resultsettable" level="DEBUG" additivity="false">>  -->
    <!--     <appender-ref ref="STDOUT" /> -->
    <!--   </logger>   -->

    <root level="INFO">
        <appender-ref ref="CONSOLE" />
        <appender-ref ref="FILE" />
    </root>

</configuration>

resources 폴더 안에 logback.xml 파일 생성 후 톰캣 재시작하면 즉시 적용됩니다.
만약 우선순위가 더 높은 application.properties 또는 application.yml 파일에 동일한 패키지에 대한 로그 레벨 설정이 있다면 적용되지 않습니다.

Leave a comment