SlideShare a Scribd company logo
1 of 40
Download to read offline
스프링 부트와 로깅
백기선
whiteship2000@gmail.com
스프링 부트의
로깅 의존성 관리
스프링 부트와 로깅
• 스프링 부트는 JCL을 사용하여 로깅 코드를 작성한다.
• 스프링 부트 애플리케이션은 SLF4J를 사용한다.
• 스프링 부트 애플리케이션은 Logback을 사용한다.
• 원한다면 얼마든지 다른 로거를 사용할 수 있다.
스프링 부트 소스 코드
import org.apache.commons.logging.Log;

import org.apache.commons.logging.LogFactory;
!
...
!
private final Log log = LogFactory.getLog(getClass());
!
...
!
if (this.log.isDebugEnabled()) {

this.log.debug("Loading source "

+ StringUtils.arrayToCommaDelimitedString(sources));

}
아파치(자카르타) 커먼스 로깅을 줄여서 JCL이라고 부릅니다.
http://commons.apache.org/proper/commons-logging/
JCL (commons-logging)
• 로깅 라이브러리가 아니라 로깅 추상화 라이브러리다.
• 로깅 라이브러리 선택권은 애플리케이션 개발자의 것이
다.
• 따라서 라이브러리나 프레임워크는 주로 로깅 추상화 라
이브러리를 사용한다.
Log Log4J
JCL이 로깅 구현체를 찾는 방법
• 설정 파일에서 찾기
• 애플리케이션 클래스패스에서 Log4J 구현체 찾아보기
• 애플리케이션이 JDK 1.4에서 구동중인지 확인하기
• 아무것도 못찾으면 기본 구현체 사용
로깅 구현체 찾는 방법
http://commons.apache.org/proper/commons-logging/
guide.html#Configuration
JCL을 꺼리는 이유
• 자바 클래스로더의 기본 동작 방식
• 서블릿 컨테이너의 클래스로더 동작 방식
• JCL은 클래스로더에 의존적인 방법으로 구현체를 찾는다.
JCL 사용시 겪을 수 있는 클래스로더 문제
http://articles.qos.ch/classloader.html
!
JCL 사용시 겪을 수 있는 메모리 누수 문제
http://wiki.apache.org/commons/Logging/UndeployMemoryLeak
!
스프링 개발자 Dave Syer, ‘과거로 돌아갈 수 있다면…’
http://spring.io/blog/2009/12/04/logging-dependencies-in-spring/
!
SLF4J
• Simple Logging Facade For Java
• 로깅 라이브러리를 런타임이 아닌 컴파일 타임에 정한다.
• 세가지 모듈(Bridging, API, Binding) 제공
SLF4J API
• 로깅 인터페이스
• slf4j-api-{version}.jar
• org.slf4j.Logger
• org.slf4j.LoggerFactory
API
SLF4J API
import org.slf4j.Logger;

