SlideShare ist ein Scribd-Unternehmen logo
1 von 63
예외를 잡고 무언가 했는데, 로그를 남겨야 하나?
로그 레벨은?
어떤 예외 클래스로?
예외 메시지에는 어떤 값을?
예외
발생
걍 아무데서나?
그랬더니 중복
여기 여기
여기
예외
발생
어라 이번엔
누락
예외
발생
여기서?
예외
발생
여기서?
예외
발생
여기서?
예외
발생
여기서?
예외
발생
여기서?
예외
발생
여기서?
예외
발생
예외의 로그 위치가 고민되면 안된다.
이미 정해져 있어야 한다.
시스템을 단순화 하면,
호출받은 이쪽과
호출한 저쪽
예외
발생
이쪽과 저쪽의 구분은
제어 가능 여부
예외
발생
손을 떠났다.
로그를
남기고 싶어도
못남긴다.
저쪽으로 보내기 전에
로그를 남기자.
중복되지도 누락되지도
않는다.
여기
예외
발생
혹은
정상상황으로 처리한 곳에서
로그를 남기자
역시
중복되지도 누락되지도
않는다.
여기
예외
발생
오직 딱 2곳에서만.
• 호출한 저쪽으로 넘기기 직전
• 정상상황으로 처리한 곳
그렇지 않을 경우 로그가 중복되거나 누락될 수 있다.
외부 호출이 아닌 스케쥴링 테스크의 경우는?
외부 호출이 아닌 스케쥴링 테스크의 경우는?
동일하다. JVM, OS 또는 Framework이 호출한 그 지점이 그
경계이다.
여기
예외
발생
JVM, OS,
Framework
• REST 타입의 외부 인터페이스
• 내부 스케쥴링 테스크
Exception Mapper가 예외를 잡
아 적절한 Http Status의 응답을
보낸다. 이 때 로그를 남긴다.
그리고 스케쥴링 테스크에서
로그를 남긴다.
Exception
Mapper
Scheduling
Task
여기
여기
REST type interface
exception mapper를 설정하여 HTTP 응답과 로그를 처리.
Exception Class HTTP Response Status
UserNotFoundException BAD_REQUEST(400)
InvalidParameterException BAD_REQUEST(400)
WebApplicatoinExceptoin(by Jersey) NOT_FOUND(404)
Throwable INTERNAL_SERVER_ERROR(500)
@Provider
public class InvalidParameterExceptionMapper implements ExceptionMapper<InvalidParameterException> {
@Override
public Response toResponse(InvalidParameterException exception) {
logger.debug(“request of invalid parameter.”, exception);
return Response.status(Status.BAD_REQUEST).build();
}
}
InvalidParameterException이 던져지면 BAD_REQUEST(400)의 응답
을 보낸다.
@Provider
public class DefaultExceptionMapper implements ExceptionMapper<Throwable> {
@Override
public Response toResponse(Throwable exception) {
logger.error(“unhandled exception.”, exception);
return Response.status(Status.INTERNAL_SYSTEM_ERROR).build();
}
}
다른 exception mapper에 의해 처리되지 못한 모든 Throwable에 대
하여 INTERNAL_SYSTEM_ERROR(500)의 응답을 보낸다.
@Service
public class SomeScheduledTask {
@Scheduled
public void process() {
try {
…
} catch(SomeException e) {
logger.warn(...);
} catch(Throwable e) {
logger.error(...);
}
}
}
process() 메소드가 저어쪽 Spring에 호출되는 지점이다.
이 경우 일반 예외뿐 아니라 Throwable로 다 잡고 있다.
• Info : 운영자에게 보이기 위한 정보.
• debug : 디버깅을 위한 내용.
• warn : 예외는 아니나, 추후 문제가 될 수 있는.
• error : 예외가 발생했으나, 정상 처리.
• fatal : 예외가 발생했고, 정상처리 못함.
예
• 8080 포트로 서버가 시작됨.
• 백업 스케쥴러가 완료됨.
• DB와 특정 url로 연결됨.
• 설정파일 some.properties를 /some/path에서 읽음.
오직 개발자의 디버깅을 위한.
내용에 제약 없다.
많아도 괜찮다.
예
• 파일 여유 공간이 10% 이하.
• 값은 있으나 사용하지 않는 설정.
예
• 디비 연결이 끊겼으나 재연결하여 처리
• 설정 값이 없어서 default 값으로 처리
예
• 디비 연결이 끊어지고 재연결 안되어 처리 못함.
• null이 될 수 없는 값이 null이어서 처리 못함.
• 사용자의 입력이 잘못되어 던져진 예외.
• NullPointerException.
• RuntimeException.
• 예외가 던져졌는데 정말 예외 상황은 아니다.
사용자의 입력이 잘못되어 던져진 예외
• 예외라 하더라도 warn의 수준도 아니다.
• 하지만 debug 정도는 괜찮겠다.
• 대신 로그 설정이 가능하도록 별개의 로거가 있어야.
NullPointerException
• 무조건 bug다.
• JVM은 NPE가 발생하면 해당 thread를 종료시킨다.
• 그렇다면 warn이상이고, fatal 혹은 error이다.
RuntimeException
• 역시 JVM은 해당 thread를 종료시킨다.
• fatal이다.
예외가 던져졌는데 정말 예외 상황은 아니다.
• 메소드 설계가 잘못된 경우.
• 예외를 던지면 안된다.
외부 인증 서버로 요청하여 인증을 처리한다.
• 외부 인증 서버의 접속 정보를 설정 파일에서 얻는다.
• 외부 인증 서버로 REST 요청을 하여 응답을 받는다.
• id와 password를 입력으로 받는다.
• id 존재 여부, password 틀림 여부를 알려주어야 한다.
• 인증된 경우 인증 토큰을 반환한다.
• 외부 인증 서버의 접속 정보를 읽지 못한다.
• 외부 인증 서버로 접속이 되지 않는다.
• 외부 인증 서버로 접속은 되었으나 응답이 없다.
• 외부 인증 서버로 응답을 받았으나 5초 지나서 받았다.
• timeout 이후 재시도 하여 응답을 받았다.
• 외부 인증 서버로 요청되어 응답을 받았으나 잘못된 형식.
• id가 존재 하지 않는다.
• password가 틀리다.
상황 던지는 예외 예외 처리 주체 로그 레벨 처리
인증서버의 접속 정보
를 읽지 못한다.
SystemFailException
(extends RuntimeException)
Exception Handler FATAL 시스템 종료
인증서버로 접속이 되
지 않는다.
AuthSystemFailException
(extends RuntimeException)
Exception Handler ERROR 500 응답
인증서버로 접속은 되
었으나 응답이 없다.
AuthSystemFailException
(extends RuntimeException)
Exception Handler ERROR 500 응답
응답을 받았으나 5초
지나서 받았다.
던지지 않는다. 모듈 내부 WARN 정상 처리
timeout 이후 재시도
하여 응답을 받았다.
던지지 않는다. 모듈 내부 WARN 정상 처리
응답을 받았으나 잘못
된 형식.
AuthSystemFailException
(extends RuntimeException)
Exception Handler ERROR 500 응답
id가 존재 하지 않는
다는 응답.
AuthFailException
호출한 모듈.
InvalidInputException으로 다시 던진다.
DEBUG 400 응답
password가 틀리다는
응답.
AuthFailException 위와 동일 DEBUG 400 응답
상황 예외 메시지 or 로그 메시지 or 처리 상세
인증서버의 접속 정보를 읽지 못한다. “loading auth server info failed. properties file=/some/path/…”.
인증서버로 접속이 되지 않는다. “connecting auth server failed. connection info=http://some.url”
인증서버로 접속은 되었으나 응답이 없다. “getting response from auth server failed. connection info=….”
응답을 받았으나 5초 지나서 받았다. “got response from auth server, but too long response time. time=10.3 sec.”
timeout 이후 재시도 하여 응답을 받았다. “get response after 1 timeout. connection info=…”
응답을 받았으나 잘못된 형식. “parsing message failed. message=…”
id가 존재 하지 않는다는 응답.
AuthFailException를 던질 때 NOT_EXIST_ID를 설정한다.
400로 반환할 때 NOT_EXIST_ID를 설정.
password가 틀리다는 응답.
AuthFailException를 던질 때 INCORRECT_PASSWORD를 설정한다.
400로 반환할 때 INCORRECT_PASSWORD를 설정.
모두 다음의 3가지 예외를 던진다.
• SystemFailException – 구동 불가
• AuthSystemFailException – 장애 발생 상황. 하지만 계속 구동.
• AuthFailException – 호출한 곳에서 잡아서 처리한다.
예외 상황을 처리하기 위해서는 시스템 전체적으로 다음이
전제되어야 한다.
• SystemFailException이 발생하면 FATAL 로그를 남기고 시스템 구동 중지
• AuthSystemFailException이 던져지면 ERROR 로그를 남기고 500 응답
• 이외 모든 RuntimeException이 던져지면 ERROR 로그를 남기고 500응답.
즉 시스템 전체적인 정책 혹은 아키텍쳐가 마련되어 있어야
한다.
모듈 설계 시에 포함되어야 한다.
try {
authToken = authManager.getAuthToken(id, password);
} catch(AuthFailException e) {
throw new InvalidInputException("invalid auth info", e.getErrorCode(), e);
}
오직 AuthFailException만 잡으면 된다.
다른 두 예외는 RuntimeException을 상속받았다.
잘못된 입력값을 전달하기 위한 getErrorCode() 메소드가 선
언되어 있다.
받는 쪽에서 처리하기에 불편하지 않게 던진다.
• 시스템 관련된 예외는 따로 잡지 않도록 RuntimeException으로 던졌다.
• FATAL과 ERROR를 구분하기 위해 SystemFailException과
AuthSystemFailException으로 구분해서 던졌다.
• ERROR 상황이지만 극복된 경우 로그만 남기고 예외를 던지지 않았다.
• 잘못된 입력을 구분하기 위해 getErrorCode() 메소드를 AuthFailException에
선언하였다.
RuntimeException을 상속한 예외 클래스로 던지면 매 호출
stack에서 명시적으로 잡지 않아도 된다.
최종 exception handler에서만 잡아서 처리하면 된다.
단 최종 exception handler가 반드시 있어야 한다.
문제가 발생하면 DEBUG 수준의 로그를 봐야 한다.
로거 설정 변경을 위해 시스템을 재구동하기는 어렵다.
logback의 경우 파일의 변경을 감지하여 반영한다.
(기존 log4j 등은 그러하지 못했다.)
혹은 JMX를 사용하여 로거 레벨을 동적으로 변경가능하도
록 하자.
debug 레벨의 로깅은 무척이나 많다.
전부 같은 이름이면, debug 레벨로 변경시 어마어마한 양의
로그가 쌓인다.
각 기능별로 로거를 분리해서 필요 부분만 레벨을 조정할
수 있도록.
요즘은 클래스의 이름을 로거 이름으로 하는 경우가 대세.
Logger logger = LogManager.getLogger(SomeDao.class);
클래스의 패키지까지 로거의 이름이 된다.
이 경우 계층적으로 로거를 설정할 수 있다.
<logger name=“some” level=“warn”/>
<logger name=“some.component” level=“debug”/>
<logger name=“some.component.dao” level=“warn”/>
• 다음 2가지 이유로 권장.
• 불필요한 String 연산 제거(by SLF4J)
• 동적 설정 변경(by LogBack)
• 불필요한 String 연산 방지
logger.debug(“userId=“+userId);
logger.debug(“userId={}”, userId);
• SLF4J는 다양한 로거에 관계없이 동일한 사용방법을 제공.
단지 진짜 사용하는 로거를 호출해 준다.
• 가장 많이 사용하는 Log4J의 다음 버전(개발자가 동일)
• 설정 파일이 동일
• 성능 훨씬 우월
• 로거 설정 파일의 default는 logback.xml 혹은 log4j.xml
• 그런데 가져다 사용하는 라이브러리 jar안에 해당 파일이
있으면, 그 설정 파일이 사용될 수 있다.
• 설정 파일 이름을 달리하고, 그 이름을 명시하자.
Java의 JUL(Java Util Logging)
java.util.logging.LogManager.getLogManager().reset();
org.slf4j.bridge.SLF4JBridgeHandler.install();
java.util.logging.Logger.getLogger("").setLevel(java.util.logging.Level.FINEST);
refer http://www.slf4j.org/legacy.html#jul-to-slf4j
Apache의 JCL(Java Commons Logging)
단지 commons-logging.jar를 jcl-over-slf4j.jar로 대체
refer http://www.slf4j.org/legacy.html#jcl-over-slf4j
System.out.println() 처럼 사용하지 말자.
로깅 코드는 삭제하지 않는다. 설치 이후에도 사용된다.
코딩 시에는 찍히는 값이 뭔지 알 수 있지만, 수 많은 로그에
서는 그 값이 무엇인지 모른다. 무언지 알 수 있어야 한다.
logger.debug(userId); // 추후에 값 만으로는 파악이 안된다.
logger.debug(“userId={}”, userId);
엔티티 전체를 로그로 찍자.
logger.debug(“userId={}”, request.getUserId()); // 이러지 말고
속성 이름은 변경되고 추가되고 삭제된다. 하지만 로깅 코드
는 업데이트 안된다.
logger.debug(“request={}”, request);
이를 위해서는 toString()이 구현되어야 한다.
Apache commons의 ToStringBuilder
@Override
public String toString() {
return ToStringBuilder.reflectionToString(this, …);
}
로그의 목적은 문제 파악이다.
예외의 stacktrace가 잔뜩 찍히는 것은 문제 해결의 축복이
다.
debug 로그가 많은 것은 단지 레벨 설정으로 처리된다.
logger.debug("request={}", request);
logger.debug("context={}", context);
logger.debug("binder={}", binder);
여러 개의 로그가 한번에 모여서 찍힌다는 보장은 없다.
multi thread 상황에서는 더더욱 그렇다.
logger.debug("request={}, context={}, binder={}",
request, context, binder);
Exception log practical_coding_guide, 예외와 로그 코딩 실용 가이드

