2011-10-28 2 views
3

나는 Spring, Hibernate 및 로깅을위한 Apache log4j를 포함한 다른 라이브러리로 largish Java 웹 애플리케이션을 개발 중이다. 계속 진행중인 프로젝트 중 하나는 더 현명한 정보를 제공하기 위해 코드의 레거시 영역 (많은 부분을 작성하지 않았습니다!)에서 많은 수의 예외를 다시 작성하는 것입니다. 일반적인 예외 블록은 다음과 같습니다.Java에서 더 좋은 예외 정보 로깅

try { 
    //Some Hibernate business here 
} 
catch (Exception e) { //Yes, Exception. That's not just me being general. I find this especially frustrating. 
    log4j.error("Fail to XXXXXX"); //again, real 
    throw new MyException(); 
} 

짐작할 수 있듯이 일부 어려운 로그가 있습니다. 나는이 예외로부터 더 나은 정보를 얻기위한 표준 방법을 찾고있다. 그 중 대부분은 Hibernate 호출을 감싸줍니다. 다음은 방금 작성한 블록과 비슷한 일반적인 블록입니다.

try { 
    myList.add(((myClass) commonService.getRecordByTableId(myClass.class, ID)).toString()); 
} catch (ServiceException e) { 
    log4j.error("Failed to retrieve record from table myClass for id " + ID); 
    e.printStackTrace(); 
} 

여기 데이터베이스에서 레코드를 가져 와서 목록에 추가합니다. catch 블록에서 나는 try 블록이 무엇을하는지에 대한 합리적인 메시지라고 생각하는 것을 기록하고 스택 추적을 인쇄합니다. 그래서, 제 질문 : 오류 진단을위한 더 나은 정보를 얻기 위해 일반적으로 할 수있는 일과해야 할 일이 있습니까?

답변

10

, 로깅 및 다시 던지는 것은 인기있는 안티 패턴입니다. 너는 그렇게해서는 안된다. 예외를 포착 한 후 로깅을 포함하여 적절하게 처리하거나 포기하지 않고 상위 레벨로 전달하도록 허용하거나 예외를 확인한 예외가있는 경우 런타임 예외로 래핑하십시오.

이렇게하면 (log + rethrow), 업스트림 코드가 이미 예외를 기록했다는 것을 알 수 없기 때문에 동일한 예외가 두 번 이상 기록 될 수 있습니다. 예외는 통과해야하며, 어떤 계층이 로그하고 임의로 다시 throw할지 결정합니다. 그러면 로그를 읽고 완전히 악몽에 빠지게 될 것입니다.

또한 예외를 던지고 잡는 것은 값 비싼 작업이므로이 모든 catch 및 rethrowing은 런타임에 성능에 도움이되지 않는다고 말할 수 있습니다.

실제로 예외를 처리하도록 선택한 경우 메시지를 삼키는 것은 올바른 방법이 아닙니다 (메시지를 기록하더라도). 적어도, 당신은 추적을 로그해야합니다

log4j.error("Failed to retrieve record from table myClass for id " + ID, e); 
+2

+1. 그렇게 할 수 있다면 더 많은 포인트를 줄 것입니다.나는 그 전에 여러 "에코"가있는 스택 추적을 보는 것에 지쳤습니다. –

+1

예, 그렇습니다. 많은 "심각한"개발자가 대부분의 예외에 대해 충분한 처리를하기 위해 로깅 및 재실행을 고려하고 있다는 것은 놀랍습니다. – Guillaume

+0

+1, 전화하세요. 이 프로젝트에서 나에게 매우 슬픈 일이 발생했는지에 대해 많은 이야기가 있습니다. 나는 그것을 모양대로 채우려고 노력하고 있습니다. : D – andronikus

1

네는 첫 번째 블록에, 그것은 다음과 같이해야한다 : 당신이 그것을 어떻게해야하므로

try { 
    //Some Hibernate business here 
} 
catch (Exception e) { //Yes, Exception. That's not just me being general 
    log4j.error("Fail to XXXXXX", e); //again, real 
    throw new MyException(e); 
} 

자바는 체인 예외로 할 수 있습니다. 또한 Log4J를 사용할 때 로그에 예외 스택 추적을 인쇄 할 수 있도록 예외를 보낼 수도 있습니다.

4

printStackTrace() 로그에 추적을 추가하지 않습니다. 하여 상황에 맞는 말이 어디 로그 파일에 출력합니다 Log4j를하는 예외 공급 : 예외 처리에서

log4j.error("Failed to retrieve record from table myClass for id " + ID, e); 
2

다른 사람이 언급 한 내용 이외에 몇 가지 : 다른 로깅 수준의

  1. 만들기 사용 : 정보; 경고하다;
  2. # 1에서 계속해서 printStackTrace() 호출을 중단합니다. 콘솔에 오류를 기록하려면 로거를 통해 오류를 기록하십시오. 그렇게하면 콘솔에서도 레벨 필터링의 이점을 얻을 수 있습니다.