import org.slf4j.LoggerFactory;
!
...
!
Logger logger = LoggerFactory.getLogger(getClass());
logger.info("Loading source {}“, source);
!
...
SLF4J API FAQ
http://www.slf4j.org/faq.html#string_or_object
SLF4J Binding
• SLF4J 인터페이스를 로깅 구현체로 연결
• 어댑터 역할.
• SLF4J 인터페이스를 직접 구현한 구현체도 있다.
• 라이브러리나 프레임워크는 사용하지 마세요.
Binding
SLF4J Binding
• 여러 바인딩 중 반드시 한개만 사용할 것
• slf4j-log4j12-{version}.jar
• slf4j-jdk14-{version}.jar
• slf4j-nop-{version}.jar
• slf4j-jcl-{version}.jar
• logback-classic-{logback-version}.jar
Binding
API
SLF4J Binding
• 여러 바인딩을 클래스패스 두면?
SLF4J: Class path contains multiple SLF4J bindings.
SLF4J: Found binding in [jar:file:/Users/naver/.m2/
repository/ch/qos/logback/logback-classic/1.1.2/logback-
classic-1.1.2.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: Found binding in [jar:file:/Users/naver/.m2/
repository/org/slf4j/slf4j-jdk14/1.7.8/slf4j-
jdk14-1.7.8.jar!/org/slf4j/impl/StaticLoggerBinder.class]
SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings
for an explanation.
SLF4J: Actual binding is of type
[ch.qos.logback.classic.util.ContextSelectorStaticBinder]
http://www.slf4j.org/codes.html#multiple_bindings
SLF4J Bridge
• 로거 호출을 SLF4J 인터페이스로 연결
• 예) Log4J -> SLF4J API
• 어떤 컴포넌트가 구체적인 로거에 의존하면서 고쳐줄 기
미가 보이지 않는다면…
• 해당 로거 호출을 대신 받아서 SLF4J API를 호출해준
다.
Bridge
JCL 호출을 SLF4J로 연결하기
• 의존성에 jcl-over-slf4j.jar 추가
• JCL 호출을 받아서 SLF4J API 호출
• JCL 인터페이스를 구현하고 있다.
• 의존성에서 commons-logging.jar 제거.
• slf4j-jcl.jar랑 같이 쓰면 안돼요.
• 무한 루프
Bridge
API
JCL
Log4J 호출을 SLF4J로 연결하기
• log4j-over-slf4j.jar 추가
• Log4J 호출을 받아서 SLF4J API 호출
• Log4J 인터페이스를 구현하고 있다.
• 의존성에서 log4j.jar 제거.
• slf4j-log4j12.jar랑 같이 쓰면 안돼요.
• 무한 루프
Bridge
API
Log4J
JUL 호출을 SLF4J로 연결하기
• jul-to-slf4j.jar 추가
• java.util.logging은 교체 불가능
• LogRecord 객체를 사용해서 위임.
• slf4j-jdk14.jar랑 같이 쓰면 안돼요.
• 무한 루프
Bridge
API
JUL
동종 브릿지와 바인딩을 같이 쓰면 어떻게 되나?
Bridge
APILog4J
Binding
log4j-over-slf4j
slf4j-api
slf4j-log4j
log4j api 호출
모든 로깅을 Logback으로 하려면?
Bridge
API
BindingLogback
log4j / jul / jcl 호출
log4j-over-slf4j
jcl-over-slf4j
jul-to-slf4j
logback-classic
스프링 부트 로깅
• spring-boot-starter-web
<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-logging</artifactId>

</dependency>

<dependency>

<groupId>org.springframework</groupId>

<artifactId>spring-core</artifactId>

<exclusions>

<exclusion>

<groupId>commons-logging</groupId>

<artifactId>commons-logging</artifactId>

</exclusion>

</exclusions>

</dependency>
스프링 부트 로깅
• spring-boot-starter-logging
<dependency>

<groupId>org.slf4j</groupId>

<artifactId>jcl-over-slf4j</artifactId>

</dependency>

<dependency>

<groupId>org.slf4j</groupId>

<artifactId>jul-to-slf4j</artifactId>

</dependency>

<dependency>

<groupId>org.slf4j</groupId>

<artifactId>log4j-over-slf4j</artifactId>

</dependency>

<dependency>

<groupId>ch.qos.logback</groupId>

<artifactId>logback-classic</artifactId>

</dependency>
스프링 부트 로깅
• 스붓 애플리케이션에서 JCL, JUL, Log4J를 사용해도
• JCL, JUL, Log4J용 브릿지가 있으니까
• 모든 로깅 메서드 호출은 SLF4J-API를 호출하게 되고
• Logback용 바인딩에 있으니까
• 결국 Logback을 사용해서 로깅한다.
스프링 부트 로깅
기본 로깅 포맷
스프링 부트 로그 포맷
2015-04-09 21:28:24.475 INFO 37267 --- [ main]
me.whiteship.Application : Started
Application in 4.178 seconds (JVM running for 5.396)
• 날짜와 시간: 밀리초 단위까지 출력하며 이 정보를 가지고 로그를 정렬할 수 있다.
• 로그 레벨: ERROR, WARN, INFO, DEBUG, TRACE 중 하나.
• 프로세스 ID
• ---: 로그 메시지 시작 구분자
• 쓰레드 이름
• 로거 이름: 보통 클래스 이름인데 패키지 이름은 축약해서 출력하기도 한다.
• 로그 메시지
스프링 부트 로깅
콘솔 출력
콘솔 출력
• DEBUG 레벨로 출력하고 싶다면
• java -jar app.jar --debug
• spring.output.ansi.enabled 설정
• ANSI를 지원하는 터미널에서는 콘솔에 색을 적용할
수 있다.
• ALWAYS, DETECT, NEVER 중에 선택해서 사용
스프링 부트 로깅
파일 출력
파일 출력
• logging.file, logging.path 설정을 사용해야 파일 출력
을 사용할 수 있다.
• 10M 단위로 로그 파일을 새로 만든다.
logging 설정
logging.path logging.file 예 설명
없음 없음 콘솔 출력만 사용
있음 없음 ./logs/
현재 디렉토리 아래 logs라는 디렉토리 안에
spring.log라는 파일에 로그를 남긴다.
없음 있음
./logs/spring-
boot-ri.log
현재 디렉토리 아래 logs라는 디렉토리 안에
spring-boot-ri.log라는 파일에 로그를 남긴다.
있음 있음
logging.path 설정은 무시하고 logging.file 설정
을 사용한다.
스프링 부트 로깅
로그 레벨
로그 레벨
• logging.level.{패키지} = {로그 레벨}
• 패키지 별로 로그 레벨을 설정할 수 있다.
• TRACE, DEBUG, INFO, WARN, ERROR, FATAL, OFF 지원
• 예) 스프링 MVC 관련 로그만 DEBUG 수준으로 보고 다른 로그
는 보고 싶지 않다면 다음과 같이 설정할 수 있다.
• logging.level.org.springframework = OFF
• logging.level.org.springframework.web = DEBUG
스프링 부트 로깅
커스텀 로그 설정
커스텀 로그 설정
• 직접 만든 로그 설정 파일을 클래스패스 루트에 두거나
• logging.config로 로그 설정 파일 위치를 설정한다.
커스텀 로그 설정
로깅 시스템 설정 파일
Logback logback.xml 또는 logback.groovy
Log4j log4j.properties 또는 log4j.xml
Log4j2 log4j2.xml
JDK (Java Util Logging) logging.properties
스프링 부트 로깅
기본 로그 설정 파일
기본 로그 설정
• 스프링 부트는 지금까지 살펴본 로깅 기능을 기본 설정으
로 제공한다.
• org.springframework.boot.logging 패키지 코드
참고.
스프링 부트 로깅
Log4j(2) 사용하기
Log4j(2) 사용하기
• spring-boot-starter-logging 의존성 제거
• spring-boot-starter-log4j(2) 의존성 추가
<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter</artifactId>

<exclusions>

<exclusion>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-logging</
artifactId>