Weitere ähnliche Inhalte

Was ist angesagt?

Goでかんたんソースコードの静的解析
Goでかんたんソースコードの静的解析Goでかんたんソースコードの静的解析
Goでかんたんソースコードの静的解析Takuya Ueda
 
JUnit & Mockito, first steps
JUnit & Mockito, first stepsJUnit & Mockito, first steps
JUnit & Mockito, first stepsRenato Primavera
 
[143] Modern C++ 무조건 써야 해?
[143] Modern C++ 무조건 써야 해?[143] Modern C++ 무조건 써야 해?
[143] Modern C++ 무조건 써야 해?NAVER D2
 
Visual C++で使えるC++11
Visual C++で使えるC++11Visual C++で使えるC++11
Visual C++で使えるC++11nekko1119
 
새해 일어난 일
새해 일어난 일새해 일어난 일
새해 일어난 일Eunhyang Kim
 
[OKKYCON] 정진욱 - 테스트하기 쉬운 코드로 개발하기
[OKKYCON] 정진욱 - 테스트하기 쉬운 코드로 개발하기[OKKYCON] 정진욱 - 테스트하기 쉬운 코드로 개발하기
[OKKYCON] 정진욱 - 테스트하기 쉬운 코드로 개발하기OKKY
 
Super Keyword in Java.pptx
Super Keyword in Java.pptxSuper Keyword in Java.pptx
Super Keyword in Java.pptxKrutikaWankhade1
 
