스택 트레이스를 문자열로 변환하려면 어떻게 해야 하나요?
결과를 변환하는 가장 쉬운 방법은 무엇입니까?Throwable.getStackTrace()
스택 트레이스를 나타내는 문자열로 변경하시겠습니까?
스택 트레이스를 적절한 라이터로 송신하기 위해서 사용합니다.
import java.io.StringWriter;
import java.io.PrintWriter;
// ...
StringWriter sw = new StringWriter();
PrintWriter pw = new PrintWriter(sw);
e.printStackTrace(pw);
String sStackTrace = sw.toString(); // stack trace as a string
System.out.println(sStackTrace);
다음 방법을 사용하여 변환이 가능합니다.Exception
스택 트레이스 대상String
이 클래스는 Apache commons-lang에서 이용할 수 있습니다.이 클래스는 많은 인기 오픈소스를 가진 가장 일반적인 의존 라이브러리입니다.
org.apache.commons.lang.exception.ExceptionUtils.getStackTrace(Throwable)
이 조작은 유효합니다.
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
String exceptionAsString = sw.toString();
Android용으로 개발 중인 경우 훨씬 쉬운 방법은 다음과 같습니다.
import android.util.Log;
String stackTrace = Log.getStackTraceString(exception);
형식은 getStacktrace와 동일합니다.
09-24 16:09:07.042: I/System.out(4844): java.lang.NullPointerException 09-24 16:09:07.042: I/System.out(4844): at com.temp.ttscancel.MainActivity.onCreate(MainActivity.java:43) 09-24 16:09:07.042: I/System.out(4844): at android.app.Activity.performCreate(Activity.java:5248) 09-24 16:09:07.043: I/System.out(4844): at android.app.Instrumentation.callActivityOnCreate(Instrumentation.java:1110) 09-24 16:09:07.043: I/System.out(4844): at android.app.ActivityThread.performLaunchActivity(ActivityThread.java:2162) 09-24 16:09:07.043: I/System.out(4844): at android.app.ActivityThread.handleLaunchActivity(ActivityThread.java:2257) 09-24 16:09:07.043: I/System.out(4844): at android.app.ActivityThread.access$800(ActivityThread.java:139) 09-24 16:09:07.043: I/System.out(4844): at android.app.ActivityThread$H.handleMessage(ActivityThread.java:1210) 09-24 16:09:07.043: I/System.out(4844): at android.os.Handler.dispatchMessage(Handler.java:102) 09-24 16:09:07.043: I/System.out(4844): at android.os.Looper.loop(Looper.java:136) 09-24 16:09:07.044: I/System.out(4844): at android.app.ActivityThread.main(ActivityThread.java:5097) 09-24 16:09:07.044: I/System.out(4844): at java.lang.reflect.Method.invokeNative(Native Method) 09-24 16:09:07.044: I/System.out(4844): at java.lang.reflect.Method.invoke(Method.java:515) 09-24 16:09:07.044: I/System.out(4844): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:785) 09-24 16:09:07.044: I/System.out(4844): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:601)
구아바 클래스
만약 당신이 실제를 가지고 있다면Throwable
예를 들어, Google Guava는 을 참조해 주세요.
예:
String s = Throwables.getStackTraceAsString ( myException ) ;
경고: 원인(일반적으로 유용한 비트)은 포함되지 않습니다.
public String stackTraceToString(Throwable e) {
StringBuilder sb = new StringBuilder();
for (StackTraceElement element : e.getStackTrace()) {
sb.append(element.toString());
sb.append("\n");
}
return sb.toString();
}
저에게 가장 깨끗하고 쉬운 방법은 다음과 같습니다.
import java.util.Arrays;
Arrays.toString(e.getStackTrace());
public static String getStackTrace(Throwable t) {
StringWriter sw = new StringWriter();
t.printStackTrace(new PrintWriter(sw));
return sw.toString();
}
다음 코드를 사용하여 stackTrace 전체를 취득할 수 있습니다.String
포맷, log4J 등의 API를 사용하지 않거나java.util.Logger
:
catch (Exception e) {
StackTraceElement[] stack = e.getStackTrace();
String exception = "";
for (StackTraceElement s : stack) {
exception = exception + s.toString() + "\n\t\t";
}
System.out.println(exception);
// then you can send the exception string to a external file.
}
스택 트레이스를 에 인쇄합니다.PrintStream
, 그 후, 로 변환합니다.String
:
// ...
catch (Exception e)
{
ByteArrayOutputStream out = new ByteArrayOutputStream();
e.printStackTrace(new PrintStream(out));
String str = new String(out.toByteArray());
System.out.println(str);
}
다음은 코드에 직접 복사 붙여넣기 가능한 버전입니다.
import java.io.StringWriter;
import java.io.PrintWriter;
//Two lines of code to get the exception into a StringWriter
StringWriter sw = new StringWriter();
new Throwable().printStackTrace(new PrintWriter(sw));
//And to actually print it
logger.info("Current stack trace is:\n" + sw.toString());
또는 캐치블록에서
} catch (Throwable t) {
StringWriter sw = new StringWriter();
t.printStackTrace(new PrintWriter(sw));
logger.info("Current stack trace is:\n" + sw.toString());
}
Arrays.toString(thrown.getStackTrace())
결과를 String으로 변환하는 가장 쉬운 방법입니다.스택 트레이스를 인쇄하기 위해 프로그램에서 사용하고 있습니다.
LOGGER.log(Level.SEVERE, "Query Builder Issue Stack Trace : {0} ,Message : {1} objid {2}", new Object[]{Arrays.toString(e.getStackTrace()), e.getMessage(),objId});
Kotlin > = 1.4
에서 기본 제공 기능을 사용합니다.Throwable
.
Kotlin < 1.4
Throwable 클래스를 확장하면 String 속성이 표시됩니다.error.stackTraceString
:
val Throwable.stackTraceString: String
get() {
val sw = StringWriter()
val pw = PrintWriter(sw)
this.printStackTrace(pw)
return sw.toString()
}
Java 8을 사용하는 경우 다음을 시도해 보십시오.
Arrays.stream(e.getStackTrace())
.map(s->s.toString())
.collect(Collectors.joining("\n"));
코드를 찾을 수 있습니다.getStackTrace()
제공되는 기능Throwable.java
다음과 같이 합니다.
public StackTraceElement[] getStackTrace() {
return getOurStackTrace().clone();
}
및 을 위해StackTraceElement
, 이 기능을 제공합니다.toString()
다음과 같습니다.
public String toString() {
return getClassName() + "." + methodName +
(isNativeMethod() ? "(Native Method)" :
(fileName != null && lineNumber >= 0 ?
"(" + fileName + ":" + lineNumber + ")" :
(fileName != null ? "("+fileName+")" : "(Unknown Source)")));
}
그냥 가입해 주세요.StackTraceElement
"\n"로 지정합니다.
스택 추적을 문자열로 인쇄하는 중
import java.io.PrintWriter;
import java.io.StringWriter;
public class StackTraceUtils {
public static String stackTraceToString(StackTraceElement[] stackTrace) {
StringWriter sw = new StringWriter();
printStackTrace(stackTrace, new PrintWriter(sw));
return sw.toString();
}
public static void printStackTrace(StackTraceElement[] stackTrace, PrintWriter pw) {
for(StackTraceElement stackTraceEl : stackTrace) {
pw.println(stackTraceEl);
}
}
}
이 기능은 현재 스레드 스택트레이스를 인쇄할 때 편리합니다.Throwable
- 단, 신규 작성은Throwable
거기서 스택 트레이스를 취득하는 것은, 실제로 콜보다 고속으로 저렴합니다.Thread.getStackTrace
.
private String getCurrentStackTraceString() {
StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
return Arrays.stream(stackTrace).map(StackTraceElement::toString)
.collect(Collectors.joining("\n"));
}
Apache Commons Lang 3.4 (Java Doc) 코드:
public static String getStackTrace(final Throwable throwable) {
final StringWriter sw = new StringWriter();
final PrintWriter pw = new PrintWriter(sw, true);
throwable.printStackTrace(pw);
return sw.getBuffer().toString();
}
다른 답변과 다른 점은 다음과 같습니다. autoFlush
에서PrintWriter
.
첫 번째 코멘트의 교묘한 스니핑은 매우 재미있었지만, 실제로 무엇을 하려고 하는가에 달려 있습니다.아직 올바른 라이브러리가 없는 경우 코드 3행(D와 같음)브로블레스키의 답변은 완벽하다.OTOH, 이미 apache.commons 라이브러리를 가지고 있다면(대부분의 대규모 프로젝트와 마찬가지로), Amar의 답변은 더 짧습니다.좋습니다. 라이브러리를 가져와 올바르게 설치하는 데 10분 정도 걸릴 수 있습니다(실행 상황을 알고 있는 경우 1분 미만).하지만 시간이 촉박해서 시간이 없을 수도 있어요.Jarek Przygodzki는 흥미로운 경고를 했습니다. "네스트된 예외가 필요하지 않다면"
하지만 풀 스택 트레이스, 네스트된 트레이스 등이 필요한 경우는 어떻게 해야 합니까?이 경우 비밀은 apache.common의 getFullStackTrace를 사용하는 것입니다(http://commons.apache.org/proper/commons-lang/javadocs/api-2.6/org/apache/commons/lang/exception/ExceptionUtils.html#getFullStackTrace%28java.lang.Throwable%29) 참조).
덕분에 살았어.고마워, 아마르, 힌트!
java.io.*
네, 그렇습니다.
String trace = e.toString() + "\n";
for (StackTraceElement e1 : e.getStackTrace()) {
trace += "\t at " + e1.toString() + "\n";
}
그리고 그 다음에trace
variable은 스택트레이스를 유지합니다출력에는 초기 원인도 포함되어 있으며 출력은 다음과 같습니다.printStackTrace()
",printStackTrace()
★★★★
java.io.FileNotFoundException: / (Is a directory)
at java.io.FileOutputStream.open0(Native Method)
at java.io.FileOutputStream.open(FileOutputStream.java:270)
at java.io.FileOutputStream.<init>(FileOutputStream.java:213)
at java.io.FileOutputStream.<init>(FileOutputStream.java:101)
at Test.main(Test.java:9)
trace
홀드(''에 인쇄된 )stdout
java.io.FileNotFoundException: / (Is a directory)
at java.io.FileOutputStream.open0(Native Method)
at java.io.FileOutputStream.open(FileOutputStream.java:270)
at java.io.FileOutputStream.<init>(FileOutputStream.java:213)
at java.io.FileOutputStream.<init>(FileOutputStream.java:101)
at Test.main(Test.java:9)
Java 8 Stream API를 사용하면 다음과 같은 작업을 수행할 수 있습니다.
Stream
.of(throwable.getStackTrace())
.map(StackTraceElement::toString)
.collect(Collectors.joining("\n"));
스택 트레이스 요소의 배열을 가져와 문자열로 변환하고 여러 줄의 문자열로 결합합니다.
Gala의 답변에 대한 설명에는 예외의 원인도 포함됩니다.
private String extrapolateStackTrace(Exception ex) {
Throwable e = ex;
String trace = e.toString() + "\n";
for (StackTraceElement e1 : e.getStackTrace()) {
trace += "\t at " + e1.toString() + "\n";
}
while (e.getCause() != null) {
e = e.getCause();
trace += "Cause by: " + e.toString() + "\n";
for (StackTraceElement e1 : e.getStackTrace()) {
trace += "\t at " + e1.toString() + "\n";
}
}
return trace;
}
Scala 버전
def stackTraceToString(e: Exception): String = {
import java.io.PrintWriter
val sw = new StringWriter()
e.printStackTrace(new PrintWriter(sw))
sw.toString
}
해결책은 배열의 stackTrace를 문자열 데이터 유형으로 변환하는 것입니다.다음의 예를 참조해 주세요.
import java.util.Arrays;
try{
}catch(Exception ex){
String stack = Arrays.toString(ex.getStackTrace());
System.out.println("stack "+ stack);
}
외부 라이브러리를 사용하지 않고 Android용으로 개발하지 않을 경우 다음과 같은 '확장' 방법을 만들 수 있습니다.
public static String getStackTraceString(Throwable e) {
return getStackTraceString(e, "");
}
private static String getStackTraceString(Throwable e, String indent) {
StringBuilder sb = new StringBuilder();
sb.append(e.toString());
sb.append("\n");
StackTraceElement[] stack = e.getStackTrace();
if (stack != null) {
for (StackTraceElement stackTraceElement : stack) {
sb.append(indent);
sb.append("\tat ");
sb.append(stackTraceElement.toString());
sb.append("\n");
}
}
Throwable[] suppressedExceptions = e.getSuppressed();
// Print suppressed exceptions indented one level deeper.
if (suppressedExceptions != null) {
for (Throwable throwable : suppressedExceptions) {
sb.append(indent);
sb.append("\tSuppressed: ");
sb.append(getStackTraceString(throwable, indent + "\t"));
}
}
Throwable cause = e.getCause();
if (cause != null) {
sb.append(indent);
sb.append("Caused by: ");
sb.append(getStackTraceString(cause, indent));
}
return sb.toString();
}
스택 트레이스를 둘러싸인 여러 줄 문자열로 변환하기 위한 my oneliner:
Stream.of(e.getStackTrace()).map((a) -> a.toString()).collect(Collectors.joining("\n", "[", "]"))
로거에 "있는 그대로" 전달하기 쉽습니다.
import java.io.PrintWriter;
import java.io.StringWriter;
public class PrintStackTrace {
public static void main(String[] args) {
try {
int division = 0 / 0;
} catch (ArithmeticException e) {
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
String exceptionAsString = sw.toString();
System.out.println(exceptionAsString);
}
}
}
프로그램을 실행하면 다음과 같은 출력이 나타납니다.
java.lang.ArithmeticException: / by zero
at PrintStackTrace.main(PrintStackTrace.java:9)
오래된 질문입니다만, 일부 클래스나 패키지를 제외하고 실제로 관심이 없는 부분을 삭제함으로써 스택 전체를 인쇄하고 싶지 않은 특별한 경우를 추가하고 싶습니다.
PrintWriter
SelectivePrintWriter
:
// This filters out this package and up.
String packageNameToFilter = "org.springframework";
StringWriter sw = new StringWriter();
PrintWriter pw = new SelectivePrintWriter(sw, packageNameToFilter);
e.printStackTrace(pw);
String sStackTrace = sw.toString();
System.out.println(sStackTrace);
갔지?SelectivePrintWriter
츠키다
public class SelectivePrintWriter extends PrintWriter {
private boolean on = true;
private static final String AT = "\tat";
private String internal;
public SelectivePrintWriter(Writer out, String packageOrClassName) {
super(out);
internal = "\tat " + packageOrClassName;
}
public void println(Object obj) {
if (obj instanceof String) {
String txt = (String) obj;
if (!txt.startsWith(AT)) on = true;
else if (txt.startsWith(internal)) on = false;
if (on) super.println(txt);
} else {
super.println(obj);
}
}
}
Regex, Regex에 의해 수 .contains
또는 기타 기준., 이 는 하다, 하다, 하다, 하다에 다르다는 것을 참고하세요.Throwable
구현 상세(변경 가능성은 낮지만 계속).
경고:좀 주제에서 벗어나긴 하지만...;)
애초에 스택 트레이스를 스트링으로 하고 싶은 원래의 포스터의 이유가 무엇이었는지 모르겠습니다.스택 트레이스가 SLF4J/Logback LOG로 끝나도 예외가 발생하지 않거나 발생해서는 안 되는 경우는 다음과 같습니다.
public void remove(List<String> ids) {
if(ids == null || ids.isEmpty()) {
LOG.warn(
"An empty list (or null) was passed to {}.remove(List). " +
"Clearly, this call is unneccessary, the caller should " +
"avoid making it. A stacktrace follows.",
getClass().getName(),
new Throwable ("Stacktrace")
);
return;
}
// actual work, remove stuff
}
외부 라이브러리가 필요 없기 때문에 마음에 듭니다(로깅 백엔드는 물론 대부분의 시간을 사용할 수 있습니다).
몇 가지 옵션
StringWriter sw = new StringWriter(); e.printStackTrace(new PrintWriter(sw)); String exceptionAsString = sw.toString();
lib Google Guava lib
String stackTrace = Throwables.getStackTraceAsString ( myException ) ;
org.disc.disc.disc.disc.gException Utils.get Stack Trace(투척 가능)
나는 이것을 위해 얼마 전에 몇 가지 방법을 썼는데, 그래서 나는 왜 이것에 대해 의견을 표명하지 않을까 생각했다.
/** @param stackTraceElements The elements to convert
* @return The resulting string */
public static final String stackTraceElementsToStr(StackTraceElement[] stackTraceElements) {
return stackTraceElementsToStr(stackTraceElements, "\n");
}
/** @param stackTraceElements The elements to convert
* @param lineSeparator The line separator to use
* @return The resulting string */
public static final String stackTraceElementsToStr(StackTraceElement[] stackTraceElements, String lineSeparator) {
return stackTraceElementsToStr(stackTraceElements, lineSeparator, "");
}
/** @param stackTraceElements The elements to convert
* @param lineSeparator The line separator to use
* @param padding The string to be used at the start of each line
* @return The resulting string */
public static final String stackTraceElementsToStr(StackTraceElement[] stackTraceElements, String lineSeparator, String padding) {
String str = "";
if(stackTraceElements != null) {
for(StackTraceElement stackTrace : stackTraceElements) {
str += padding + (!stackTrace.toString().startsWith("Caused By") ? "\tat " : "") + stackTrace.toString() + lineSeparator;
}
}
return str;
}
/** @param stackTraceElements The elements to convert
* @return The resulting string */
public static final String stackTraceCausedByElementsOnlyToStr(StackTraceElement[] stackTraceElements) {
return stackTraceCausedByElementsOnlyToStr(stackTraceElements, "\n");
}
/** @param stackTraceElements The elements to convert
* @param lineSeparator The line separator to use
* @return The resulting string */
public static final String stackTraceCausedByElementsOnlyToStr(StackTraceElement[] stackTraceElements, String lineSeparator) {
return stackTraceCausedByElementsOnlyToStr(stackTraceElements, lineSeparator, "");
}
/** @param stackTraceElements The elements to convert
* @param lineSeparator The line separator to use
* @param padding The string to be used at the start of each line
* @return The resulting string */
public static final String stackTraceCausedByElementsOnlyToStr(StackTraceElement[] stackTraceElements, String lineSeparator, String padding) {
String str = "";
if(stackTraceElements != null) {
for(StackTraceElement stackTrace : stackTraceElements) {
str += (!stackTrace.toString().startsWith("Caused By") ? "" : padding + stackTrace.toString() + lineSeparator);
}
}
return str;
}
/** @param e The {@link Throwable} to convert
* @return The resulting String */
public static final String throwableToStrNoStackTraces(Throwable e) {
return throwableToStrNoStackTraces(e, "\n");
}
/** @param e The {@link Throwable} to convert
* @param lineSeparator The line separator to use
* @return The resulting String */
public static final String throwableToStrNoStackTraces(Throwable e, String lineSeparator) {
return throwableToStrNoStackTraces(e, lineSeparator, "");
}
/** @param e The {@link Throwable} to convert
* @param lineSeparator The line separator to use
* @param padding The string to be used at the start of each line
* @return The resulting String */
public static final String throwableToStrNoStackTraces(Throwable e, String lineSeparator, String padding) {
if(e == null) {
return "null";
}
String str = e.getClass().getName() + ": ";
if((e.getMessage() != null) && !e.getMessage().isEmpty()) {
str += e.getMessage() + lineSeparator;
} else {
str += lineSeparator;
}
str += padding + stackTraceCausedByElementsOnlyToStr(e.getStackTrace(), lineSeparator, padding);
for(Throwable suppressed : e.getSuppressed()) {
str += padding + throwableToStrNoStackTraces(suppressed, lineSeparator, padding + "\t");
}
Throwable cause = e.getCause();
while(cause != null) {
str += padding + "Caused by:" + lineSeparator + throwableToStrNoStackTraces(e.getCause(), lineSeparator, padding);
cause = cause.getCause();
}
return str;
}
/** @param e The {@link Throwable} to convert
* @return The resulting String */
public static final String throwableToStr(Throwable e) {
return throwableToStr(e, "\n");
}
/** @param e The {@link Throwable} to convert
* @param lineSeparator The line separator to use
* @return The resulting String */
public static final String throwableToStr(Throwable e, String lineSeparator) {
return throwableToStr(e, lineSeparator, "");
}
/** @param e The {@link Throwable} to convert
* @param lineSeparator The line separator to use
* @param padding The string to be used at the start of each line
* @return The resulting String */
public static final String throwableToStr(Throwable e, String lineSeparator, String padding) {
if(e == null) {
return "null";
}
String str = padding + e.getClass().getName() + ": ";
if((e.getMessage() != null) && !e.getMessage().isEmpty()) {
str += e.getMessage() + lineSeparator;
} else {
str += lineSeparator;
}
str += padding + stackTraceElementsToStr(e.getStackTrace(), lineSeparator, padding);
for(Throwable suppressed : e.getSuppressed()) {
str += padding + "Suppressed: " + throwableToStr(suppressed, lineSeparator, padding + "\t");
}
Throwable cause = e.getCause();
while(cause != null) {
str += padding + "Caused by:" + lineSeparator + throwableToStr(e.getCause(), lineSeparator, padding);
cause = cause.getCause();
}
return str;
}
예:
try(InputStream in = new FileInputStream(file)) {
...
} catch(IOException e) {
String exceptionToString = throwableToStr(e);
someLoggingUtility.println(exceptionToString);
...
}
인쇄:
java.io.FileNotFoundException: C:\test.txt (The system cannot find the file specified)
at java.io.FileInputStream.open0(Native Method)
at java.io.FileInputStream.open(Unknown Source)
at java.io.FileInputStream.<init>(Unknown Source)
at com.gmail.br45entei.Example.main(Example.java:32)
언급URL : https://stackoverflow.com/questions/1149703/how-can-i-convert-a-stack-trace-to-a-string
'sourcecode' 카테고리의 다른 글
Java Stanford NLP: 음성 라벨의 일부? (0) | 2022.08.28 |
---|---|
라우터 매개 변수의 프로펠러 유형이 잘못되었습니다. 수에 문자열이 있어야 합니다. (0) | 2022.08.28 |
VUEJS-url에서 매개 변수를 제거하는 방법 (0) | 2022.08.28 |
TreeMap에서 반복하는 방법 (0) | 2022.08.28 |
Linux는 syslog를 어디에 저장합니까? (0) | 2022.08.28 |