</exclusion>

</exclusions>

</dependency>

<dependency>

<groupId>org.springframework.boot</groupId>

<artifactId>spring-boot-starter-log4j</artifactId>

</dependency>
참고
• http://docs.spring.io/spring-boot/docs/
current/reference/html/boot-features-
logging.html
• http://docs.spring.io/spring-boot/docs/
current/reference/html/howto-logging.html
• http://www.slf4j.org/legacy.html
• http://wiki.apache.org/commons/Logging/
UndeployMemoryLeak
감사합니다.

More Related Content

What's hot

Migrating to Java 11
Migrating to Java 11Migrating to Java 11
Migrating to Java 11Arto Santala
 
오딘: 발할라 라이징 MMORPG의 성능 최적화 사례 공유 [카카오게임즈 - 레벨 300] - 발표자: 김문권, 팀장, 라이온하트 스튜디오...
오딘: 발할라 라이징 MMORPG의 성능 최적화 사례 공유 [카카오게임즈 - 레벨 300] - 발표자: 김문권, 팀장, 라이온하트 스튜디오...오딘: 발할라 라이징 MMORPG의 성능 최적화 사례 공유 [카카오게임즈 - 레벨 300] - 발표자: 김문권, 팀장, 라이온하트 스튜디오...
오딘: 발할라 라이징 MMORPG의 성능 최적화 사례 공유 [카카오게임즈 - 레벨 300] - 발표자: 김문권, 팀장, 라이온하트 스튜디오...Amazon Web Services Korea
 
고려대학교 컴퓨터학과 특강 - 대학생 때 알았더라면 좋았을 것들
고려대학교 컴퓨터학과 특강 - 대학생 때 알았더라면 좋았을 것들고려대학교 컴퓨터학과 특강 - 대학생 때 알았더라면 좋았을 것들
고려대학교 컴퓨터학과 특강 - 대학생 때 알았더라면 좋았을 것들Chris Ohk
 
인프콘 2022 - Rust 크로스 플랫폼 프로그래밍
인프콘 2022 - Rust 크로스 플랫폼 프로그래밍인프콘 2022 - Rust 크로스 플랫폼 프로그래밍
인프콘 2022 - Rust 크로스 플랫폼 프로그래밍Chris Ohk
 
KSUG 스프링캠프 2019 발표자료 - "무엇을 테스트할 것인가, 어떻게 테스트할 것인가"
KSUG 스프링캠프 2019 발표자료 - "무엇을 테스트할 것인가, 어떻게 테스트할 것인가"KSUG 스프링캠프 2019 발표자료 - "무엇을 테스트할 것인가, 어떻게 테스트할 것인가"
KSUG 스프링캠프 2019 발표자료 - "무엇을 테스트할 것인가, 어떻게 테스트할 것인가"용근 권
 
How To Become Better Engineer
How To Become Better EngineerHow To Become Better Engineer
How To Become Better EngineerDaeMyung Kang
 
Spring boot
Spring bootSpring boot
Spring bootsdeeg
 
今さら聞けないDiとspring
今さら聞けないDiとspring今さら聞けないDiとspring
今さら聞けないDiとspring土岐 孝平
 
스프링 시큐리티 구조 이해
스프링 시큐리티 구조 이해스프링 시큐리티 구조 이해
스프링 시큐리티 구조 이해beom kyun choi
 
Iocp 기본 구조 이해
Iocp 기본 구조 이해Iocp 기본 구조 이해
Iocp 기본 구조 이해Nam Hyeonuk
 
Airflow를 이용한 데이터 Workflow 관리
Airflow를 이용한  데이터 Workflow 관리Airflow를 이용한  데이터 Workflow 관리
Airflow를 이용한 데이터 Workflow 관리YoungHeon (Roy) Kim
 
〈야생의 땅: 듀랑고〉 서버 아키텍처 Vol. 3
〈야생의 땅: 듀랑고〉 서버 아키텍처 Vol. 3〈야생의 땅: 듀랑고〉 서버 아키텍처 Vol. 3
〈야생의 땅: 듀랑고〉 서버 아키텍처 Vol. 3Heungsub Lee
 
Spring boot introduction
Spring boot introductionSpring boot introduction
Spring boot introductionRasheed Waraich
 
社内Java8勉強会 ラムダ式とストリームAPI
社内Java8勉強会 ラムダ式とストリームAPI社内Java8勉強会 ラムダ式とストリームAPI
社内Java8勉強会 ラムダ式とストリームAPIAkihiro Ikezoe
 
How to build massive service for advance
How to build massive service for advanceHow to build massive service for advance
How to build massive service for advanceDaeMyung Kang
 

What's hot (20)

Migrating to Java 11
Migrating to Java 11Migrating to Java 11
Migrating to Java 11
 
오딘: 발할라 라이징 MMORPG의 성능 최적화 사례 공유 [카카오게임즈 - 레벨 300] - 발표자: 김문권, 팀장, 라이온하트 스튜디오...
오딘: 발할라 라이징 MMORPG의 성능 최적화 사례 공유 [카카오게임즈 - 레벨 300] - 발표자: 김문권, 팀장, 라이온하트 스튜디오...오딘: 발할라 라이징 MMORPG의 성능 최적화 사례 공유 [카카오게임즈 - 레벨 300] - 발표자: 김문권, 팀장, 라이온하트 스튜디오...
오딘: 발할라 라이징 MMORPG의 성능 최적화 사례 공유 [카카오게임즈 - 레벨 300] - 발표자: 김문권, 팀장, 라이온하트 스튜디오...
 