Windows IOCP vs Linux EPOLL Performance Comparison
Windows IOCP vs Linux EPOLL Performance ComparisonWindows IOCP vs Linux EPOLL Performance Comparison
Windows IOCP vs Linux EPOLL Performance ComparisonSeungmo Koo
 
Exception Handling In Java
Exception Handling In JavaException Handling In Java
Exception Handling In Javaparag
 
Best Practices in Exception Handling
Best Practices in Exception HandlingBest Practices in Exception Handling
Best Practices in Exception HandlingLemi Orhan Ergin
 
L14 exception handling
L14 exception handlingL14 exception handling
L14 exception handlingteach4uin
 
KSUG 스프링캠프 2019 발표자료 - "무엇을 테스트할 것인가, 어떻게 테스트할 것인가"
KSUG 스프링캠프 2019 발표자료 - "무엇을 테스트할 것인가, 어떻게 테스트할 것인가"KSUG 스프링캠프 2019 발표자료 - "무엇을 테스트할 것인가, 어떻게 테스트할 것인가"
KSUG 스프링캠프 2019 발표자료 - "무엇을 테스트할 것인가, 어떻게 테스트할 것인가"용근 권
 
제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화
제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화
제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화sung ki choi
 
Migrating to Java 11
Migrating to Java 11Migrating to Java 11
Migrating to Java 11Arto Santala
 
Java exception handling ppt
Java exception handling pptJava exception handling ppt
Java exception handling pptJavabynataraJ
 

Was ist angesagt? (20)

Goでかんたんソースコードの静的解析
Goでかんたんソースコードの静的解析Goでかんたんソースコードの静的解析
Goでかんたんソースコードの静的解析
 
Hacking Wordpress Plugins
Hacking Wordpress PluginsHacking Wordpress Plugins
Hacking Wordpress Plugins
 
Java8 features
Java8 featuresJava8 features
Java8 features
 
Java Logging
Java LoggingJava Logging
Java Logging
 
JUnit & Mockito, first steps
JUnit & Mockito, first stepsJUnit & Mockito, first steps
JUnit & Mockito, first steps
 
[143] Modern C++ 무조건 써야 해?
[143] Modern C++ 무조건 써야 해?[143] Modern C++ 무조건 써야 해?
[143] Modern C++ 무조건 써야 해?
 
Visual C++で使えるC++11
Visual C++で使えるC++11Visual C++で使えるC++11
Visual C++で使えるC++11
 
Logback
LogbackLogback
Logback
 
새해 일어난 일
새해 일어난 일새해 일어난 일
새해 일어난 일
 
[OKKYCON] 정진욱 - 테스트하기 쉬운 코드로 개발하기
[OKKYCON] 정진욱 - 테스트하기 쉬운 코드로 개발하기[OKKYCON] 정진욱 - 테스트하기 쉬운 코드로 개발하기
[OKKYCON] 정진욱 - 테스트하기 쉬운 코드로 개발하기
 
Super Keyword in Java.pptx
Super Keyword in Java.pptxSuper Keyword in Java.pptx
Super Keyword in Java.pptx
 
Windows IOCP vs Linux EPOLL Performance Comparison
Windows IOCP vs Linux EPOLL Performance ComparisonWindows IOCP vs Linux EPOLL Performance Comparison
Windows IOCP vs Linux EPOLL Performance Comparison
 
Exception Handling In Java
Exception Handling In JavaException Handling In Java
Exception Handling In Java
 
Best Practices in Exception Handling
Best Practices in Exception HandlingBest Practices in Exception Handling
Best Practices in Exception Handling
 
L14 exception handling
L14 exception handlingL14 exception handling
L14 exception handling
 
KSUG 스프링캠프 2019 발표자료 - "무엇을 테스트할 것인가, 어떻게 테스트할 것인가"
KSUG 스프링캠프 2019 발표자료 - "무엇을 테스트할 것인가, 어떻게 테스트할 것인가"KSUG 스프링캠프 2019 발표자료 - "무엇을 테스트할 것인가, 어떻게 테스트할 것인가"
KSUG 스프링캠프 2019 발표자료 - "무엇을 테스트할 것인가, 어떻게 테스트할 것인가"
 
제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화
제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화
제프리 리처의 Windows via C/C++ : 8장 유저 모드에서의 스레드 동기화
 
Exception handling in Java
Exception handling in JavaException handling in Java
Exception handling in Java
 
Migrating to Java 11
Migrating to Java 11Migrating to Java 11
Migrating to Java 11
 
Java exception handling ppt
Java exception handling pptJava exception handling ppt
Java exception handling ppt
 

Andere mochten auch

알고리즘 문제해결전략 #1
알고리즘 문제해결전략 #1알고리즘 문제해결전략 #1
알고리즘 문제해결전략 #1Byeongsu Kang
 
코딩소림사 Rx java
코딩소림사 Rx java코딩소림사 Rx java
코딩소림사 Rx javaByeongsu Kang
 
멸종하는 공룡이 되지 않으려면
멸종하는 공룡이 되지 않으려면멸종하는 공룡이 되지 않으려면
멸종하는 공룡이 되지 않으려면Byeongsu Kang
 
Aws summit 2017 사내전파교육
Aws summit 2017 사내전파교육Aws summit 2017 사내전파교육
Aws summit 2017 사내전파교육Byeongsu Kang
 
Kth개발자 세미나 1회
Kth개발자 세미나 1회Kth개발자 세미나 1회
Kth개발자 세미나 1회Byeongsu Kang
 
Scala dreaded underscore
Scala dreaded underscoreScala dreaded underscore
Scala dreaded underscoreRUDDER
 
카카오스토리 웹팀의 코드리뷰 경험
카카오스토리 웹팀의 코드리뷰 경험카카오스토리 웹팀의 코드리뷰 경험
카카오스토리 웹팀의 코드리뷰 경험Ohgyun Ahn
 
Webservice cache strategy
Webservice cache strategyWebservice cache strategy
Webservice cache strategyDaeMyung Kang
 
세션4. 예제로 배우는 스마트 컨트랙트 프로그래밍
세션4. 예제로 배우는 스마트 컨트랙트 프로그래밍세션4. 예제로 배우는 스마트 컨트랙트 프로그래밍
세션4. 예제로 배우는 스마트 컨트랙트 프로그래밍Jay JH Park
 
세션3. geth 클라이언트 실습 및 모니터링과 시각화
세션3. geth 클라이언트 실습 및 모니터링과 시각화세션3. geth 클라이언트 실습 및 모니터링과 시각화
세션3. geth 클라이언트 실습 및 모니터링과 시각화Jay JH Park
 
