토리맘의 한글라이즈 프로젝트 logo 토리맘의 한글라이즈 프로젝트

스프링 부트 공식 레퍼런스를 한글로 번역한 문서입니다.

전체 목차는 여기에 있습니다.

목차


7.4. Logging

스프링 부트는 모든 내부 로깅에 Commons Logging을 사용하지만, 근본적인 로그 구현체는 선택할 수 있게 되어있다. Java Util Logging, Log4J2, Logback을 위한 디폴트 설정을 제공한다. 각 로거는 콘솔 출력을 위한 설정이 미리 정의돼 있으며, 원한다면 파일에도 출력할 수 있다.

기본적으로 “스타터”를 사용하면 로그백으로 로깅한다. 적절한 Logback 라우팅도 포함하기 때문에 Java Util Logging이나 Commons Logging, Log4J, SLF4J를 사용하는 의존 라이브러리 모두 잘 동작한다.

자바에서 활용할 수 있는 로깅 프레임워크는 다양하다. 위에서 너무 많은 것을 언급해 혼란스럽더라도 걱정할 필요 없다. 보통은 로깅 의존성은 변경할 필요 없으며, 스프링 부트 디폴트로도 문제 없이 동작한다.

애플리케이션을 서블릿 컨테이너나 애플리케이션 서버에 배포할 때는, Java Util Logging API를 통해 남긴 로그는 애플리케이션 로그로 라우팅되지 않는다. 따라서 컨테이너나 컨테이너에 배포된 다른 애플리케이션이 남긴 로그는 애플리케이션 로그에 나타나지 않는다.

7.4.1. Log Format

스프링 부트는 기본적으로 다음과 유사한 로그를 기록한다:

2019-03-05 10:57:51.112  INFO 45469 --- [           main] org.apache.catalina.core.StandardEngine  : Starting Servlet Engine: Apache Tomcat/7.0.52
2019-03-05 10:57:51.253  INFO 45469 --- [ost-startStop-1] o.a.c.c.C.[Tomcat].[localhost].[/]       : Initializing Spring embedded WebApplicationContext
2019-03-05 10:57:51.253  INFO 45469 --- [ost-startStop-1] o.s.web.context.ContextLoader            : Root WebApplicationContext: initialization completed in 1358 ms
2019-03-05 10:57:51.698  INFO 45469 --- [ost-startStop-1] o.s.b.c.e.ServletRegistrationBean        : Mapping servlet: 'dispatcherServlet' to [/]
2019-03-05 10:57:51.702  INFO 45469 --- [ost-startStop-1] o.s.b.c.embedded.FilterRegistrationBean  : Mapping filter: 'hiddenHttpMethodFilter' to: [/*]

여기서는 다음과 같은 항목들을 출력한다:

로그백엔 FATAL 레벨은 없으며, ERROR에 매핑된다.

7.4.2. Console Output

디폴트 로그 설정에선 로그를 작성하면 콘솔에 메세지를 출력한다. 기본적으로 ERROR, WARN, INFO 레벨 메세지를 남긴다. --debug 플래그로 애플리케이션을 시작하면 “디버그” 모드를 활성화할 수 있다:

$ java -jar myapp.jar --debug

application.properties에서 debug=true를 명시해도 된다.

디버그 모드를 활성화하면 몇 가지 코어 로거들(임베디드 컨테이너, Hibernate, 스프링 부트)을 설정해서 더 많은 정보를 출력한다. 디버그 모드를 활성화한다고 해서 애플리케이션이 DEBUG 레벨에 있는 메세지를 전부 기록하도록 설정되는 건 아니다.

아니면 --trace 플래그(또는 application.propertiestrace=true)로 애플리케이션을 시작해서 “trace” 모드를 활성화해도 된다. trace 모드를 활성화하면 몇 가지 핵심 로거(임베디드 컨테이너, Hibernate schema generation, 전체 스프링 portfolio)에 trace 로깅을 활성화한다.

Color-coded Output

ANSI를 지원하는 터미널에선 색상 출력을 통해 가독성을 개선할 수 있다. 자동 감지auto-detection를 재정의하려면 spring.output.ansi.enabled지원하는 값을 설정하면 된다.

색상 코드는 conversion word %clr을 사용해 설정한다. 아래는 가장 간단한 예시인데, 컨버터가 로그 레벨에 따라 출력 문구에 색을 입혀준다:

%clr(%5p)

다음은 로그 레벨에 따라 매핑되는 색상을 정리한 테이블이다:

Level Color
FATAL Red
ERROR Red
WARN Yellow
INFO Green
DEBUG Green
TRACE Green

아니면 변환 옵션을 제공해서 사용할 색상이나 스타일을 지정해도 된다. 예를 들어 텍스트를 노란색으로 만들고 싶다면 아래 설정을 사용해라:

%clr(%d{yyyy-MM-dd HH:mm:ss.SSS}){yellow}

지원하는 색상과 스타일은 다음과 같다:

7.4.3. File Output

기본적으로 스프링 부트는 콘솔에만 로그를 기록하며, 로그 파일은 작성하지 않는다. 콘솔 출력과 더불어 로그 파일도 작성하고 싶으면 logging.file.name이나 logging.file.path 프로퍼티를 설정해야 한다 (ex. application.properties 안에).

다음은 logging.* 프로퍼티를 조합해서 활용하는 방법을 나타낸 테이블이다:

logging.file.name logging.file.path Example Description
(none) (none)   콘솔에만 기록한다.
특정 파일 (none) my.log 지정한 로그 파일에 기록한다. 정확한 위치 또는 현재 디렉토리를 기준으로 상대적인 위치를 사용할 수 있다.
(none) 특정 디렉토리 /var/log 지정한 디렉토리에 spring.log를 작성한다. 정확한 위치 또는 현재 디렉토리를 기준으로 상대적인 위치를 사용할 수 있다.

기본 설정에선 로그 파일은 10MB에 도달하면 로테이트rotate되며, 콘솔 출력과 동일하게 ERROR, WARN, INFO 레벨 메세지를 남긴다.

로그 관련 프로퍼티들은 실제 로그를 출력하는 인프라와는 독립적이다. 즉, 전용 설정 키(ex. Logback의 logback.configurationFile)들은 스프링 부트에서 관리하지 않는다.

7.4.4. File Rotation

Logback을 사용한다면 application.propertiesapplication.yaml 파일을 통해 로그 로테이션rotation 설정을 세밀하게 변경할 수 있다. 그외 다른 로깅 시스템에선 로테이션 설정을 직접 구성해야 한다 (예를 들어 Log4J2를 사용하고 있다면 log4j.xml 파일을 추가하면 된다).

아래 프로퍼티들로 로테이션 정책을 설정할 수 있다:

Name Description
logging.logback.rollingpolicy.file-name-pattern 로그 아카이브를 만들 때 파일 이름에 사용할 패턴.
logging.logback.rollingpolicy.clean-history-on-start 애플리케이션을 시작할 때 로그 아카이브를 비워야 하는지.
logging.logback.rollingpolicy.max-file-size 로그 파일을 아카이빙하기 전 최대 사이즈.
logging.logback.rollingpolicy.total-size-cap 로그 아카이브 파일들의 최대 용량으로, 이 크기를 넘어가면 삭제된다.
logging.logback.rollingpolicy.max-history 로그 아카이브를 유지할 일 수 (디폴트는 7일)

7.4.5. Log Levels

지원하는 로깅 시스템 모두 logging.level.<logger-name>=<level>을 통해 스프링 Environment에 로거 레벨을 설정할 수 있다 (ex. application.properties 안에). 여기서 level은 TRACE, DEBUG, INFO, WARN, ERROR, FATAL OFF 중 하나다. root 로거는 logging.level.root로 설정하면 된다.

예를 들어 아래 예제처럼 application.properties에 로그 설정을 추가할 수 있다:

properties yaml
logging.level.root=warn
logging.level.org.springframework.web=debug
logging.level.org.hibernate=error
logging:
  level:
    root: "warn"
    org.springframework.web: "debug"
    org.hibernate: "error"

로그 레벨은 환경 변수로도 설정할 수 있다. 예를 들어 LOGGING_LEVEL_ORG_SPRINGFRAMEWORK_WEB=DEBUGorg.springframework.webDEBUG로 설정해준다.

위에서 언급한 방식은 패키지 레벨 로깅에만 적용할 수 있다. 환경 변수는 바인딩 규칙을 완화하면서 소문자로 변환되므로, 이 방식으로는 개별 클래스에 로깅을 설정할 수 없다. 클래스 단위로 로깅을 설정해야 할 땐 SPRING_APPLICATION_JSON 변수를 활용하면 된다.

7.4.6. Log Groups

서로 관련 있는 로거를 함께 묶어서 전부 한 번에 설정할 수 있다면 매우 편리할 거다. 예를 들어서 흔히 톰캣과 관련된 모든 로거의 로그 레벨을 변경할 수 있는데, 최상위 패키지를 매번 기억하긴 쉽지 않다.

스프링 부트에선 스프링 Environment에 로그 그룹을 정의할 수 있다. 다음은 “tomcat” 그룹을 application.properties에 정의하는 예시다:

properties yaml
logging.group.tomcat=org.apache.catalina,org.apache.coyote,org.apache.tomcat
logging:
  group:
    tomcat: "org.apache.catalina,org.apache.coyote,org.apache.tomcat"

이렇게 정의하고 나면, 설정 한 줄만으로 여기 있는 모든 로거의 레벨을 변경할 수 있다:

properties yaml
logging.level.tomcat=trace
logging:
  level:
    tomcat: "trace"

스프링 부트에선 아래 로그 그룹들을 바로 사용할 수 있게 미리 정의해 뒀다:

Name Loggers
web org.springframework.core.codec, org.springframework.http, org.springframework.web, org.springframework.boot.actuate.endpoint.web, org.springframework.boot.web.servlet.ServletContextInitializerBeans
sql org.springframework.jdbc.core, org.hibernate.SQL, org.jooq.tools.LoggerListener

7.4.7. Using a Log Shutdown Hook

애플리케이션이 종료될 때 로깅 리소스를 반환할 수 있도록 JVM이 종료될 때는 셧다운 훅을 통해 로그 시스템 정리를 트리거한다. 이 셧다운 훅은 애플리케이션을 war 파일로 배포하지만 않으면 자동으로 등록된다. 애플리케이션의 컨텍스트 계층구조가 복잡하면 셧다운 훅을 활용하기가 어려울 수도 있다. 이런땐 셧다운 훅을 비활성화하고 내부 로깅 시스템이 직접 제공하는 옵션을 찾아봐라. 예를 들어, Logback은 각 Logger를 자체 컨텍스트에서 생성 할 수 있는 context selector를 제공한다. 셧다운 훅을 비활성화할 땐 logging.register-shutdown-hook 프로퍼티를 사용하면 된다. false로 설정하면 등록을 비활성화한다. 이 프로퍼티는 application.propertiesapplication.yaml 파일에 설정하면 된다:

properties yaml
logging.register-shutdown-hook=false
logging:
  register-shutdown-hook: false

7.4.8. Custom Log Configuration

클래스패스에 적절한 라이브러리를 추가하는 것으로 다양한 로깅 시스템을 활성화할 수 있으며, 클래스패스의 루트나 스프링 Environment 프로퍼티 logging.config에 지정한 위치에 적당한 설정 파일을 제공하면 좀 더 커스텀할 수도 있다.

시스템 프로퍼티 org.springframework.boot.logging.LoggingSystem을 사용하면 스프링 부트가 사용할 로깅 시스템을 강제할 수 있다. 이 프로퍼티 값엔 LoggingSystem 구현체의 풀 네임fully qualified class name을 사용해야 한다. none을 사용하면 스프링 부트의 로깅 설정을 완전히 비활성화할 수도 있다.

로깅 시스템은 ApplicationContext를 생성하기 전에 초기화하기 때문에, 스프링 @Configuration 파일의 @PropertySources로는 로깅 시스템을 제어할 수 없다. 로깅 시스템을 변경하거나 완전히 비활성화하는 유일한 방법은 시스템 프로퍼티를 사용하는 방법 뿐이다.

사용하는 로깅 시스템에 따라 아래와 같은 파일들을 로드한다:

Logging System Customization
Logback logback-spring.xml, logback-spring.groovy, logback.xml, logback.groovy
Log4j2 log4j2-spring.xml, log4j2.xml
JDK (Java Util Logging) logging.properties

가능하면 로깅 설정에는 -spring 이 붙어 있는 파일을 사용하는 게 좋다 (예를 들어 logback.xml 대신 logback-spring.xml). 표준 설정 location를 사용하게 되면 스프링이 로그 초기화를 완전히 제어할 수 없다.

Java Util Logging에선 ‘실행 가능한 jarexecutable jar‘로 실행하면 클래스 로딩 이슈가 발생하는 것으로 알려져 있다. 가능하면 ‘실행 가능한 jar’에서 실행할 때는 Java Util Logging을 사용하지 않는 게 좋다.

커스텀을 돕기 위해 다음 테이블에서 보이는 스프링 Environment의 일부 프로퍼티들은 시스템 프로퍼티로 옮겨간다:

Spring Environment System Property Comments
logging.exception-conversion-word LOG_EXCEPTION_CONVERSION_WORD 예외를 로깅할 때 사용할 conversion word.
logging.file.name LOG_FILE 값을 정의하면 디폴트 로그 설정에서 사용한다.
logging.file.path LOG_PATH 값을 정의하면 디폴트 로그 설정에서 사용한다.
logging.pattern.console CONSOLE_LOG_PATTERN 콘솔에서 사용할 로그 패턴 (stdout).
logging.pattern.dateformat LOG_DATEFORMAT_PATTERN 로그 날짜 포맷에 사용할 어펜더 패턴.
logging.charset.console CONSOLE_LOG_CHARSET 콘솔 로깅에 사용할 캐릭터 셋.
logging.pattern.file FILE_LOG_PATTERN 파일에서 사용할 로그 패턴 (LOG_FILE을 활성화했다면).
logging.charset.file FILE_LOG_CHARSET 파일 로깅에 사용할 캐릭터 셋 (LOG_FILE을 활성화했다면).
logging.pattern.level LOG_LEVEL_PATTERN 로그 레벨을 렌더링할 때 사용할 포맷 (디폴트는 %5p).
PID PID 현재 프로세스 ID (OS 환경 변수로 이미 정의하지 않았다면 가능하면 값을 알아낸다)

로그백을 사용할 땐 아래 프로퍼티도 함께 옮겨진다:

Spring Environment System Property Comments
logging.logback.rollingpolicy.file-name-pattern LOGBACK_ROLLINGPOLICY_
FILE_NAME_PATTERN
roll over한 로그 파일 이름에 사용할 패턴 (디폴트는 ${LOG_FILE}.%d{yyyy-MM-dd}.%i.gz).
logging.logback.rollingpolicy.clean-history-on-start LOGBACK_ROLLINGPOLICY_
CLEAN_HISTORY_ON_START
기동 시에 로그 아카이브 파일을 비울지.
logging.logback.rollingpolicy.max-file-size LOGBACK_ROLLINGPOLICY_
MAX_FILE_SIZE
로그 파일의 최대 사이즈.
logging.logback.rollingpolicy.total-size-cap LOGBACK_ROLLINGPOLICY_
TOTAL_SIZE_CAP
백업으로 남겨둘 로그의 총 크기.
logging.logback.rollingpolicy.max-history LOGBACK_ROLLINGPOLICY_
MAX_HISTORY
최대로 유지할 로그 아카이브 파일 수.

지원하는 로깅 시스템은 전부 설정 파일을 파싱할 때 시스템 프로퍼티를 참조할 수 있다. 예제는 spring-boot.jar에 있는 디폴트 설정을 보면 된다:

로깅 프로퍼티에 플레이스홀더를 사용하고 싶으면 내부 프레임워크의 구문 대신 스프링 부트의 구문을 사용해야 한다. 특히 Logback을 사용한다면 프로퍼티 이름과 디폴트 값 사이 구분자는 :-가 아닌 :를 사용해야 한다.

LOG_LEVEL_PATTERN(또는 Logback에선 logging.pattern.level)만 재정의하면 로그마다 MDC나 다른 애드혹 컨텐츠를 추가할 수 있다. 예를 들어 logging.pattern.level=user:%X{user} %5p를 사용하면 아래 예시처럼 디폴트 기본 로그 포맷에 “user”에 관한 MDC 항목이 추가된다 (존재하면).

2019-08-30 12:30:04.031 user:someone INFO 22174 --- [  nio-8080-exec-0] demo.Controller Handling authenticated request

7.4.9. Logback Extensions

스프링 부트는 고급 설정에서 활용할만한 다양한 Logback 익스텐션을 제공한다. 이런 익스텐션은 logback-spring.xml 설정 파일에서 사용할 수 있다.

표준 logback.xml 파일은 너무 빨리 로드되기 때문에, 이 파일 안에선 익스텐션을 사용할 수 없다. 익스텐션을 사용하려면 logback-spring.xml을 사용하거나 logging.config 프로퍼티를 정의해야 한다.

익스텐션은 Logback의 설정 스캔과는 사용할 수 없다. 함께 사용하게 되면, 설정 파일 변경 시 아래와 유사한 에러 중 하나를 만나게될 거다.

ERROR in ch.qos.logback.core.joran.spi.Interpreter@4:71 - no applicable action for [springProperty], current ElementPath is [[configuration][springProperty]]
ERROR in ch.qos.logback.core.joran.spi.Interpreter@4:71 - no applicable action for [springProfile], current ElementPath is [[configuration][springProfile]]

Profile-specific Configuration

<springProfile> 태그를 활용하면 스프링의 활성 프로파일에 따라 원하는대로 설정 섹션을 포함시키거나 제외시킬 수 있다. 프로파일 섹션은 <configuration> 요소 내에 어디든지 사용할 수 있다. 설정을 허용할 프로파일은 name 속성으로 지정한다. <springProfile> 태그에는 프로파일명(ex. staging)이나 프로파일 표현식을 사용할 수 있다. 프로파일 표현식을 쓰면 production & (eu-central | eu-west)같이 좀 더 복잡한 프로파일 로직을 표현할 수 있다. 자세한 내용은 레퍼런스 가이드를 확인해봐라. 다음은 세 가지 샘플 프로파일을 사용하는 예시다:

<springProfile name="staging">
    <!-- configuration to be enabled when the "staging" profile is active -->
</springProfile>

<springProfile name="dev | staging">
    <!-- configuration to be enabled when the "dev" or "staging" profiles are active -->
</springProfile>

<springProfile name="!production">
    <!-- configuration to be enabled when the "production" profile is not active -->
</springProfile>

Environment Properties

<springProperty> 태그는 스프링 Environment에 있는 프로퍼티를 로그백 안에서 사용할 수 있도록 노출해준다. 이렇게하면 Logback 설정에서 application.properties 파일에 있는 값에 접근할 수 있다. 이 태그는 Logback의 표준 <property> 태그와 유사하게 동작한다. 단, 직접 value를 지정하는 대신, (Environment에 있는) 프로퍼티를 가져올 source를 지정한다. 프로퍼티를 local 스코프 외에 다른 곳에 저장해야 한다면 scope 속성을 사용하면 된다. 폴백 값이 필요하면 (Environment에 프로퍼티를 설정하지 않았을 때 사용할) defaultValue 속성을 사용하면 된다. 다음은 Logback 안에서 사용할 프로퍼티를 노출하는 예시다:

<springProperty scope="context" name="fluentHost" source="myapp.fluentd.host"
        defaultValue="localhost"/>
<appender name="FLUENT" class="ch.qos.logback.more.appenders.DataFluentAppender">
    <remoteHost>${fluentHost}</remoteHost>
    ...
</appender>

source는 반드시 케밥 케이스로 지정해야 한다 (ex. my.property-name). 물론 Environment에 추가할 때는 완화된 규칙을 사용할 수 있다.


Next :
Internationalization
리소스 번들을 사용해서 스프링 부트 메세지 현지화하기

전체 목차는 여기에 있습니다.

<< >>

TOP