고려대학교 컴퓨터학과 특강 - 대학생 때 알았더라면 좋았을 것들
고려대학교 컴퓨터학과 특강 - 대학생 때 알았더라면 좋았을 것들고려대학교 컴퓨터학과 특강 - 대학생 때 알았더라면 좋았을 것들
고려대학교 컴퓨터학과 특강 - 대학생 때 알았더라면 좋았을 것들
 
인프콘 2022 - Rust 크로스 플랫폼 프로그래밍
인프콘 2022 - Rust 크로스 플랫폼 프로그래밍인프콘 2022 - Rust 크로스 플랫폼 프로그래밍
인프콘 2022 - Rust 크로스 플랫폼 프로그래밍
 
Spring Boot
Spring BootSpring Boot
Spring Boot
 
Spring Boot
Spring BootSpring Boot
Spring Boot
 
KSUG 스프링캠프 2019 발표자료 - "무엇을 테스트할 것인가, 어떻게 테스트할 것인가"
KSUG 스프링캠프 2019 발표자료 - "무엇을 테스트할 것인가, 어떻게 테스트할 것인가"KSUG 스프링캠프 2019 발표자료 - "무엇을 테스트할 것인가, 어떻게 테스트할 것인가"
KSUG 스프링캠프 2019 발표자료 - "무엇을 테스트할 것인가, 어떻게 테스트할 것인가"
 
How To Become Better Engineer
How To Become Better EngineerHow To Become Better Engineer
How To Become Better Engineer
 
Spring Core
Spring CoreSpring Core
Spring Core
 
Spring Boot
Spring BootSpring Boot
Spring Boot
 
Spring boot
Spring bootSpring boot
Spring boot
 
今さら聞けないDiとspring
今さら聞けないDiとspring今さら聞けないDiとspring
今さら聞けないDiとspring
 
스프링 시큐리티 구조 이해
스프링 시큐리티 구조 이해스프링 시큐리티 구조 이해
스프링 시큐리티 구조 이해
 
Iocp 기본 구조 이해
Iocp 기본 구조 이해Iocp 기본 구조 이해
Iocp 기본 구조 이해
 
Airflow를 이용한 데이터 Workflow 관리
Airflow를 이용한  데이터 Workflow 관리Airflow를 이용한  데이터 Workflow 관리
Airflow를 이용한 데이터 Workflow 관리
 
〈야생의 땅: 듀랑고〉 서버 아키텍처 Vol. 3
〈야생의 땅: 듀랑고〉 서버 아키텍처 Vol. 3〈야생의 땅: 듀랑고〉 서버 아키텍처 Vol. 3
〈야생의 땅: 듀랑고〉 서버 아키텍처 Vol. 3
 
Spring AOP
Spring AOPSpring AOP
Spring AOP
 
Spring boot introduction
Spring boot introductionSpring boot introduction
Spring boot introduction
 
社内Java8勉強会 ラムダ式とストリームAPI
社内Java8勉強会 ラムダ式とストリームAPI社内Java8勉強会 ラムダ式とストリームAPI
社内Java8勉強会 ラムダ式とストリームAPI
 
How to build massive service for advance
How to build massive service for advanceHow to build massive service for advance
How to build massive service for advance
 

Viewers also liked

Spring boot 를 적용한 전사모니터링 시스템 backend 개발 사례
Spring boot 를 적용한 전사모니터링 시스템 backend 개발 사례Spring boot 를 적용한 전사모니터링 시스템 backend 개발 사례
Spring boot 를 적용한 전사모니터링 시스템 backend 개발 사례Jemin Huh
 
세바시15분 게임으로 세상을 바꾸다 - 피터리 놀공발전소 대표
세바시15분 게임으로 세상을 바꾸다 - 피터리 놀공발전소 대표세바시15분 게임으로 세상을 바꾸다 - 피터리 놀공발전소 대표
세바시15분 게임으로 세상을 바꾸다 - 피터리 놀공발전소 대표cbs15min
 
세바시15분 스마트폰으로부터 아이를 구출하라 - 권장희 놀이미디어교육센터 소장
세바시15분 스마트폰으로부터 아이를 구출하라 - 권장희 놀이미디어교육센터 소장세바시15분 스마트폰으로부터 아이를 구출하라 - 권장희 놀이미디어교육센터 소장
세바시15분 스마트폰으로부터 아이를 구출하라 - 권장희 놀이미디어교육센터 소장cbs15min
 
소프트웨어 개발자 로드맵
소프트웨어 개발자 로드맵소프트웨어 개발자 로드맵
소프트웨어 개발자 로드맵중선 곽
 
Spring-Boot (springcamp2014)
Spring-Boot (springcamp2014)Spring-Boot (springcamp2014)
Spring-Boot (springcamp2014)sung yong jung
 
자동화된 Test Case의 효과
자동화된 Test Case의 효과자동화된 Test Case의 효과
자동화된 Test Case의 효과도형 임
 
TDD.JUnit.조금더.알기
TDD.JUnit.조금더.알기TDD.JUnit.조금더.알기
TDD.JUnit.조금더.알기Wonchang Song
 
목 오브젝트(Mock Object)의 이해
목 오브젝트(Mock Object)의 이해목 오브젝트(Mock Object)의 이해
목 오브젝트(Mock Object)의 이해Yong Hoon Kim
 