Bitcoin 2.0(blockchain technology 2)
Bitcoin 2.0(blockchain technology 2)Bitcoin 2.0(blockchain technology 2)
Bitcoin 2.0(blockchain technology 2)Wooseung Kim
 
세션5. web3.js와 Node.js 를 사용한 dApp 개발
세션5. web3.js와 Node.js 를 사용한 dApp 개발세션5. web3.js와 Node.js 를 사용한 dApp 개발
세션5. web3.js와 Node.js 를 사용한 dApp 개발Jay JH Park
 
세션2. 이더리움 합의 알고리즘과 마이닝
세션2. 이더리움 합의 알고리즘과 마이닝세션2. 이더리움 합의 알고리즘과 마이닝
세션2. 이더리움 합의 알고리즘과 마이닝Jay JH Park
 
세션1. block chain as a platform
세션1. block chain as a platform세션1. block chain as a platform
세션1. block chain as a platformJay JH Park
 
텐서플로우 설치도 했고 튜토리얼도 봤고 기초 예제도 짜봤다면 TensorFlow KR Meetup 2016
텐서플로우 설치도 했고 튜토리얼도 봤고 기초 예제도 짜봤다면 TensorFlow KR Meetup 2016텐서플로우 설치도 했고 튜토리얼도 봤고 기초 예제도 짜봤다면 TensorFlow KR Meetup 2016
텐서플로우 설치도 했고 튜토리얼도 봤고 기초 예제도 짜봤다면 TensorFlow KR Meetup 2016Taehoon Kim
 
지적 대화를 위한 깊고 넓은 딥러닝 PyCon APAC 2016
지적 대화를 위한 깊고 넓은 딥러닝 PyCon APAC 2016지적 대화를 위한 깊고 넓은 딥러닝 PyCon APAC 2016
지적 대화를 위한 깊고 넓은 딥러닝 PyCon APAC 2016Taehoon Kim
 
딥러닝과 강화 학습으로 나보다 잘하는 쿠키런 AI 구현하기 DEVIEW 2016
딥러닝과 강화 학습으로 나보다 잘하는 쿠키런 AI 구현하기 DEVIEW 2016딥러닝과 강화 학습으로 나보다 잘하는 쿠키런 AI 구현하기 DEVIEW 2016
딥러닝과 강화 학습으로 나보다 잘하는 쿠키런 AI 구현하기 DEVIEW 2016Taehoon Kim
 
알아두면 쓸데있는 신기한 강화학습 NAVER 2017
알아두면 쓸데있는 신기한 강화학습 NAVER 2017알아두면 쓸데있는 신기한 강화학습 NAVER 2017
알아두면 쓸데있는 신기한 강화학습 NAVER 2017Taehoon Kim
 
책 읽어주는 딥러닝: 배우 유인나가 해리포터를 읽어준다면 DEVIEW 2017
책 읽어주는 딥러닝: 배우 유인나가 해리포터를 읽어준다면 DEVIEW 2017책 읽어주는 딥러닝: 배우 유인나가 해리포터를 읽어준다면 DEVIEW 2017
책 읽어주는 딥러닝: 배우 유인나가 해리포터를 읽어준다면 DEVIEW 2017Taehoon Kim
 

Andere mochten auch (20)

알고리즘 문제해결전략 #1
알고리즘 문제해결전략 #1알고리즘 문제해결전략 #1
알고리즘 문제해결전략 #1
 
코딩소림사 Rx java
코딩소림사 Rx java코딩소림사 Rx java
코딩소림사 Rx java
 
멸종하는 공룡이 되지 않으려면
멸종하는 공룡이 되지 않으려면멸종하는 공룡이 되지 않으려면
멸종하는 공룡이 되지 않으려면
 
알고리즘2
알고리즘2알고리즘2
알고리즘2
 
Aws summit 2017 사내전파교육
Aws summit 2017 사내전파교육Aws summit 2017 사내전파교육
Aws summit 2017 사내전파교육
 
Kth개발자 세미나 1회
Kth개발자 세미나 1회Kth개발자 세미나 1회
Kth개발자 세미나 1회
 
Scala dreaded underscore
Scala dreaded underscoreScala dreaded underscore
Scala dreaded underscore
 
카카오스토리 웹팀의 코드리뷰 경험
카카오스토리 웹팀의 코드리뷰 경험카카오스토리 웹팀의 코드리뷰 경험
카카오스토리 웹팀의 코드리뷰 경험
 
Webservice cache strategy
Webservice cache strategyWebservice cache strategy
Webservice cache strategy
 
세션4. 예제로 배우는 스마트 컨트랙트 프로그래밍
세션4. 예제로 배우는 스마트 컨트랙트 프로그래밍세션4. 예제로 배우는 스마트 컨트랙트 프로그래밍
세션4. 예제로 배우는 스마트 컨트랙트 프로그래밍
 
세션3. geth 클라이언트 실습 및 모니터링과 시각화
세션3. geth 클라이언트 실습 및 모니터링과 시각화세션3. geth 클라이언트 실습 및 모니터링과 시각화
세션3. geth 클라이언트 실습 및 모니터링과 시각화
 
Bitcoin 2.0(blockchain technology 2)
Bitcoin 2.0(blockchain technology 2)Bitcoin 2.0(blockchain technology 2)
Bitcoin 2.0(blockchain technology 2)
 
세션5. web3.js와 Node.js 를 사용한 dApp 개발
세션5. web3.js와 Node.js 를 사용한 dApp 개발세션5. web3.js와 Node.js 를 사용한 dApp 개발
세션5. web3.js와 Node.js 를 사용한 dApp 개발
 
세션2. 이더리움 합의 알고리즘과 마이닝
세션2. 이더리움 합의 알고리즘과 마이닝세션2. 이더리움 합의 알고리즘과 마이닝
세션2. 이더리움 합의 알고리즘과 마이닝
 
세션1. block chain as a platform
세션1. block chain as a platform세션1. block chain as a platform
세션1. block chain as a platform
 
텐서플로우 설치도 했고 튜토리얼도 봤고 기초 예제도 짜봤다면 TensorFlow KR Meetup 2016
텐서플로우 설치도 했고 튜토리얼도 봤고 기초 예제도 짜봤다면 TensorFlow KR Meetup 2016텐서플로우 설치도 했고 튜토리얼도 봤고 기초 예제도 짜봤다면 TensorFlow KR Meetup 2016
텐서플로우 설치도 했고 튜토리얼도 봤고 기초 예제도 짜봤다면 TensorFlow KR Meetup 2016
 
지적 대화를 위한 깊고 넓은 딥러닝 PyCon APAC 2016
지적 대화를 위한 깊고 넓은 딥러닝 PyCon APAC 2016지적 대화를 위한 깊고 넓은 딥러닝 PyCon APAC 2016
지적 대화를 위한 깊고 넓은 딥러닝 PyCon APAC 2016
 
딥러닝과 강화 학습으로 나보다 잘하는 쿠키런 AI 구현하기 DEVIEW 2016
딥러닝과 강화 학습으로 나보다 잘하는 쿠키런 AI 구현하기 DEVIEW 2016딥러닝과 강화 학습으로 나보다 잘하는 쿠키런 AI 구현하기 DEVIEW 2016
딥러닝과 강화 학습으로 나보다 잘하는 쿠키런 AI 구현하기 DEVIEW 2016
 
