본문 바로가기
별밤 일지/개발

[Spring] Logback 을 활용한 로깅하기

by 별밤 에디터 2024. 1. 30.

 

로그의 중요성

아래는 우리가 스프링부트를 실행하면 흔히 볼 수 있는 것이다.

 

.   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v2.5.2)

2024-01-28 22:19:06.122  INFO 11216 --- [           main] c.s.t.TourApiProjectApplication          : Starting TourApiProjectApplication using Java 11.0.19 on DESKTOP-M0JUU87 with PID 11216
2024-01-28 22:19:06.125  INFO 11216 --- [           main] c.s.t.TourApiProjectApplication          : The following profiles are active: local,localdb,common,security
2024-01-28 22:19:07.359  INFO 11216 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2024-01-28 22:19:07.683  INFO 11216 --- [           main] .s.d.r.c.RepositoryConfigurationDelegate : Finished Spring Data repository scanning in 316 ms. Found 33 JPA repository interfaces.
2024-01-28 22:19:07.868  WARN 11216 --- [           main] o.m.s.mapper.ClassPathMapperScanner      : No MyBatis mapper was found in '[com.server.tourApiProject]' package. Please check your configuration.
...

 

위와 같이 로그는 프로그램이 실행될 때 발생하는 이벤트를 추적할 수 있도록 프로그램 실행 기록을 남기는 것으로, 개발 및 운영에 꼭 필요한 요소이다.

 

기존의 별 헤는 밤을 개발하면서 로그를 보기만 했지 커스텀하거나 저장하지 않았는데, 점점 어플이 커지고 운영의 효율을 위해 로그 시스템을 개선해 보기로 하였다.

 

SLF4J

로그 라이브러리에는 java.util.logging, Apache Commons logging, Log4j, Logback 등 다양한 종류가 있다.

SLF4J는 Simple Logging Facade for Java의 약자로 라이브러리 인터페이스 역할을 하며, 여러 라이브러리들을 하나의 통일된 방식으로 사용할 수 있는 방법을 제공한다.

 

SLF4J 을 사용하기 위해서는 아래 dependency를 추가하고,

 

dependencies {
		implementation 'ch.qos.logback:logback-classic:1.4.1'
		implementation 'org.slf4j:slf4j-api:2.0.3'
}

build.gradle

 

아래와 같이 사용하면 된다.

 

private static final Logger LOG = LoggerFactory.getLogger(TestService.class);
logger.debug("Hello world!");

 

 

하지만 lombok 라이브러리를 사용한다면 @Slf4j 어노테이션으로 간단하게 사용할 수 있으니 lombok을 사용하도록 하자

 

dependencies {
		compileOnly 'org.projectlombok:lombok'
		annotationProcessor 'org.projectlombok:lombok'
}

build.gradle

 

@Slf4j
public class TestService {
		log.info("Hello world!");
}

 

이 글에서는 slf4j 인터페이스 중 Logback을 사용할 것이기 때문에 Logback 사용 방법에 대해 알아보자.

 

 