Jupyter notebook 이해하기
Jupyter notebook 이해하기 Jupyter notebook 이해하기
Jupyter notebook 이해하기 Yong Joon Moon
 
Okjsp 13주년 발표자료: 생존 프로그래밍 Test
Okjsp 13주년 발표자료: 생존 프로그래밍 TestOkjsp 13주년 발표자료: 생존 프로그래밍 Test
Okjsp 13주년 발표자료: 생존 프로그래밍 Testbeom kyun choi
 
실리콘 밸리 데이터 사이언티스트의 하루
실리콘 밸리 데이터 사이언티스트의 하루실리콘 밸리 데이터 사이언티스트의 하루
실리콘 밸리 데이터 사이언티스트의 하루Jaimie Kwon (권재명)
 
어떻게 하면 데이터 사이언티스트가 될 수 있나요?
어떻게 하면 데이터 사이언티스트가 될 수 있나요?어떻게 하면 데이터 사이언티스트가 될 수 있나요?
어떻게 하면 데이터 사이언티스트가 될 수 있나요?Yongho Ha
 
데이터는 차트가 아니라 돈이 되어야 한다.
데이터는 차트가 아니라 돈이 되어야 한다.데이터는 차트가 아니라 돈이 되어야 한다.
데이터는 차트가 아니라 돈이 되어야 한다.Yongho Ha
 
중국 VR 보고서 - 2016
중국 VR 보고서 - 2016중국 VR 보고서 - 2016
중국 VR 보고서 - 2016Brandon Lee
 

Viewers also liked (17)

Spring boot 를 적용한 전사모니터링 시스템 backend 개발 사례
Spring boot 를 적용한 전사모니터링 시스템 backend 개발 사례Spring boot 를 적용한 전사모니터링 시스템 backend 개발 사례
Spring boot 를 적용한 전사모니터링 시스템 backend 개발 사례
 
세바시15분 게임으로 세상을 바꾸다 - 피터리 놀공발전소 대표
세바시15분 게임으로 세상을 바꾸다 - 피터리 놀공발전소 대표세바시15분 게임으로 세상을 바꾸다 - 피터리 놀공발전소 대표
세바시15분 게임으로 세상을 바꾸다 - 피터리 놀공발전소 대표
 
세바시15분 스마트폰으로부터 아이를 구출하라 - 권장희 놀이미디어교육센터 소장
세바시15분 스마트폰으로부터 아이를 구출하라 - 권장희 놀이미디어교육센터 소장세바시15분 스마트폰으로부터 아이를 구출하라 - 권장희 놀이미디어교육센터 소장
세바시15분 스마트폰으로부터 아이를 구출하라 - 권장희 놀이미디어교육센터 소장
 
소프트웨어 개발자 로드맵
소프트웨어 개발자 로드맵소프트웨어 개발자 로드맵
소프트웨어 개발자 로드맵
 
Spring-Boot (springcamp2014)
Spring-Boot (springcamp2014)Spring-Boot (springcamp2014)
Spring-Boot (springcamp2014)
 
TEST?
TEST?TEST?
TEST?
 
자동화된 Test Case의 효과
자동화된 Test Case의 효과자동화된 Test Case의 효과
자동화된 Test Case의 효과
 
TDD.JUnit.조금더.알기
TDD.JUnit.조금더.알기TDD.JUnit.조금더.알기
TDD.JUnit.조금더.알기
 
목 오브젝트(Mock Object)의 이해
목 오브젝트(Mock Object)의 이해목 오브젝트(Mock Object)의 이해
목 오브젝트(Mock Object)의 이해
 
Jupyter notebook 이해하기
Jupyter notebook 이해하기 Jupyter notebook 이해하기
Jupyter notebook 이해하기
 
Maven의 이해
Maven의 이해Maven의 이해
Maven의 이해
 
Okjsp 13주년 발표자료: 생존 프로그래밍 Test
Okjsp 13주년 발표자료: 생존 프로그래밍 TestOkjsp 13주년 발표자료: 생존 프로그래밍 Test
Okjsp 13주년 발표자료: 생존 프로그래밍 Test
 
Spring Boot 소개
Spring Boot 소개Spring Boot 소개
Spring Boot 소개
 
실리콘 밸리 데이터 사이언티스트의 하루
실리콘 밸리 데이터 사이언티스트의 하루실리콘 밸리 데이터 사이언티스트의 하루
실리콘 밸리 데이터 사이언티스트의 하루
 
어떻게 하면 데이터 사이언티스트가 될 수 있나요?
어떻게 하면 데이터 사이언티스트가 될 수 있나요?어떻게 하면 데이터 사이언티스트가 될 수 있나요?
어떻게 하면 데이터 사이언티스트가 될 수 있나요?
 
데이터는 차트가 아니라 돈이 되어야 한다.
데이터는 차트가 아니라 돈이 되어야 한다.데이터는 차트가 아니라 돈이 되어야 한다.
데이터는 차트가 아니라 돈이 되어야 한다.
 
중국 VR 보고서 - 2016
중국 VR 보고서 - 2016중국 VR 보고서 - 2016
중국 VR 보고서 - 2016
 

Similar to 스프링 부트와 로깅

logback 세미나 발표자료
logback 세미나 발표자료logback 세미나 발표자료
logback 세미나 발표자료JungGeun Lee
 
예제로 쉽게 배우는 Log4j 기초 활용법
예제로 쉽게 배우는 Log4j 기초 활용법예제로 쉽게 배우는 Log4j 기초 활용법
예제로 쉽게 배우는 Log4j 기초 활용법오석 한
 