알아두면 쓸데있는 신기한 강화학습 NAVER 2017
알아두면 쓸데있는 신기한 강화학습 NAVER 2017알아두면 쓸데있는 신기한 강화학습 NAVER 2017
알아두면 쓸데있는 신기한 강화학습 NAVER 2017
 
책 읽어주는 딥러닝: 배우 유인나가 해리포터를 읽어준다면 DEVIEW 2017
책 읽어주는 딥러닝: 배우 유인나가 해리포터를 읽어준다면 DEVIEW 2017책 읽어주는 딥러닝: 배우 유인나가 해리포터를 읽어준다면 DEVIEW 2017
책 읽어주는 딥러닝: 배우 유인나가 해리포터를 읽어준다면 DEVIEW 2017
 

Ähnlich wie Exception log practical_coding_guide, 예외와 로그 코딩 실용 가이드

온라인 게임에서 사례로 살펴보는 디버깅
온라인 게임에서 사례로 살펴보는 디버깅온라인 게임에서 사례로 살펴보는 디버깅
온라인 게임에서 사례로 살펴보는 디버깅Ryan Park
 
자바 웹 개발 시작하기 (7주차 : 국제화, 확인검증, 예외처리)
자바 웹 개발 시작하기 (7주차 : 국제화, 확인검증, 예외처리)자바 웹 개발 시작하기 (7주차 : 국제화, 확인검증, 예외처리)
자바 웹 개발 시작하기 (7주차 : 국제화, 확인검증, 예외처리)DK Lee
 
[스프링 스터디 1일차] 예외 처리
[스프링 스터디 1일차] 예외 처리[스프링 스터디 1일차] 예외 처리
[스프링 스터디 1일차] 예외 처리AnselmKim
 
Scala, Spring-Boot, JPA의 불편하면서도 즐거운 동거
Scala, Spring-Boot, JPA의 불편하면서도 즐거운 동거Scala, Spring-Boot, JPA의 불편하면서도 즐거운 동거
Scala, Spring-Boot, JPA의 불편하면서도 즐거운 동거Javajigi Jaesung
 
임태현, 서버점검 제로에의 도전, NDC2011
임태현, 서버점검 제로에의 도전, NDC2011임태현, 서버점검 제로에의 도전, NDC2011
임태현, 서버점검 제로에의 도전, NDC2011devCAT Studio, NEXON
 
TDD.JUnit.조금더.알기
TDD.JUnit.조금더.알기TDD.JUnit.조금더.알기
TDD.JUnit.조금더.알기Wonchang Song
 
자바야 놀자 PPT
자바야 놀자 PPT자바야 놀자 PPT
자바야 놀자 PPTJinKyoungHeo
 
오버라이딩을 사용한 테스트 시의 설정 처리
오버라이딩을 사용한 테스트 시의 설정 처리오버라이딩을 사용한 테스트 시의 설정 처리
오버라이딩을 사용한 테스트 시의 설정 처리도형 임
 
[아꿈사/110528] 멀티코어cpu이야기 5,6장
[아꿈사/110528] 멀티코어cpu이야기 5,6장[아꿈사/110528] 멀티코어cpu이야기 5,6장
[아꿈사/110528] 멀티코어cpu이야기 5,6장sung ki choi
 
[오픈소스컨설팅]Fault Tolerance Architecture by Netflix
[오픈소스컨설팅]Fault Tolerance Architecture by Netflix[오픈소스컨설팅]Fault Tolerance Architecture by Netflix
[오픈소스컨설팅]Fault Tolerance Architecture by NetflixJi-Woong Choi
 
자바 웹 개발 시작하기 (8주차 : 명세서, 단위테스트, 통합)
자바 웹 개발 시작하기 (8주차 : 명세서, 단위테스트, 통합)자바 웹 개발 시작하기 (8주차 : 명세서, 단위테스트, 통합)
자바 웹 개발 시작하기 (8주차 : 명세서, 단위테스트, 통합)DK Lee
 
Wow hacker Level7 WriteUp
Wow hacker Level7 WriteUpWow hacker Level7 WriteUp
Wow hacker Level7 WriteUphyeok gyu Kwon
 
[NDC08] 최적화와 프로파일링 - 송창규
[NDC08] 최적화와 프로파일링 - 송창규[NDC08] 최적화와 프로파일링 - 송창규
[NDC08] 최적화와 프로파일링 - 송창규ChangKyu Song
 
Tcpl 14장 예외처리
Tcpl 14장 예외처리Tcpl 14장 예외처리
Tcpl 14장 예외처리재정 이
 
0.javascript기본(~3일차내)
0.javascript기본(~3일차내)0.javascript기본(~3일차내)
0.javascript기본(~3일차내)Sung-hoon Ma
 
Codegate 2013 Junior - Music Player Exploit
Codegate 2013 Junior - Music Player ExploitCodegate 2013 Junior - Music Player Exploit
Codegate 2013 Junior - Music Player Exploitsweetchip
 

Ähnlich wie Exception log practical_coding_guide, 예외와 로그 코딩 실용 가이드 (20)

온라인 게임에서 사례로 살펴보는 디버깅
온라인 게임에서 사례로 살펴보는 디버깅온라인 게임에서 사례로 살펴보는 디버깅
온라인 게임에서 사례로 살펴보는 디버깅
 
4-1. javascript
4-1. javascript4-1. javascript
4-1. javascript
 
자바 웹 개발 시작하기 (7주차 : 국제화, 확인검증, 예외처리)
자바 웹 개발 시작하기 (7주차 : 국제화, 확인검증, 예외처리)자바 웹 개발 시작하기 (7주차 : 국제화, 확인검증, 예외처리)
자바 웹 개발 시작하기 (7주차 : 국제화, 확인검증, 예외처리)
 
[스프링 스터디 1일차] 예외 처리
[스프링 스터디 1일차] 예외 처리[스프링 스터디 1일차] 예외 처리
[스프링 스터디 1일차] 예외 처리
 
Scala, Spring-Boot, JPA의 불편하면서도 즐거운 동거
Scala, Spring-Boot, JPA의 불편하면서도 즐거운 동거Scala, Spring-Boot, JPA의 불편하면서도 즐거운 동거
Scala, Spring-Boot, JPA의 불편하면서도 즐거운 동거
 
임태현, 서버점검 제로에의 도전, NDC2011
임태현, 서버점검 제로에의 도전, NDC2011임태현, 서버점검 제로에의 도전, NDC2011
임태현, 서버점검 제로에의 도전, NDC2011
 
TDD.JUnit.조금더.알기
TDD.JUnit.조금더.알기TDD.JUnit.조금더.알기
TDD.JUnit.조금더.알기
 
자바야 놀자 PPT
자바야 놀자 PPT자바야 놀자 PPT
자바야 놀자 PPT
 
Exception&log
Exception&logException&log
Exception&log
 
오버라이딩을 사용한 테스트 시의 설정 처리
오버라이딩을 사용한 테스트 시의 설정 처리오버라이딩을 사용한 테스트 시의 설정 처리
오버라이딩을 사용한 테스트 시의 설정 처리
 
[아꿈사/110528] 멀티코어cpu이야기 5,6장
[아꿈사/110528] 멀티코어cpu이야기 5,6장[아꿈사/110528] 멀티코어cpu이야기 5,6장
[아꿈사/110528] 멀티코어cpu이야기 5,6장
 
System+os study 7
System+os study 7System+os study 7
System+os study 7
 
