[java] log4j에 stacktrace를 보내는 방법은 무엇입니까?

e.printStackTrace () 를 수행하면 예외를 잡아서 표준 출력 (예 : 콘솔)에서 다음을 얻습니다 .

java.io.FileNotFoundException: so.txt
        at java.io.FileInputStream.<init>(FileInputStream.java)
        at ExTest.readMyFile(ExTest.java:19)
        at ExTest.main(ExTest.java:7)

이제 이것을 log4j와 같은 로거로 보내서 다음을 얻습니다.

31947 [AWT-EventQueue-0] ERROR Java.io.FileNotFoundException: so.txt
32204 [AWT-EventQueue-0] ERROR    at java.io.FileInputStream.<init>(FileInputStream.java)
32235 [AWT-EventQueue-0] ERROR    at ExTest.readMyFile(ExTest.java:19)
32370 [AWT-EventQueue-0] ERROR    at ExTest.main(ExTest.java:7)

어떻게해야합니까?

try {
   ...
} catch (Exception e) {
    final String s;
    ...  // <-- What goes here?
    log.error( s );
}



답변

예외를 로거에 직접 전달합니다. 예 :

try {
   ...
} catch (Exception e) {
    log.error( "failed!", e );
}

스택 추적을 렌더링하는 것은 log4j에 달려 있습니다.


답변

예외없이 스택 추적을 기록하려면 다음을 수행하십시오.

String message = "";

for(StackTraceElement stackTraceElement : Thread.currentThread().getStackTrace()) {
    message = message + System.lineSeparator() + stackTraceElement.toString();
}
log.warn("Something weird happened. I will print the the complete stacktrace even if we have no exception just to help you find the cause" + message);


답변

를 통해 스택 추적을 문자열로 얻을 수도 있습니다 ExceptionUtils.getStackTrace.

참조 : ExceptionUtils.java

나는 간결하게 log.debug유지하기 위해 만 사용합니다 log.error.


답변

그것이 나에게 일어난 것이기 때문에 유용 할 수 있습니다. 이렇게하면

try {
   ...
} catch (Exception e) {
    log.error( "failed! {}", e );
}

전체 스택 추적이 아닌 예외 헤더를 가져옵니다. 로거는 문자열을 전달한다고 생각하기 때문입니다. {}skaffman이 말한대로 하지 마십시오


답변

skaffman의 대답은 확실히 정답입니다. 같은 모든 로거 방법은 error(), warn(), info(), debug()두 번째 매개 변수로의 Throwable을 :

try {
...
 } catch (Exception e) {
logger.error("error: ", e);
}

그러나 stacktrace를 String으로 추출 할 수도 있습니다. “{}”자리 표시자를 사용하여 형식 지정 기능을 활용하려는 경우에 유용 할 수 있습니다 void info(String var1, Object... var2);.이 경우 문자열 참조 stacktrace가 있다고 가정하면 실제로 다음과 같은 작업을 수행 할 수 있습니다.

try {
...
 } catch (Exception e) {
String stacktrace = TextUtils.getStacktrace(e);
logger.error("error occurred for usename {} and group {}, details: {}",username, group, stacktrace);
}

이렇게하면 매개 변수화 된 메시지와 스택 추적이 메소드와 동일한 방식으로 끝에 인쇄됩니다. logger.error("error: ", e);

실제로 스택 트레이스에서 일부 노이즈를 스마트하게 필터링하는 옵션을 사용하여 스택 트레이스를 String으로 추출하는 유틸리티가있는 오픈 소스 라이브러리를 작성했습니다. 즉, 추출 된 스택 추적에 관심이있는 패키지 접두사를 지정하면 관련이없는 부분이 필터링되어 매우 정교 한 정보가 남습니다. 다음은 라이브러리에있는 유틸리티와 라이브러리를 얻을 수있는 위치 (maven 아티팩트 및 git 소스)와 사용 방법을 설명하는 기사 링크입니다. 스택 추적 필터링, 자동 문자열 구문 분석 유니 코드 변환기 및 버전 비교가 포함 된 오픈 소스 Java 라이브러리 “스택 추적 노이즈 필터 ” 단락을 참조하십시오.


답변

이 답변은 질문과 관련된 것이 아니라 질문의 제목과 관련이있을 수 있습니다.

public class ThrowableTest {

    public static void main(String[] args) {

        Throwable createdBy = new Throwable("Created at main()");
        ByteArrayOutputStream os = new ByteArrayOutputStream();
        PrintWriter pw = new PrintWriter(os);
        createdBy.printStackTrace(pw);
        try {
            pw.close();
            os.close();
        } catch (IOException e) {
            e.printStackTrace();
        }
        logger.debug(os.toString());
    }
}

또는

public static String getStackTrace (Throwable t)
{
    StringWriter stringWriter = new StringWriter();
    PrintWriter  printWriter  = new PrintWriter(stringWriter);
    t.printStackTrace(printWriter);
    printWriter.close();    //surprise no IO exception here
    try {
        stringWriter.close();
    }
    catch (IOException e) {
    }
    return stringWriter.toString();
}

또는

StackTraceElement[] stackTraceElements = Thread.currentThread().getStackTrace();
for(StackTraceElement stackTrace: stackTraceElements){
    logger.debug(stackTrace.getClassName()+ "  "+ stackTrace.getMethodName()+" "+stackTrace.getLineNumber());
}


답변

Log4j 2에서는 Logger.catching () 을 사용하여 포착 된 예외에서 스택 추적 을 기록 할 수 있습니다 .

    try {
        String msg = messages[messages.length];
        logger.error("An exception should have been thrown");
    } catch (Exception ex) {
        logger.catching(ex);
    }