안드로이드 로그 파일로 남기기
안드로이드 로그 파일로 남기기안드로이드 로그 파일로 남기기
안드로이드 로그 파일로 남기기운용 최
 
ibatis_khhan
ibatis_khhanibatis_khhan
ibatis_khhanohgamja3
 
20130213 jdbc logger
20130213 jdbc logger20130213 jdbc logger
20130213 jdbc loggerSukjin Yun
 
Laravel 로 배우는 서버사이드 #2
Laravel 로 배우는 서버사이드 #2Laravel 로 배우는 서버사이드 #2
Laravel 로 배우는 서버사이드 #2성일 한
 
Open Source Engineering V2
Open Source Engineering V2Open Source Engineering V2
Open Source Engineering V2YoungSu Son
 
Hyperledger farbric build your first network install and analysis
Hyperledger farbric   build your first network install and analysisHyperledger farbric   build your first network install and analysis
Hyperledger farbric build your first network install and analysis병준 김
 
Python study 1강 (오픈소스컨설팅 내부 강의)
Python study 1강 (오픈소스컨설팅 내부 강의)Python study 1강 (오픈소스컨설팅 내부 강의)
Python study 1강 (오픈소스컨설팅 내부 강의)정명훈 Jerry Jeong
 
Golang Restful 서버 개발기
Golang Restful 서버 개발기Golang Restful 서버 개발기
Golang Restful 서버 개발기Hyejong
 
xecon-phpfest2014composer
xecon-phpfest2014composerxecon-phpfest2014composer
xecon-phpfest2014composerjhyeon1010
 
도커(Docker) 메트릭스 & 로그 수집
도커(Docker) 메트릭스 & 로그 수집도커(Docker) 메트릭스 & 로그 수집
도커(Docker) 메트릭스 & 로그 수집Daegwon Kim
 
Eclipse RAP - Single Source
Eclipse RAP - Single SourceEclipse RAP - Single Source
Eclipse RAP - Single Sourcecho hyun jong
 
Introduction to Golang
Introduction to GolangIntroduction to Golang
Introduction to GolangHyejong
 
Jdk(java) 7 - 5. invoke-dynamic
Jdk(java) 7 - 5. invoke-dynamicJdk(java) 7 - 5. invoke-dynamic
Jdk(java) 7 - 5. invoke-dynamicknight1128
 

Similar to 스프링 부트와 로깅 (20)

logback 세미나 발표자료
logback 세미나 발표자료logback 세미나 발표자료
logback 세미나 발표자료
 
예제로 쉽게 배우는 Log4j 기초 활용법
예제로 쉽게 배우는 Log4j 기초 활용법예제로 쉽게 배우는 Log4j 기초 활용법
예제로 쉽게 배우는 Log4j 기초 활용법
 
Easyloggingpp
EasyloggingppEasyloggingpp
Easyloggingpp
 
안드로이드 로그 파일로 남기기
안드로이드 로그 파일로 남기기안드로이드 로그 파일로 남기기
안드로이드 로그 파일로 남기기
 
Ibatis
IbatisIbatis
Ibatis
 
ibatis_khhan
ibatis_khhanibatis_khhan
ibatis_khhan
 
20130213 jdbc logger
20130213 jdbc logger20130213 jdbc logger
20130213 jdbc logger
 
Laravel 로 배우는 서버사이드 #2
Laravel 로 배우는 서버사이드 #2Laravel 로 배우는 서버사이드 #2
Laravel 로 배우는 서버사이드 #2
 
Open Source Engineering V2
Open Source Engineering V2Open Source Engineering V2
Open Source Engineering V2
 
Hyperledger farbric build your first network install and analysis
Hyperledger farbric   build your first network install and analysisHyperledger farbric   build your first network install and analysis
Hyperledger farbric build your first network install and analysis
 
Python study 1강 (오픈소스컨설팅 내부 강의)
Python study 1강 (오픈소스컨설팅 내부 강의)Python study 1강 (오픈소스컨설팅 내부 강의)
Python study 1강 (오픈소스컨설팅 내부 강의)
 
Log4j 사용법
Log4j 사용법Log4j 사용법
Log4j 사용법
 
Jdk 7 3-nio2
Jdk 7 3-nio2Jdk 7 3-nio2
Jdk 7 3-nio2
 
Golang Restful 서버 개발기
Golang Restful 서버 개발기Golang Restful 서버 개발기
Golang Restful 서버 개발기
 
xecon-phpfest2014composer
xecon-phpfest2014composerxecon-phpfest2014composer
xecon-phpfest2014composer
 
도커(Docker) 메트릭스 & 로그 수집
도커(Docker) 메트릭스 & 로그 수집도커(Docker) 메트릭스 & 로그 수집
도커(Docker) 메트릭스 & 로그 수집
 
Oracle History #8
Oracle History #8Oracle History #8
Oracle History #8
 
Eclipse RAP - Single Source
Eclipse RAP - Single SourceEclipse RAP - Single Source
Eclipse RAP - Single Source
 
Introduction to Golang
Introduction to GolangIntroduction to Golang
Introduction to Golang
 
Jdk(java) 7 - 5. invoke-dynamic
Jdk(java) 7 - 5. invoke-dynamicJdk(java) 7 - 5. invoke-dynamic
Jdk(java) 7 - 5. invoke-dynamic
 

