Throwable.getStackTrace()
ප්රති result ලය ස්ටක්ට්රේස් නිරූපණය කරන නූලකට පරිවර්තනය කිරීමට ඇති පහසුම ක්රමය කුමක්ද?
Throwable.getStackTrace()
ප්රති result ලය ස්ටක්ට්රේස් නිරූපණය කරන නූලකට පරිවර්තනය කිරීමට ඇති පහසුම ක්රමය කුමක්ද?
Answers:
Exception
තොග හෝඩුවාවක් පරිවර්තනය කිරීමට කෙනෙකුට පහත ක්රමය භාවිතා කළ හැකිය String
. මෙම පන්තිය අපාචේ කොමන්ස්-ලැන්ග් හි ඇත, එය බොහෝ ජනප්රිය විවෘත ප්රභවයන් සහිත යැපෙන පුස්තකාලයකි
org.apache.commons.lang.exception.ExceptionUtils.getStackTrace(Throwable)
org.apache.commons.lang3.exception.ExceptionUtils
.
Throwable.printStackTrace(PrintWriter pw)
සුදුසු ලේඛකයෙකුට තොග හෝඩුවාව යැවීමට භාවිතා කරන්න .
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);
StringWriter
හා PrintWriter
?
මෙය ක්රියාත්මක විය යුතුය:
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
String exceptionAsString = sw.toString();
printStackTrace
මුද්රණය කළ යුතුද නැද්ද යන්න පිළිබඳ තීරණයක් තබා පරිශීලකයා වෙත ආපසු යා යුතුය :)
printXXX()
XXX මුද්රණය කළ යුතුය.
ඔබ ඇන්ඩ්රොයිඩ් සඳහා සංවර්ධනය කරන්නේ නම්, මෙය භාවිතා කිරීම වඩා පහසු ක්රමයකි:
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)
Log.e("TAG", "My message", new Throwable());
Throwables
පන්තියඔබට සත්ය Throwable
අවස්ථාව තිබේ නම්, ගූගල් ගුවා සපයයි Throwables.getStackTraceAsString()
.
උදාහරණයක්:
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();
}
String.format("%n")
වෙනුවට ඒ හා සමාන දෙයක් භාවිතා කරන්න "\n"
.
මට නම් පිරිසිදු හා පහසුම ක්රමය වූයේ:
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();
}
StringWriter
හා PrintWriter
වස්තූන් විය යුතු බවයි close
.... (නැතහොත් PrintWriter
එය වසා දැමිය යුතු බැවින් වසා දැමිය යුතු අවශ්යතා පමණක් වසා දැමිය යුතු යැයි මම සිතමි StringWriter
)
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.
}
කේතයට කෙලින්ම පිටපත් කළ හැකි අනුවාදයක් මෙන්න:
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());
}
Throwable
අර්ථ දක්වන්නේ, හරිද?
Arrays.toString(thrown.getStackTrace())
ප්රති result ලය නූල් බවට පරිවර්තනය කිරීමට ඇති පහසුම ක්රමය මෙයයි. මම මෙය මගේ වැඩසටහනේ භාවිතා කරන්නේ තොග හෝඩුවාව මුද්රණය කිරීමට ය
LOGGER.log(Level.SEVERE, "Query Builder Issue Stack Trace : {0} ,Message : {1} objid {2}", new Object[]{Arrays.toString(e.getStackTrace()), e.getMessage(),objId});
තොග හෝඩුවාව a ට මුද්රණය කර PrintStream
එය a බවට පරිවර්තනය කරන්න 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.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"));
}
පළමු අදහස් දැක්වීමේදී ඉතා දක්ෂ ලෙස විනිවිද යාම ඉතා විනෝදජනක විය, නමුත් එය සැබවින්ම රඳා පවතින්නේ ඔබ කිරීමට උත්සාහ කරන දේ මතය. ඔබට දැනටමත් නිවැරදි පුස්තකාලයක් නොමැති නම්, කේත පේළි 3 ක් (ඩී. වර්බ්ලෙව්ස්කිගේ පිළිතුරෙහි මෙන්) පරිපූර්ණයි. OTOH, ඔබට දැනටමත් apache.commons පුස්තකාලය තිබේ නම් (බොහෝ විශාල ව්යාපෘති වලට අනුව), එවිට අමර්ගේ පිළිතුර කෙටි වේ. හරි, පුස්තකාලය ලබාගෙන එය නිවැරදිව ස්ථාපනය කිරීමට ඔබට විනාඩි දහයක් ගතවනු ඇත (ඔබ කරන්නේ කුමක්දැයි ඔබ දන්නේ නම් එකකට වඩා අඩුය). නමුත් ඔරලෝසුව හීලෑ වේ, එබැවින් ඔබට ඉතිරි කිරීමට කාලය නොමැති විය හැකිය. ජැරෙක් ප්රසිගාඩ්ස්කි සිත්ගන්නාසුලු අවවාදයක් - “ඔබට කැදැලි ව්යතිරේක අවශ්ය නොවේ නම්”.
නමුත් මට සම්පූර්ණ කූඩාරම්, කූඩු සහ සියල්ල අවශ්ය නම් කුමක් කළ යුතුද? එවැනි අවස්ථාවකදී රහස වන්නේ 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 )
ඒකෙන් මගේ බේකන් බේරුණා. ස්තූතියි, අමර්, ඉඟිය සඳහා!
Apache Commons Lang 3.4 ( JavaDoc ) වෙතින් කේතය :
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
.
java.io.*
එය නොමැතිව මේ ආකාරයෙන් කළ හැකිය.
String trace = e.toString() + "\n";
for (StackTraceElement e1 : e.getStackTrace()) {
trace += "\t at " + e1.toString() + "\n";
}
එවිට trace
විචල්යය ඔබේ තොග හෝඩුවාව රඳවා ගනී. ප්රතිදානය ද ආරම්භක හේතුව දරයි, ප්රතිදානය සමාන වේ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)
පරිමාණ අනුවාදය
def stackTraceToString(e: Exception): String = {
import java.io.PrintWriter
val sw = new StringWriter()
e.printStackTrace(new PrintWriter(sw))
sw.toString
}
ඔබ ජාවා 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" සමඟ සම්බන්ධ වන්න.
ජාවා 8 ධාරා API සමඟ ඔබට මේ වගේ දෙයක් කළ හැකිය:
Stream
.of(throwable.getStackTrace())
.map(StackTraceElement::toString)
.collect(Collectors.joining("\n"));
එය සිරස් ලුහු ce ු මූලද්රව්ය සමූහයක් ගෙන ඒවා නූල් බවට පරිවර්තනය කර බහු රේඛා වලට සම්බන්ධ වේ.
ගාලාගේ පිළිතුරෙහි විස්තාරණයක් වන අතර එය ව්යතිරේකයට හේතු ද ඇතුළත් වේ:
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;
}
විසඳුම වන්නේ අරා ස්ටැක්ට්රේස් නූල් දත්ත වර්ගයට පරිවර්තනය කිරීමයි . පහත උදාහරණය බලන්න:
import java.util.Arrays;
try{
}catch(Exception ex){
String stack = Arrays.toString(ex.getStackTrace());
System.out.println("stack "+ stack);
}
සංවෘත බහු රේඛා නූලට තොග හෝඩුවාව පරිවර්තනය කිරීමට මගේ ඔනලයිනර්:
Stream.of(e.getStackTrace()).map((a) -> a.toString()).collect(Collectors.joining("\n", "[", "]"))
"පවතින ආකාරයට" ලොගර් වෙත යැවීම පහසුය.
printStackTrace()
ඔබට මෙහි ලැබෙනු ඇත: 1) විසි කළ ව්යතිරේකය; 2) හේතු සහ ඒවායේ සිරස් තලය
printStackTrace()
කිසි විටෙකත් පරිවර්තනය කිරීම ප්රශ්නයේ කොටසක් නොවූ හෙයින් වෙනස තරමක් අපේක්ෂා කෙරේ .
ඔබට බාහිර පුස්තකාලයක් භාවිතා කිරීමට අවශ්ය නැතිනම් ඔබ ඇන්ඩ්රොයිඩ් සඳහා සංවර්ධනය නොකරන්නේ නම් , ඔබට මෙවැනි 'දිගුවක්' ක්රමයක් නිර්මාණය කළ හැකිය :
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();
}
පරණ ප්රශ්නය, නමුත් මම ඔබට අවශ්ය සියලුම කොටස් මුද්රණය කිරීමට අකමැති විශේෂ අවස්ථාව එකතු කිරීමට කැමතියි සමහර පංති හෝ පැකේජ හැර ඔබ සැබවින්ම උනන්දුවක් නොදක්වන සමහර කොටස් ඉවත් කිරීමෙන් ඔබට .
ඒ වෙනුවට ක 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);
}
}
}
මෙම පංතිය රීජෙක්ස් contains
හෝ වෙනත් නිර්ණායක මඟින් පෙරීමට පහසුවෙන් අනුගත විය හැකි බව කරුණාවෙන් සලකන්න . එය Throwable
ක්රියාත්මක කිරීමේ තොරතුරු මත රඳා පවතින බව සලකන්න (වෙනස් වීමට ඉඩක් නැත, නමුත් තවමත්).
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)
කිසිවෙකු සඳහන් නොකළේ මන්දැයි මම කල්පනා කරමි ExceptionUtils.getStackFrames(exception)
මට නම් එය සියළුම හේතුන් සමඟ ස්ටැක්ට්රේස් අවසානය දක්වා ඉවත ලෑමට වඩාත් පහසුම ක්රමයයි:
String.join("\n", ExceptionUtils.getStackFrames(exception));
අවවාදයයි: මෙය ටිකක් මාතෘකාවක් විය හැකිය, නමුත් ඔහ් හොඳයි ...;)
මුල් පෝස්ටරයේ හේතුව කුමක්දැයි මම නොදනිමි . සිරස් හෝඩුවාව 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
}
මම එයට කැමතියි එයට බාහිර පුස්තකාලයක් අවශ්ය නොවන නිසා (ඔබේ ල ging ු-සටහන් පසුබිම හැර, එය බොහෝ විට බොහෝ විට ක්රියාත්මක වනු ඇත, ඇත්ත වශයෙන්ම).
විකල්ප කිහිපයක්
StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
String exceptionAsString = sw.toString();
ගූගල් ගුවා ලිබ් භාවිතා කිරීම
String stackTrace = Throwables.getStackTraceAsString ( myException ) ;
org.apache.commons.lang.exception.ExceptionUtils.getStackTrace (විසි කළ හැකි)