[오픈소스컨설팅]Fault Tolerance Architecture by Netflix
[오픈소스컨설팅]Fault Tolerance Architecture by Netflix[오픈소스컨설팅]Fault Tolerance Architecture by Netflix
[오픈소스컨설팅]Fault Tolerance Architecture by Netflix
 
자바 웹 개발 시작하기 (8주차 : 명세서, 단위테스트, 통합)
자바 웹 개발 시작하기 (8주차 : 명세서, 단위테스트, 통합)자바 웹 개발 시작하기 (8주차 : 명세서, 단위테스트, 통합)
자바 웹 개발 시작하기 (8주차 : 명세서, 단위테스트, 통합)
 
Wow hacker Level7 WriteUp
Wow hacker Level7 WriteUpWow hacker Level7 WriteUp
Wow hacker Level7 WriteUp
 
[NDC08] 최적화와 프로파일링 - 송창규
[NDC08] 최적화와 프로파일링 - 송창규[NDC08] 최적화와 프로파일링 - 송창규
[NDC08] 최적화와 프로파일링 - 송창규
 
Tcpl 14장 예외처리
Tcpl 14장 예외처리Tcpl 14장 예외처리
Tcpl 14장 예외처리
 
0.javascript기본(~3일차내)
0.javascript기본(~3일차내)0.javascript기본(~3일차내)
0.javascript기본(~3일차내)
 
Codegate 2013 Junior - Music Player Exploit
Codegate 2013 Junior - Music Player ExploitCodegate 2013 Junior - Music Player Exploit
Codegate 2013 Junior - Music Player Exploit
 
Node.js 기본
Node.js 기본Node.js 기본
Node.js 기본
 

Mehr von 도형 임

인공지능과 심리상담
인공지능과 심리상담인공지능과 심리상담
인공지능과 심리상담도형 임
 
Anomaly detection practive_using_deep_learning
Anomaly detection practive_using_deep_learningAnomaly detection practive_using_deep_learning
Anomaly detection practive_using_deep_learning도형 임
 
Deep learning application_to_manufacturing
Deep learning application_to_manufacturingDeep learning application_to_manufacturing
Deep learning application_to_manufacturing도형 임
 
프로그래머를 고려하는 당신에게
프로그래머를 고려하는 당신에게프로그래머를 고려하는 당신에게
프로그래머를 고려하는 당신에게도형 임
 
테스트 기발 개발, TBD(Test based developement)
테스트 기발 개발, TBD(Test based developement)테스트 기발 개발, TBD(Test based developement)
테스트 기발 개발, TBD(Test based developement)도형 임
 
코드와 실습으로 이해하는 인공지능
코드와 실습으로 이해하는 인공지능코드와 실습으로 이해하는 인공지능
코드와 실습으로 이해하는 인공지능도형 임
 
알파고 학습 이해하기
알파고 학습 이해하기알파고 학습 이해하기
알파고 학습 이해하기도형 임
 
Ai 그까이거
Ai 그까이거Ai 그까이거
Ai 그까이거도형 임
 
테스트 케이스와 SW 품질
테스트 케이스와 SW 품질테스트 케이스와 SW 품질
테스트 케이스와 SW 품질도형 임
 
유지보수성이 sw의 품질이다.
유지보수성이 sw의 품질이다.유지보수성이 sw의 품질이다.
유지보수성이 sw의 품질이다.도형 임
 
Release and versioning
Release and versioningRelease and versioning
Release and versioning도형 임
 
고품질 Sw와 개발문화
고품질 Sw와 개발문화고품질 Sw와 개발문화
고품질 Sw와 개발문화도형 임
 
행복한 개발을 위한_테스트_케이스
행복한 개발을 위한_테스트_케이스행복한 개발을 위한_테스트_케이스
행복한 개발을 위한_테스트_케이스도형 임
 
행복, 그리고 인지과학
행복, 그리고 인지과학행복, 그리고 인지과학
행복, 그리고 인지과학도형 임
 
유지보수를 고려한 SW 개발
유지보수를 고려한 SW 개발유지보수를 고려한 SW 개발
유지보수를 고려한 SW 개발도형 임
 
Git 사용 가이드
Git 사용 가이드Git 사용 가이드
Git 사용 가이드도형 임
 
흰머리 성성하게 개발하기 위해
흰머리 성성하게 개발하기 위해흰머리 성성하게 개발하기 위해
흰머리 성성하게 개발하기 위해도형 임
 
프로젝트 Xxx에 적용하고 싶은 개발방법
프로젝트 Xxx에 적용하고 싶은 개발방법프로젝트 Xxx에 적용하고 싶은 개발방법
프로젝트 Xxx에 적용하고 싶은 개발방법도형 임
 
행복한 소프트웨어 개발
행복한 소프트웨어 개발행복한 소프트웨어 개발
행복한 소프트웨어 개발도형 임
 
Java 그쪽 동네는
Java 그쪽 동네는Java 그쪽 동네는
Java 그쪽 동네는도형 임
 

Mehr von 도형 임 (20)

인공지능과 심리상담
인공지능과 심리상담인공지능과 심리상담
인공지능과 심리상담
 
Anomaly detection practive_using_deep_learning
Anomaly detection practive_using_deep_learningAnomaly detection practive_using_deep_learning
Anomaly detection practive_using_deep_learning
 
Deep learning application_to_manufacturing
Deep learning application_to_manufacturingDeep learning application_to_manufacturing
Deep learning application_to_manufacturing
 
프로그래머를 고려하는 당신에게
프로그래머를 고려하는 당신에게프로그래머를 고려하는 당신에게
프로그래머를 고려하는 당신에게
 
테스트 기발 개발, TBD(Test based developement)
테스트 기발 개발, TBD(Test based developement)테스트 기발 개발, TBD(Test based developement)
테스트 기발 개발, TBD(Test based developement)
 
코드와 실습으로 이해하는 인공지능
코드와 실습으로 이해하는 인공지능코드와 실습으로 이해하는 인공지능
코드와 실습으로 이해하는 인공지능
 
알파고 학습 이해하기
알파고 학습 이해하기알파고 학습 이해하기
알파고 학습 이해하기
 
Ai 그까이거
Ai 그까이거Ai 그까이거
Ai 그까이거
 
테스트 케이스와 SW 품질
테스트 케이스와 SW 품질테스트 케이스와 SW 품질
테스트 케이스와 SW 품질
 
유지보수성이 sw의 품질이다.
유지보수성이 sw의 품질이다.유지보수성이 sw의 품질이다.
유지보수성이 sw의 품질이다.
 
Release and versioning
Release and versioningRelease and versioning
Release and versioning
 
고품질 Sw와 개발문화
고품질 Sw와 개발문화고품질 Sw와 개발문화
고품질 Sw와 개발문화
 
행복한 개발을 위한_테스트_케이스
행복한 개발을 위한_테스트_케이스행복한 개발을 위한_테스트_케이스
행복한 개발을 위한_테스트_케이스
 
행복, 그리고 인지과학
행복, 그리고 인지과학행복, 그리고 인지과학
행복, 그리고 인지과학
 
유지보수를 고려한 SW 개발
유지보수를 고려한 SW 개발유지보수를 고려한 SW 개발
유지보수를 고려한 SW 개발
 
Git 사용 가이드
Git 사용 가이드Git 사용 가이드
Git 사용 가이드
 
흰머리 성성하게 개발하기 위해
흰머리 성성하게 개발하기 위해흰머리 성성하게 개발하기 위해
흰머리 성성하게 개발하기 위해
 