스프링 부트와 로깅

  • 3. 스프링 부트와 로깅 • 스프링 부트는 JCL을 사용하여 로깅 코드를 작성한다. • 스프링 부트 애플리케이션은 SLF4J를 사용한다. • 스프링 부트 애플리케이션은 Logback을 사용한다. • 원한다면 얼마든지 다른 로거를 사용할 수 있다.
  • 4. 스프링 부트 소스 코드 import org.apache.commons.logging.Log;
 import org.apache.commons.logging.LogFactory; ! ... ! private final Log log = LogFactory.getLog(getClass()); ! ... ! if (this.log.isDebugEnabled()) {
 this.log.debug("Loading source "
 + StringUtils.arrayToCommaDelimitedString(sources));
 } 아파치(자카르타) 커먼스 로깅을 줄여서 JCL이라고 부릅니다. http://commons.apache.org/proper/commons-logging/
  • 5. JCL (commons-logging) • 로깅 라이브러리가 아니라 로깅 추상화 라이브러리다. • 로깅 라이브러리 선택권은 애플리케이션 개발자의 것이 다. • 따라서 라이브러리나 프레임워크는 주로 로깅 추상화 라 이브러리를 사용한다. Log Log4J
  • 6. JCL이 로깅 구현체를 찾는 방법 • 설정 파일에서 찾기 • 애플리케이션 클래스패스에서 Log4J 구현체 찾아보기 • 애플리케이션이 JDK 1.4에서 구동중인지 확인하기 • 아무것도 못찾으면 기본 구현체 사용 로깅 구현체 찾는 방법 http://commons.apache.org/proper/commons-logging/ guide.html#Configuration
  • 7. JCL을 꺼리는 이유 • 자바 클래스로더의 기본 동작 방식 • 서블릿 컨테이너의 클래스로더 동작 방식 • JCL은 클래스로더에 의존적인 방법으로 구현체를 찾는다. JCL 사용시 겪을 수 있는 클래스로더 문제 http://articles.qos.ch/classloader.html ! JCL 사용시 겪을 수 있는 메모리 누수 문제 http://wiki.apache.org/commons/Logging/UndeployMemoryLeak ! 스프링 개발자 Dave Syer, ‘과거로 돌아갈 수 있다면…’ http://spring.io/blog/2009/12/04/logging-dependencies-in-spring/ !
  • 8. SLF4J • Simple Logging Facade For Java • 로깅 라이브러리를 런타임이 아닌 컴파일 타임에 정한다. • 세가지 모듈(Bridging, API, Binding) 제공
  • 9. SLF4J API • 로깅 인터페이스 • slf4j-api-{version}.jar • org.slf4j.Logger • org.slf4j.LoggerFactory API
  • 10. SLF4J API import org.slf4j.Logger;
 import org.slf4j.LoggerFactory; ! ... ! Logger logger = LoggerFactory.getLogger(getClass()); logger.info("Loading source {}“, source); ! ... SLF4J API FAQ http://www.slf4j.org/faq.html#string_or_object
  • 11. SLF4J Binding • SLF4J 인터페이스를 로깅 구현체로 연결 • 어댑터 역할. • SLF4J 인터페이스를 직접 구현한 구현체도 있다. • 라이브러리나 프레임워크는 사용하지 마세요. Binding
  • 12. SLF4J Binding • 여러 바인딩 중 반드시 한개만 사용할 것 • slf4j-log4j12-{version}.jar • slf4j-jdk14-{version}.jar • slf4j-nop-{version}.jar • slf4j-jcl-{version}.jar • logback-classic-{logback-version}.jar Binding API
  • 13. SLF4J Binding • 여러 바인딩을 클래스패스 두면? SLF4J: Class path contains multiple SLF4J bindings. SLF4J: Found binding in [jar:file:/Users/naver/.m2/ repository/ch/qos/logback/logback-classic/1.1.2/logback- classic-1.1.2.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: Found binding in [jar:file:/Users/naver/.m2/ repository/org/slf4j/slf4j-jdk14/1.7.8/slf4j- jdk14-1.7.8.jar!/org/slf4j/impl/StaticLoggerBinder.class] SLF4J: See http://www.slf4j.org/codes.html#multiple_bindings for an explanation. SLF4J: Actual binding is of type [ch.qos.logback.classic.util.ContextSelectorStaticBinder] http://www.slf4j.org/codes.html#multiple_bindings
  • 14. SLF4J Bridge • 로거 호출을 SLF4J 인터페이스로 연결 • 예) Log4J -> SLF4J API • 어떤 컴포넌트가 구체적인 로거에 의존하면서 고쳐줄 기 미가 보이지 않는다면… • 해당 로거 호출을 대신 받아서 SLF4J API를 호출해준 다. Bridge
  • 15. JCL 호출을 SLF4J로 연결하기 • 의존성에 jcl-over-slf4j.jar 추가 • JCL 호출을 받아서 SLF4J API 호출 • JCL 인터페이스를 구현하고 있다. • 의존성에서 commons-logging.jar 제거. • slf4j-jcl.jar랑 같이 쓰면 안돼요. • 무한 루프 Bridge API JCL
  • 16. Log4J 호출을 SLF4J로 연결하기 • log4j-over-slf4j.jar 추가 • Log4J 호출을 받아서 SLF4J API 호출 • Log4J 인터페이스를 구현하고 있다. • 의존성에서 log4j.jar 제거. • slf4j-log4j12.jar랑 같이 쓰면 안돼요. • 무한 루프 Bridge API Log4J
  • 17. JUL 호출을 SLF4J로 연결하기 • jul-to-slf4j.jar 추가 • java.util.logging은 교체 불가능 • LogRecord 객체를 사용해서 위임. • slf4j-jdk14.jar랑 같이 쓰면 안돼요. • 무한 루프 Bridge API JUL
  • 18. 동종 브릿지와 바인딩을 같이 쓰면 어떻게 되나? Bridge APILog4J Binding log4j-over-slf4j slf4j-api slf4j-log4j log4j api 호출
  • 19. 모든 로깅을 Logback으로 하려면? Bridge API BindingLogback log4j / jul / jcl 호출 log4j-over-slf4j jcl-over-slf4j jul-to-slf4j logback-classic
  • 20. 스프링 부트 로깅 • spring-boot-starter-web <dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-logging</artifactId>
 </dependency>
 <dependency>
 <groupId>org.springframework</groupId>
 <artifactId>spring-core</artifactId>
 <exclusions>
 <exclusion>
 <groupId>commons-logging</groupId>
 <artifactId>commons-logging</artifactId>
 </exclusion>
 </exclusions>
 </dependency>
  • 21. 스프링 부트 로깅 • spring-boot-starter-logging <dependency>
 <groupId>org.slf4j</groupId>
 <artifactId>jcl-over-slf4j</artifactId>
 </dependency>
 <dependency>
 <groupId>org.slf4j</groupId>
 <artifactId>jul-to-slf4j</artifactId>
 </dependency>
 <dependency>
 <groupId>org.slf4j</groupId>
 <artifactId>log4j-over-slf4j</artifactId>
 </dependency>
 <dependency>
 <groupId>ch.qos.logback</groupId>
 <artifactId>logback-classic</artifactId>
 </dependency>
  • 22. 스프링 부트 로깅 • 스붓 애플리케이션에서 JCL, JUL, Log4J를 사용해도 • JCL, JUL, Log4J용 브릿지가 있으니까 • 모든 로깅 메서드 호출은 SLF4J-API를 호출하게 되고 • Logback용 바인딩에 있으니까 • 결국 Logback을 사용해서 로깅한다.
  • 24. 스프링 부트 로그 포맷 2015-04-09 21:28:24.475 INFO 37267 --- [ main] me.whiteship.Application : Started Application in 4.178 seconds (JVM running for 5.396) • 날짜와 시간: 밀리초 단위까지 출력하며 이 정보를 가지고 로그를 정렬할 수 있다. • 로그 레벨: ERROR, WARN, INFO, DEBUG, TRACE 중 하나. • 프로세스 ID • ---: 로그 메시지 시작 구분자 • 쓰레드 이름 • 로거 이름: 보통 클래스 이름인데 패키지 이름은 축약해서 출력하기도 한다. • 로그 메시지
  • 26. 콘솔 출력 • DEBUG 레벨로 출력하고 싶다면 • java -jar app.jar --debug • spring.output.ansi.enabled 설정 • ANSI를 지원하는 터미널에서는 콘솔에 색을 적용할 수 있다. • ALWAYS, DETECT, NEVER 중에 선택해서 사용
  • 28. 파일 출력 • logging.file, logging.path 설정을 사용해야 파일 출력 을 사용할 수 있다. • 10M 단위로 로그 파일을 새로 만든다.
  • 29. logging 설정 logging.path logging.file 예 설명 없음 없음 콘솔 출력만 사용 있음 없음 ./logs/ 현재 디렉토리 아래 logs라는 디렉토리 안에 spring.log라는 파일에 로그를 남긴다. 없음 있음 ./logs/spring- boot-ri.log 현재 디렉토리 아래 logs라는 디렉토리 안에 spring-boot-ri.log라는 파일에 로그를 남긴다. 있음 있음 logging.path 설정은 무시하고 logging.file 설정 을 사용한다.
  • 31. 로그 레벨 • logging.level.{패키지} = {로그 레벨} • 패키지 별로 로그 레벨을 설정할 수 있다. • TRACE, DEBUG, INFO, WARN, ERROR, FATAL, OFF 지원 • 예) 스프링 MVC 관련 로그만 DEBUG 수준으로 보고 다른 로그 는 보고 싶지 않다면 다음과 같이 설정할 수 있다. • logging.level.org.springframework = OFF • logging.level.org.springframework.web = DEBUG
  • 33. 커스텀 로그 설정 • 직접 만든 로그 설정 파일을 클래스패스 루트에 두거나 • logging.config로 로그 설정 파일 위치를 설정한다.
  • 34. 커스텀 로그 설정 로깅 시스템 설정 파일 Logback logback.xml 또는 logback.groovy Log4j log4j.properties 또는 log4j.xml Log4j2 log4j2.xml JDK (Java Util Logging) logging.properties
  • 35. 스프링 부트 로깅 기본 로그 설정 파일
  • 36. 기본 로그 설정 • 스프링 부트는 지금까지 살펴본 로깅 기능을 기본 설정으 로 제공한다. • org.springframework.boot.logging 패키지 코드 참고.
  • 38. Log4j(2) 사용하기 • spring-boot-starter-logging 의존성 제거 • spring-boot-starter-log4j(2) 의존성 추가 <dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter</artifactId>
 <exclusions>
 <exclusion>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-logging</ artifactId>
 </exclusion>
 </exclusions>
 </dependency>
 <dependency>
 <groupId>org.springframework.boot</groupId>
 <artifactId>spring-boot-starter-log4j</artifactId>
 </dependency>