스프링 부트 공식 레퍼런스를 한글로 번역한 문서입니다.
전체 목차는 여기에 있습니다.
목차
- 7.4.1. Log Format
- 7.4.2. Console Output
- 7.4.3. File Output
- 7.4.4. File Rotation
- 7.4.5. Log Levels
- 7.4.6. Log Groups
- 7.4.7. Using a Log Shutdown Hook
- 7.4.8. Custom Log Configuration
- 7.4.9. Logback Extensions
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: [/*]
여기서는 다음과 같은 항목들을 출력한다:
- 날짜와 시간: 밀리세컨드 단위까지 지원하며 쉽게 정렬해서 볼 수 있다.
- 로그 레벨:
ERROR
,WARN
,INFO
,DEBUG
,TRACE
. - 프로세스 ID.
- 실제 로그 메세지가 시작됨을 알리는 구분자
---
. - 스레드 이름: 대괄호로 묶여 있다 (콘솔에선 잘릴 수도 있다truncated).
- 로거 이름: 보통 소스 클래스명 (축약하기도 한다).
- 로그 메세지.
로그백엔
FATAL
레벨은 없으며,ERROR
에 매핑된다.
7.4.2. Console Output
디폴트 로그 설정에선 로그를 작성하면 콘솔에 메세지를 출력한다. 기본적으로 ERROR
, WARN
, INFO
레벨 메세지를 남긴다. --debug
플래그로 애플리케이션을 시작하면 “디버그” 모드를 활성화할 수 있다:
$ java -jar myapp.jar --debug
application.properties
에서debug=true
를 명시해도 된다.
디버그 모드를 활성화하면 몇 가지 코어 로거들(임베디드 컨테이너, Hibernate, 스프링 부트)을 설정해서 더 많은 정보를 출력한다. 디버그 모드를 활성화한다고 해서 애플리케이션이 DEBUG
레벨에 있는 메세지를 전부 기록하도록 설정되는 건 아니다.
아니면 --trace
플래그(또는 application.properties
의 trace=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}
지원하는 색상과 스타일은 다음과 같다:
blue
cyan
faint
green
magenta
red
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.properties
나 application.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
에 로그 설정을 추가할 수 있다:
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=DEBUG는 org.springframework.web
을 DEBUG
로 설정해준다.
위에서 언급한 방식은 패키지 레벨 로깅에만 적용할 수 있다. 환경 변수는 바인딩 규칙을 완화하면서 소문자로 변환되므로, 이 방식으로는 개별 클래스에 로깅을 설정할 수 없다. 클래스 단위로 로깅을 설정해야 할 땐
SPRING_APPLICATION_JSON
변수를 활용하면 된다.
7.4.6. Log Groups
서로 관련 있는 로거를 함께 묶어서 전부 한 번에 설정할 수 있다면 매우 편리할 거다. 예를 들어서 흔히 톰캣과 관련된 모든 로거의 로그 레벨을 변경할 수 있는데, 최상위 패키지를 매번 기억하긴 쉽지 않다.
스프링 부트에선 스프링 Environment
에 로그 그룹을 정의할 수 있다. 다음은 “tomcat” 그룹을 application.properties
에 정의하는 예시다:
logging.group.tomcat=org.apache.catalina,org.apache.coyote,org.apache.tomcat
logging:
group:
tomcat: "org.apache.catalina,org.apache.coyote,org.apache.tomcat"
이렇게 정의하고 나면, 설정 한 줄만으로 여기 있는 모든 로거의 레벨을 변경할 수 있다:
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.properties
나 application.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
리소스 번들을 사용해서 스프링 부트 메세지 현지화하기
전체 목차는 여기에 있습니다.