프로젝트 Xxx에 적용하고 싶은 개발방법
프로젝트 Xxx에 적용하고 싶은 개발방법프로젝트 Xxx에 적용하고 싶은 개발방법
프로젝트 Xxx에 적용하고 싶은 개발방법
 
행복한 소프트웨어 개발
행복한 소프트웨어 개발행복한 소프트웨어 개발
행복한 소프트웨어 개발
 
Java 그쪽 동네는
Java 그쪽 동네는Java 그쪽 동네는
Java 그쪽 동네는
 

Exception log practical_coding_guide, 예외와 로그 코딩 실용 가이드

  • 1.
  • 2. 예외를 잡고 무언가 했는데, 로그를 남겨야 하나? 로그 레벨은? 어떤 예외 클래스로? 예외 메시지에는 어떤 값을?
  • 3.
  • 13. 예외의 로그 위치가 고민되면 안된다. 이미 정해져 있어야 한다.
  • 14. 시스템을 단순화 하면, 호출받은 이쪽과 호출한 저쪽 예외 발생
  • 15. 이쪽과 저쪽의 구분은 제어 가능 여부 예외 발생 손을 떠났다. 로그를 남기고 싶어도 못남긴다.
  • 16. 저쪽으로 보내기 전에 로그를 남기자. 중복되지도 누락되지도 않는다. 여기 예외 발생
  • 17. 혹은 정상상황으로 처리한 곳에서 로그를 남기자 역시 중복되지도 누락되지도 않는다. 여기 예외 발생
  • 18. 오직 딱 2곳에서만. • 호출한 저쪽으로 넘기기 직전 • 정상상황으로 처리한 곳 그렇지 않을 경우 로그가 중복되거나 누락될 수 있다.
  • 19. 외부 호출이 아닌 스케쥴링 테스크의 경우는?
  • 20. 외부 호출이 아닌 스케쥴링 테스크의 경우는? 동일하다. JVM, OS 또는 Framework이 호출한 그 지점이 그 경계이다. 여기 예외 발생 JVM, OS, Framework
  • 21. • REST 타입의 외부 인터페이스 • 내부 스케쥴링 테스크 Exception Mapper가 예외를 잡 아 적절한 Http Status의 응답을 보낸다. 이 때 로그를 남긴다. 그리고 스케쥴링 테스크에서 로그를 남긴다. Exception Mapper Scheduling Task 여기 여기 REST type interface
  • 22. exception mapper를 설정하여 HTTP 응답과 로그를 처리. Exception Class HTTP Response Status UserNotFoundException BAD_REQUEST(400) InvalidParameterException BAD_REQUEST(400) WebApplicatoinExceptoin(by Jersey) NOT_FOUND(404) Throwable INTERNAL_SERVER_ERROR(500)
  • 23. @Provider public class InvalidParameterExceptionMapper implements ExceptionMapper<InvalidParameterException> { @Override public Response toResponse(InvalidParameterException exception) { logger.debug(“request of invalid parameter.”, exception); return Response.status(Status.BAD_REQUEST).build(); } } InvalidParameterException이 던져지면 BAD_REQUEST(400)의 응답 을 보낸다.
  • 24. @Provider public class DefaultExceptionMapper implements ExceptionMapper<Throwable> { @Override public Response toResponse(Throwable exception) { logger.error(“unhandled exception.”, exception); return Response.status(Status.INTERNAL_SYSTEM_ERROR).build(); } } 다른 exception mapper에 의해 처리되지 못한 모든 Throwable에 대 하여 INTERNAL_SYSTEM_ERROR(500)의 응답을 보낸다.
  • 25. @Service public class SomeScheduledTask { @Scheduled public void process() { try { … } catch(SomeException e) { logger.warn(...); } catch(Throwable e) { logger.error(...); } } } process() 메소드가 저어쪽 Spring에 호출되는 지점이다. 이 경우 일반 예외뿐 아니라 Throwable로 다 잡고 있다.
  • 26.
  • 27. • Info : 운영자에게 보이기 위한 정보. • debug : 디버깅을 위한 내용. • warn : 예외는 아니나, 추후 문제가 될 수 있는. • error : 예외가 발생했으나, 정상 처리. • fatal : 예외가 발생했고, 정상처리 못함.
  • 28. 예 • 8080 포트로 서버가 시작됨. • 백업 스케쥴러가 완료됨. • DB와 특정 url로 연결됨. • 설정파일 some.properties를 /some/path에서 읽음.
  • 29. 오직 개발자의 디버깅을 위한. 내용에 제약 없다. 많아도 괜찮다.
  • 30. 예 • 파일 여유 공간이 10% 이하. • 값은 있으나 사용하지 않는 설정.
  • 31. 예 • 디비 연결이 끊겼으나 재연결하여 처리 • 설정 값이 없어서 default 값으로 처리
  • 32. 예 • 디비 연결이 끊어지고 재연결 안되어 처리 못함. • null이 될 수 없는 값이 null이어서 처리 못함.
  • 33. • 사용자의 입력이 잘못되어 던져진 예외. • NullPointerException. • RuntimeException. • 예외가 던져졌는데 정말 예외 상황은 아니다.
  • 34. 사용자의 입력이 잘못되어 던져진 예외 • 예외라 하더라도 warn의 수준도 아니다. • 하지만 debug 정도는 괜찮겠다. • 대신 로그 설정이 가능하도록 별개의 로거가 있어야.
  • 35. NullPointerException • 무조건 bug다. • JVM은 NPE가 발생하면 해당 thread를 종료시킨다. • 그렇다면 warn이상이고, fatal 혹은 error이다.
  • 36. RuntimeException • 역시 JVM은 해당 thread를 종료시킨다. • fatal이다.
  • 37. 예외가 던져졌는데 정말 예외 상황은 아니다. • 메소드 설계가 잘못된 경우. • 예외를 던지면 안된다.
  • 38.
  • 39. 외부 인증 서버로 요청하여 인증을 처리한다. • 외부 인증 서버의 접속 정보를 설정 파일에서 얻는다. • 외부 인증 서버로 REST 요청을 하여 응답을 받는다. • id와 password를 입력으로 받는다. • id 존재 여부, password 틀림 여부를 알려주어야 한다. • 인증된 경우 인증 토큰을 반환한다.
  • 40. • 외부 인증 서버의 접속 정보를 읽지 못한다. • 외부 인증 서버로 접속이 되지 않는다. • 외부 인증 서버로 접속은 되었으나 응답이 없다. • 외부 인증 서버로 응답을 받았으나 5초 지나서 받았다. • timeout 이후 재시도 하여 응답을 받았다. • 외부 인증 서버로 요청되어 응답을 받았으나 잘못된 형식. • id가 존재 하지 않는다. • password가 틀리다.
  • 41. 상황 던지는 예외 예외 처리 주체 로그 레벨 처리 인증서버의 접속 정보 를 읽지 못한다. SystemFailException (extends RuntimeException) Exception Handler FATAL 시스템 종료 인증서버로 접속이 되 지 않는다. AuthSystemFailException (extends RuntimeException) Exception Handler ERROR 500 응답 인증서버로 접속은 되 었으나 응답이 없다. AuthSystemFailException (extends RuntimeException) Exception Handler ERROR 500 응답 응답을 받았으나 5초 지나서 받았다. 던지지 않는다. 모듈 내부 WARN 정상 처리 timeout 이후 재시도 하여 응답을 받았다. 던지지 않는다. 모듈 내부 WARN 정상 처리 응답을 받았으나 잘못 된 형식. AuthSystemFailException (extends RuntimeException) Exception Handler ERROR 500 응답 id가 존재 하지 않는 다는 응답. AuthFailException 호출한 모듈. InvalidInputException으로 다시 던진다. DEBUG 400 응답 password가 틀리다는 응답. AuthFailException 위와 동일 DEBUG 400 응답
  • 42. 상황 예외 메시지 or 로그 메시지 or 처리 상세 인증서버의 접속 정보를 읽지 못한다. “loading auth server info failed. properties file=/some/path/…”. 인증서버로 접속이 되지 않는다. “connecting auth server failed. connection info=http://some.url” 인증서버로 접속은 되었으나 응답이 없다. “getting response from auth server failed. connection info=….” 응답을 받았으나 5초 지나서 받았다. “got response from auth server, but too long response time. time=10.3 sec.” timeout 이후 재시도 하여 응답을 받았다. “get response after 1 timeout. connection info=…” 응답을 받았으나 잘못된 형식. “parsing message failed. message=…” id가 존재 하지 않는다는 응답. AuthFailException를 던질 때 NOT_EXIST_ID를 설정한다. 400로 반환할 때 NOT_EXIST_ID를 설정. password가 틀리다는 응답. AuthFailException를 던질 때 INCORRECT_PASSWORD를 설정한다. 400로 반환할 때 INCORRECT_PASSWORD를 설정.
  • 43. 모두 다음의 3가지 예외를 던진다. • SystemFailException – 구동 불가 • AuthSystemFailException – 장애 발생 상황. 하지만 계속 구동. • AuthFailException – 호출한 곳에서 잡아서 처리한다.
  • 44. 예외 상황을 처리하기 위해서는 시스템 전체적으로 다음이 전제되어야 한다. • SystemFailException이 발생하면 FATAL 로그를 남기고 시스템 구동 중지 • AuthSystemFailException이 던져지면 ERROR 로그를 남기고 500 응답 • 이외 모든 RuntimeException이 던져지면 ERROR 로그를 남기고 500응답. 즉 시스템 전체적인 정책 혹은 아키텍쳐가 마련되어 있어야 한다. 모듈 설계 시에 포함되어야 한다.
  • 45. try { authToken = authManager.getAuthToken(id, password); } catch(AuthFailException e) { throw new InvalidInputException("invalid auth info", e.getErrorCode(), e); } 오직 AuthFailException만 잡으면 된다. 다른 두 예외는 RuntimeException을 상속받았다. 잘못된 입력값을 전달하기 위한 getErrorCode() 메소드가 선 언되어 있다.
  • 46. 받는 쪽에서 처리하기에 불편하지 않게 던진다. • 시스템 관련된 예외는 따로 잡지 않도록 RuntimeException으로 던졌다. • FATAL과 ERROR를 구분하기 위해 SystemFailException과 AuthSystemFailException으로 구분해서 던졌다. • ERROR 상황이지만 극복된 경우 로그만 남기고 예외를 던지지 않았다. • 잘못된 입력을 구분하기 위해 getErrorCode() 메소드를 AuthFailException에 선언하였다.
  • 47.
  • 48. RuntimeException을 상속한 예외 클래스로 던지면 매 호출 stack에서 명시적으로 잡지 않아도 된다. 최종 exception handler에서만 잡아서 처리하면 된다. 단 최종 exception handler가 반드시 있어야 한다.
  • 49. 문제가 발생하면 DEBUG 수준의 로그를 봐야 한다. 로거 설정 변경을 위해 시스템을 재구동하기는 어렵다. logback의 경우 파일의 변경을 감지하여 반영한다. (기존 log4j 등은 그러하지 못했다.) 혹은 JMX를 사용하여 로거 레벨을 동적으로 변경가능하도 록 하자.
  • 50. debug 레벨의 로깅은 무척이나 많다. 전부 같은 이름이면, debug 레벨로 변경시 어마어마한 양의 로그가 쌓인다. 각 기능별로 로거를 분리해서 필요 부분만 레벨을 조정할 수 있도록.
  • 51. 요즘은 클래스의 이름을 로거 이름으로 하는 경우가 대세. Logger logger = LogManager.getLogger(SomeDao.class); 클래스의 패키지까지 로거의 이름이 된다. 이 경우 계층적으로 로거를 설정할 수 있다. <logger name=“some” level=“warn”/> <logger name=“some.component” level=“debug”/> <logger name=“some.component.dao” level=“warn”/>
  • 52. • 다음 2가지 이유로 권장. • 불필요한 String 연산 제거(by SLF4J) • 동적 설정 변경(by LogBack)
  • 53. • 불필요한 String 연산 방지 logger.debug(“userId=“+userId); logger.debug(“userId={}”, userId); • SLF4J는 다양한 로거에 관계없이 동일한 사용방법을 제공. 단지 진짜 사용하는 로거를 호출해 준다.
  • 54. • 가장 많이 사용하는 Log4J의 다음 버전(개발자가 동일) • 설정 파일이 동일 • 성능 훨씬 우월
  • 55. • 로거 설정 파일의 default는 logback.xml 혹은 log4j.xml • 그런데 가져다 사용하는 라이브러리 jar안에 해당 파일이 있으면, 그 설정 파일이 사용될 수 있다. • 설정 파일 이름을 달리하고, 그 이름을 명시하자.
  • 56. Java의 JUL(Java Util Logging) java.util.logging.LogManager.getLogManager().reset(); org.slf4j.bridge.SLF4JBridgeHandler.install(); java.util.logging.Logger.getLogger("").setLevel(java.util.logging.Level.FINEST); refer http://www.slf4j.org/legacy.html#jul-to-slf4j
  • 57. Apache의 JCL(Java Commons Logging) 단지 commons-logging.jar를 jcl-over-slf4j.jar로 대체 refer http://www.slf4j.org/legacy.html#jcl-over-slf4j
  • 58. System.out.println() 처럼 사용하지 말자. 로깅 코드는 삭제하지 않는다. 설치 이후에도 사용된다. 코딩 시에는 찍히는 값이 뭔지 알 수 있지만, 수 많은 로그에 서는 그 값이 무엇인지 모른다. 무언지 알 수 있어야 한다. logger.debug(userId); // 추후에 값 만으로는 파악이 안된다. logger.debug(“userId={}”, userId);
  • 59. 엔티티 전체를 로그로 찍자. logger.debug(“userId={}”, request.getUserId()); // 이러지 말고 속성 이름은 변경되고 추가되고 삭제된다. 하지만 로깅 코드 는 업데이트 안된다. logger.debug(“request={}”, request); 이를 위해서는 toString()이 구현되어야 한다.
  • 60. Apache commons의 ToStringBuilder @Override public String toString() { return ToStringBuilder.reflectionToString(this, …); }
  • 61. 로그의 목적은 문제 파악이다. 예외의 stacktrace가 잔뜩 찍히는 것은 문제 해결의 축복이 다. debug 로그가 많은 것은 단지 레벨 설정으로 처리된다.
  • 62. logger.debug("request={}", request); logger.debug("context={}", context); logger.debug("binder={}", binder); 여러 개의 로그가 한번에 모여서 찍힌다는 보장은 없다. multi thread 상황에서는 더더욱 그렇다. logger.debug("request={}, context={}, binder={}", request, context, binder);