사전 지식

  • 로그 레벨 Level 설명
    error 예상하지 못한 심각한 문제가 발생하는 경우, 즉시 조치를 취해야 할 수준의 레벨
    warn 로직 상 유효성 확인, 예상 가능한 문제로 인한 예외 처리, 당장 서비스 운영에는 영향이 없지만 주의해야 할 부분
    info 운영에 참고할만한 사항, 중요한 비즈니스 프로세스가 완료됨
    debug 개발 단계에서 사용하며, SQL 로깅을 할 수 있음
    trace 모든 레벨에 대한 로깅이 추적되므로 개발 단계에서 사용함
  • 로그 패턴
    • %logger : 패키지 포함 클래스 정보
    • %logger{0} : 패키지를 제외한 클래스 이름만 출력
    • %logger{length} : Logger name을 축약할 수 있음. {length}는 최대 자리 수, ex)logger{35}
    • %-5level : 로그 레벨, -5는 출력의 고정폭 값(5글자), 로깅레벨이i nfo일 경우 빈칸 하나 추가
    • ${PID:-} : 프로세스 아이디
    • %d : 로그 기록시간 출력
    • %p : 로깅 레벨 출력
    • %F : 로깅이 발생한 프로그램 파일명 출력
    • %M : 로깅이 발생한 메소드의 이름 출력
    • %line : 로깅이 발생한 호출지의 라인
    • %L : 로깅이 발생한 호출지의 라인
    • %thread : 현재 Thread 명
    • %t : 로깅이 발생한 Thread 명
    • %c : 로깅이 발생한 카테고리
    • %C : 로깅이 발생한 클래스 명 (%C{2}는 somePackage.SomeClass 가 출력됨)
    • %msg : 로그 메시지 (=%message)
    • %n : 줄바꿈(new line)
    • %% : %를 출력
    • %r : 애플리케이션 시작 이후부터 로깅이 발생한 시점까지의 시간(ms)
    • %d{yyyy-MM-dd-HH:mm:ss:sss} : %d는 date를 의미하며 중괄호에 들어간 문자열은 dateformat을 의미. 따라서 [2021-07-12 12:42:78]과 같은 날짜가 로그에 출력됨.
    • %-4relative : %relative는 초 아래 단위 시간(밀리초)을 나타냄. 4를하면 4칸의 출력폼을 고정으로 가지고 출력. 따라서 숫자에 따라 [2021-07-12 12:42:78:232] 혹은 [2021-07-12 12:42:78:2332]와 같이 표현됨
    • %magenta() : 괄호 안에 포함된 출력의 색상을 마젠타색으로 설정합니다.
    • highlight() : 로깅 레벨에 따라 괄호 안에 포함된 출력의 색상을 설정합니다(예: ERROR = 빨간색).

 

logback 적용

위 로그 포맷을 사용해서 원하는 포맷으로 콘솔에 로그를 출력해 보자.

설정 파일 이름은 logback-spring.xml, 위치는 src/main/resources 에 위치하도록 한다.

 

다음은 logback의 3가지 주요 설정이다.

  • Appender : 어디에 출력할지에 대해 기술
    • ConsoleAppender : 콘솔에 로그를 어떤 포맷으로 남길지 설정할 수 있다
    • FileAppender : 파일에 로그를 어떤 포맷으로 남길지 설정할 수 있다
    • RollingFileAppender : 로그의 양이 많아지면 하나의 파일로 관리하기 어렵기 때문에 하루 단위로 로그 파일을 관리할 때 설정한다.
  • Logger : 로그의 주체. 로그의 메시지 전달, 특정 패키지 안의 특정 레벨 이상인 것에 대해 출력
  • Layout(Encoder) : 어떻게 출력할지에 대해 기술

아래는 콘솔에 원하는 패턴으로 로그를 출력하게 하는 설정 파일이다.

참고로 root level = INFO는 Info 레벨 이상의 로그만 출력한다는 의미이다.

 

<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
        <layout class="ch.qos.logback.classic.PatternLayout">
            <Pattern>
                %d{yyyy-MM-dd HH:mm:ss} [%t] %-5level [%logger{0}:%line] - %msg%n
            </Pattern>
        </layout>
    </appender>

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

logback-spring.xml

 

 

실행 시, 맨 위의 콘솔 로그와 달리 원하는 포맷으로 로그가 출력되었음을 확인할 수 있다.

.   ____          _            __ _ _
 /\\ / ___'_ __ _ _(_)_ __  __ _ \ \ \ \
( ( )\___ | '_ | '_| | '_ \/ _` | \ \ \ \
 \\/  ___)| |_)| | | | | || (_| |  ) ) ) )
  '  |____| .__|_| |_|_| |_\__, | / / / /
 =========|_|==============|___/=/_/_/_/
 :: Spring Boot ::                (v2.5.2)

2024-01-28 23:12:06 [background-preinit] INFO  [Version:21] - HV000001: Hibernate Validator 6.2.0.Final
2024-01-28 23:12:06 [main] INFO  [TourApiProjectApplication:55] - Starting TourApiProjectApplication using Java 11.0.19 on DESKTOP-M0JUU87 with PID 27800
2024-01-28 23:12:06 [main] INFO  [TourApiProjectApplication:663] - The following profiles are active: local,localdb,common,security
2024-01-28 23:12:07 [main] INFO  [RepositoryConfigurationDelegate:132] - Bootstrapping Spring Data JPA repositories in DEFAULT mode.
2024-01-28 23:12:08 [main] INFO  [RepositoryConfigurationDelegate:201] - Finished Spring Data repository scanning in 349 ms. Found 33 JPA repository interfaces.
...

 

특히 패턴 중 %line 은 로깅이 발생한 호출지의 라인을 표시해 주는데, 에러 발생 시 에러가 발생한 부분의 코드라인을 바로 확인할 수 있기에 개인적으로 매우 편한 옵션이라고 생각한다. 추천한다!

 
만약 로그를 콘솔창이 아닌 파일에 따로 저장하고 싶다면 다음과 같이 appender 를 수정하면 된다.
<?xml version="1.0" encoding="UTF-8"?>
<configuration>
    <appender name="CONSOLE" class="ch.qos.logback.core.FileAppender">
				<file>testFile.log</file>
        <append>true</append>
            <immediateFlush>true</immediateFlush>
            <encoder>
                <pattern>
                    %d{yyyy-MM-dd HH:mm:ss} [%t] %-5level [%logger{0}:%line] - %msg%n
                </pattern>
            </encoder>
    </appender>

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

logback-spring.xml

 

 

그럼 testFile.log 란 파일이 생성되고, 해당 파일에 로그가 찍힘을 확인할 수 있다.

 

 

만약 profile 별로 다른 logback 을 설정하고 싶다면 springProfile 을 사용하면 된다.
아래 코드는 profile 이 prod 일때는 파일에, local 일 때는 콘솔에 로그를 표출하는 설정이다.
 
<?xml version="1.0" encoding="UTF-8"?>
<configuration>

		<!--    운영계    -->
    <springProfile name="prod">
        <appender name="FILE" class="ch.qos.logback.core.FileAppender">
            <file>testFile.log</file>
            <append>true</append>
            <immediateFlush>true</immediateFlush>
            <encoder>
                <pattern>
                    %d{yyyy-MM-dd HH:mm:ss} [%t] %-5level [%logger{0}:%line] - %msg%n
                </pattern>
            </encoder>
        </appender>

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

		<!--    개발계    -->
    <springProfile name="local">
        <appender name="CONSOLE" class="ch.qos.logback.core.ConsoleAppender">
            <layout class="ch.qos.logback.classic.PatternLayout">
                <Pattern>
                    %d{yyyy-MM-dd HH:mm:ss} [%t] %-5level [%logger{0}:%line] - %msg%n
                </Pattern>
            </layout>
        </appender>

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

</configuration>

 


마무리

이번 시간에는 로그 라이브러리 Logback을 사용하여 원하는 포맷으로 로그를 출력하고, 로그 파일을 추출하며 로깅 시스템을 개선해 보았다. 생각보다 간단한 설정만으로 가능하여 하루 정도 투자하면 편하게 로그를 볼 수 있을 것이다.

 

 

<별 헤는 밤> 보러 가기

 

별 헤는 밤: 밤하늘, 별자리, 여행정보와 날씨예보까지 - Google Play 앱

오늘부터 별잘알! 오늘밤 별자리 정보, 날씨·광공해·월령까지 고려한 '관측적합도', 주변 관측지 검색으로 누구나 쉽게 밤하늘을 즐겨보세요.