मैं एक स्टैक ट्रेस को स्ट्रिंग में कैसे बदल सकता हूं?


1501

Throwable.getStackTrace()स्टैकट्रेस को दर्शाने वाले स्ट्रिंग के परिणाम को परिवर्तित करने का सबसे आसान तरीका क्या है ?


6
क्योंकि jqno का जवाब वास्तव में Throwable.getStackTrace () पद्धति का उपयोग करता है जिसे आपने अपने प्रश्न में निर्दिष्ट किया है, जबकि ब्रायन नहीं करता है। वह इसके बजाय Throwable.printStackTrace () का उपयोग करता है।
स्टिजन डे विट

10
बस हर जावा प्रोजेक्ट में अपाचे कॉमन्स-लैंग शामिल होना चाहिए। इसमें बेहद सामान्य विकास जरूरतों को लागू करने वाले कई सुविधा विधियां शामिल हैं।
रसेल सिल्वा

20
@StijndeWitt कोड की उन तीन पंक्तियों को लगभग निश्चित रूप से उस जगह से फैक्टरिंग की आवश्यकता होती है जिसे आपने उन्हें बुलाया है। चूंकि आप नहीं जानते कि उन्हें कहां रखा जाए, तो वे अन्य सभी उपयोगी स्निपेट्स के साथ आपके उपयोगिता टूलबॉक्स में जाएंगे। बिंगो! आपने अमरूद / कॉमन-लैंग / जो कुछ भी ... बस इतना ही अच्छा नहीं लगाया है। बदले में एक समझदार उपयोगिताओं के पुस्तकालय को आयात करें, और पहिया को सुदृढ़ करने से बचाएं। एक नौसिखिए का सही संकेत यह सोच रहा है कि आप पुस्तकालय लेखकों की तुलना में बेहतर काम कर सकते हैं।
एंड्रयू स्पेंसर

6
1. अमरूद है - Throwables.getStackTraceAsString (e) 2. Apache Commons Lang - ExceptionUtils.getFullStackTrace 3. हमारे अपने कस्टम तरीके लिखें
user2323036

8
@AndrewSpencer मुझे समझ में नहीं आता है कि आप लोग कुछ छोटे स्निपेट के साथ इसे प्राप्त करने की इच्छा के लिए StijndeWitt को कैसे हरा सकते हैं। एक छोटी सी उपयोगिता विधि लिखने में वास्तव में बहुत ज्यादा खतरा नहीं है (मैं इसे "शायर तीरंदाजी ओह नूओ के रूप में नहीं देखता! वह सोचता है कि वह अपाचे से बेहतर है !!")। विशेष रूप से गैर-जावा जेवीएम भाषाओं में बहुत सारी परियोजनाएं हैं जो वास्तव में केवल एक स्टैक्रेस को लॉग करने के लिए अमरूद या कॉमन्स लैंग को शामिल नहीं करना चाहती हैं। मैं Scala और Clojure पुस्तकालय लिखता हूं और निश्चित रूप से Apache Commons Lang को केवल एक विधि के लिए एक सकरात्मक निर्भरता नहीं बनाऊंगा।
jm0

जवाबों:


1039

Exceptionस्टैक ट्रेस को कनवर्ट करने के लिए निम्न विधि का उपयोग कर सकते हैं String। यह वर्ग अपाचे कॉमन्स-लैंग में उपलब्ध है जो कई लोकप्रिय खुले स्रोतों के साथ सबसे आम आश्रित पुस्तकालय है

org.apache.commons.lang.exception.ExceptionUtils.getStackTrace(Throwable)


88
@Stijn - निष्पक्ष होने के लिए (मैंने नीचे वर्तमान में सबसे अधिक मतदान वाला उत्तर लिखा है) यह कॉमन्स-लैंग को बहुत अधिक कार्यक्षमता के लिए देखने लायक है
ब्रायन एग्न्यू

54
@StijndeWitt कॉमन्स लैंग बहुत आम है। यह पहले से ही मेरी अधिकांश परियोजनाओं / कामों में मौजूद है।
WhyNotHugo

16
@ ह्यूगो धन्यवाद, एक नए पुस्तकालय को जोड़ने से बचने के लिए स्ट्रिंगराइटर का उपयोग करने जा रहा था - पता चलता है कि यह पहले से ही मेरी निर्भरता के 3 में से एक निर्भरता है। तो बाकी के लिए, अगर आपके पास पहले से है तो जांच लें।
नाथनियल

33
@MartinAsenov - अपने तर्क के बाद आप इस तरह के पुस्तकालय का उपयोग कभी नहीं करेंगे, क्या आप करेंगे? आप इसका उपयोग तब तक नहीं करेंगे जब तक आप पहले से इसका उपयोग नहीं कर रहे हैं?
ब्रायन एग्न्यू

16
Fyi, पैकेज बदल गया है और कक्षा अब है org.apache.commons.lang3.exception.ExceptionUtils:।
schmmd

2200

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);

505
यदि आप किसी बाहरी लाइब्रेरी को पसंद नहीं करते हैं, जैसे कि यह छोटा और सरल है, तो इस उत्तर का उपयोग करें।
स्टिजन डे विट

8
यह स्टैक ट्रेस ट्रिम करता है, उसी तरह प्रिंटस्टैकट्रेस ()। स्टैक में सभी अपवाद दिखाई देते हैं, लेकिन प्रत्येक अपवाद के लिए स्टैक को ट्रिम किया जा सकता है। पूरे ट्रेस की आवश्यकता वाले किसी व्यक्ति को इस पर विचार करना चाहिए।
लैला अगावे

5
यह, जैसा कि यह पता चला है, बहुत ज्यादा है क्या Apache ExceptionUtils.getStackTrace () विधि करता है। लगभग पत्र वास्तव में।
टिकटॉक

6
@BrianAgnew, आप बंद नहीं करना चाहिए StringWriterऔर PrintWriter?
मुहम्मद गालबाना

13
@BrianAgnew, उत्तर के लिए धन्यवाद। इसने मुझे उत्सुक कर दिया और यहाँ मुझे वही मिला जो है: stackoverflow.com/questions/14542535/…
मुहम्मद गेलबाना

459

यह काम करना चाहिए:

StringWriter sw = new StringWriter();
e.printStackTrace(new PrintWriter(sw));
String exceptionAsString = sw.toString();

69
जावा संदर्भ में संक्षिप्तता हमेशा पहाड़ी है। यही कारण है कि printStackTraceअभी लौटना चाहिए स्ट्रिंग, चाहे वह उपयोगकर्ता के लिए प्रिंट या नहीं :) पर निर्णय छोड़ने
दिमित्री

35
कंसोल में PrintStackTrace प्रिंटिंग स्वीकार्य है, लेकिन कम से कम एक गेटस्ट्रेस यह एक स्ट्रिंग के रूप में वापस आ रहा है जो डिफ़ॉल्ट रूप से उपलब्ध होना चाहिए
Mateus Viccari

5
इसका कौन सा भाग संक्षिप्त है? आपको 2 वस्तुओं का निर्माण करना होगा जो स्टैक ट्रेस को एक स्ट्रिंग में डालने के अलावा किसी भी उद्देश्य के लिए मौजूद नहीं हैं।
आर्टऑफवर्फ

7
@dmitry एक विधि जिसे printXXX()XXX प्रिंट करना चाहिए।
user207421

2
@Greg वास्तव में वह व्यंग्य भी नहीं था, उसे बस एक सादे पढ़ने की आवश्यकता थी जो उसने कहा।
एंड्रयू

224

यदि आप 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)

2
धन्यवाद। इस स्थिति में प्रत्येक पंक्ति में एक तिथि और टैग नहीं लिखा जाता है जैसा कि प्रिंटस्टैकट्रेस () में है।
कूलमाइंड

1
वास्तव में Log.getStackTraceString अपने मूल में उपरोक्त वर्णित (Droblewski के) StringWriter और Printwriter का उपयोग करता है।
माइकेल सेप

2
एंड्रॉइड लॉग में सिर्फ इसे प्रिंट करने का सबसे आसान तरीका है: Log.e("TAG", "My message", new Throwable());
एरिक एम। स्प्रेंगेल


113

चेतावनी: कारण शामिल नहीं है (जो आमतौर पर उपयोगी बिट है!)

public String stackTraceToString(Throwable e) {
    StringBuilder sb = new StringBuilder();
    for (StackTraceElement element : e.getStackTrace()) {
        sb.append(element.toString());
        sb.append("\n");
    }
    return sb.toString();
}

1
यदि आप ट्रेस ट्रिम करना चाहते हैं, तो मैं इस दृष्टिकोण के विस्तार के साथ जाऊंगा, उदाहरण के लिए एक मैक्सलाइन पैरामीटर पास करें और केवल ट्रेस में कई पंक्तियाँ जोड़ें
रिच सेलर

E.getStackTrace के बाद के कोष्ठक गायब हैं। सार्वजनिक स्थैतिक स्ट्रिंग stackTraceTring (अपवाद e) {StringBuilder sb = new StringBuilder (); for (StackTraceElement element: e.getStackTrace ()) {sb.append (element.toString ()); sb.append ("<br />"); } रिटर्न sb.toString (); }
आरएलसी

2
निश्चित नहीं है, लेकिन मुझे लगता है कि यह मूल कारण अपवाद के स्टैक ट्रेस को प्रिंट नहीं करेगा।
अपूर्व ०२०

7
आप जो कुछ भी करते हैं, ट्रेस ट्रिम नहीं करते हैं। यह मेरे साथ कई बार हुआ है, कई बार मैंने ग्लासफिश लॉग में एक स्टैक ट्रेस देखा, जिसमें उपयोगी भागों की छंटनी की गई थी।
सेहोरस्टमन

डॉस लेमर्स को खुश करने के String.format("%n")बजाय कुछ इसी तरह का उपयोग करें या कुछ करें "\n"
छत

89

मेरे लिए सबसे साफ और आसान तरीका था:

import java.util.Arrays;
Arrays.toString(e.getStackTrace());

37
कोड साफ है, लेकिन आउटपुट नहीं है। आपको अंत में .replaceAll (",", "\ n") करना होगा। हालाँकि आप उस इंडेंटेशन को खो देते हैं जो प्रिंटस्टैकट्रेस प्रस्तावित करता है।
रोष

4
यह तब उपयोगी होता है जब आप एक लाइन में ट्रेस लॉग करते हैं
वेबजॉकी

28
public static String getStackTrace(Throwable t) {
    StringWriter sw = new StringWriter();
    t.printStackTrace(new PrintWriter(sw));
    return sw.toString();
}

1
नमस्ते, मैं केवल यह बताना चाहूंगा कि उत्तर के टिप्पणी अनुभाग में बताया गया है कि वस्तुओं StringWriterऔर PrintWriterवस्तुओं को closeघ होना चाहिए .... (या मुझे लगता है कि PrintWriterइसे बंद करने के बाद से केवल जरूरतों को बंद करने की आवश्यकता StringWriterहै)
एरिक

8
प्रेरित से आप का मतलब नकल? आप केवल इसे एक विधि में रखते हैं ... यहां उत्तर पढ़ना "ग्राउंडहोग डे" देखने जैसा है
म्यूरेल

26

निम्न कोड आपको Stringलॉग 4J या यहां तक ​​कि एपीआई जैसे उपयोग किए बिना, पूरे स्टैकट्रेस को एक प्रारूप के साथ प्राप्त करने की अनुमति देता है 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.
}

1
हाँ, लेकिन इसकी थोड़ी भारी लगता है न? किसी भी उचित आकार के प्रोजेक्ट लॉगिंग फ्रेमवर्क में बहुत जरूरी है कि परेशान क्यों हो
mzzzzb

यह एक शुरुआत में त्रुटि संदेश नहीं दे रहा है। हालांकि जोड़ा जा सकता है
kommradHomer 11

आप साधारण संगति के बजाय स्ट्रिंग स्ट्रिंग का उपयोग करना चाह सकते हैं।
dedda1994

यह उपयोगी है जब आपको गोपनीयता कारणों से संदेश को लॉग करने की अनुमति नहीं है।
A1m

हालांकि यह जान लें कि यह समाधान आंतरिक कारणों
A1m

19

यहां एक संस्करण है जो सीधे कॉपी-पेस्ट करने योग्य है:

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परिभाषित किया गया है, है ना?
n611x007

16
Arrays.toString(thrown.getStackTrace())

स्टैक ट्रेस को प्रिंट करने के लिए अपने प्रोग्राम में स्ट्रींग में परिणाम को परिवर्तित करने का सबसे आसान तरीका है

LOGGER.log(Level.SEVERE, "Query Builder Issue Stack Trace : {0} ,Message : {1} objid {2}", new Object[]{Arrays.toString(e.getStackTrace()), e.getMessage(),objId});

मेरे लिए काम किया, कुछ भी नहीं छंटनी की जा रही है! अन्य उत्तर की तुलना में सरल भी w / o किसी भी बाहरी पुस्तकालय, महान जवाब!
शंग चेंग

16

स्टैक ट्रेस को एक में प्रिंट करें PrintStream, फिर उसे एक में बदलें String:

// ...

catch (Exception e)
{
    ByteArrayOutputStream out = new ByteArrayOutputStream(); 
    e.printStackTrace(new PrintStream(out));
    String str = new String(out.toByteArray());

    System.out.println(str);
}

1
यह सबसे सीधा जवाब है
DaSqy Stc

11

स्ट्रिंग के लिए मुद्रण स्टैक ट्रेस

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


11

Kotlin

थ्रोबेबल क्लास का विस्तार आपको स्ट्रिंग की संपत्ति देगा error.stackTraceString:

val Throwable.stackTraceString: String
  get() {
    val sw = StringWriter()
    val pw = PrintWriter(sw)
    this.printStackTrace(pw)
    return sw.toString()
  }

10
private String getCurrentStackTraceString() {
    StackTraceElement[] stackTrace = Thread.currentThread().getStackTrace();
    return Arrays.stream(stackTrace).map(StackTraceElement::toString)
            .collect(Collectors.joining("\n"));
}

1
धन्यवाद! यह मेरे सभी मामलों के लिए एकदम सही काम करता है। मैंने अभी-अभी इसे आधार TestNG क्लास में जोड़ा है और यह मेरे सभी परीक्षणों में से एक-एक करके स्टैकट्रैक्स इकट्ठा करता है!
Krzysztof Walczewski

9

टिप्पणियों के पहले सेट में चालाक छींक बहुत मनोरंजक था, लेकिन यह वास्तव में इस बात पर निर्भर करता है कि आप क्या करने की कोशिश कर रहे हैं। यदि आपके पास पहले से ही सही पुस्तकालय नहीं है, तो कोड की 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 )

इसने मेरी बेकन को बचा लिया। धन्यवाद, अमर, संकेत के लिए!


9

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


8

इसके बिना 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)

5

स्काला संस्करण

def stackTraceToString(e: Exception): String = {
  import java.io.PrintWriter
  val sw = new StringWriter()
  e.printStackTrace(new PrintWriter(sw))
  sw.toString
}

5

यदि आप जावा 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" से जुड़ें ।


यह समाधान स्टैक ट्रेस टैब इंडेंट का सम्मान नहीं करता है अन्यथा यह बहुत अच्छा काम करता है!
krizajb

4

गाला के उत्तर पर एक विस्तार जो अपवाद के कारणों को भी शामिल करेगा:

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;
}

4

समाधान सरणी के स्टैकट्रेस को स्ट्रिंग में बदलना है डेटा प्रकार में । निम्नलिखित उदाहरण देखें:

import java.util.Arrays;

try{

}catch(Exception ex){
    String stack = Arrays.toString(ex.getStackTrace());
    System.out.println("stack "+ stack);
}

4

जावा 8 स्ट्रीम एपीआई के साथ आप कुछ इस तरह से कर सकते हैं:

Stream
    .of(throwable.getStackTrace())
    .map(StackTraceElement::toString)
    .collect(Collectors.joining("\n"));

यह स्टैक ट्रेस तत्वों की सरणी लेगा, उन्हें स्ट्रिंग में परिवर्तित करेगा और मल्टीलाइन स्ट्रिंग में शामिल होगा।


2
यह समाधान संदेश को हटा रहा है और सभी अभिभावकों का पता लगाने में
आनाकानी कर रहा है

3

संलग्न बहु-पंक्ति स्ट्रिंग के लिए स्टैक ट्रेस को बदलने के लिए मेरा ऑनलाइनर:

Stream.of(e.getStackTrace()).map((a) -> a.toString()).collect(Collectors.joining("\n", "[", "]"))

लकड़हारा "जैसा है" पास करना आसान है।


आपको कुछ ऐसा मिलता है जो printStackTrace()यहां से अलग हो जाता है, आप ढीले हो जाएंगे: 1) अपवाद जो फेंक दिया गया था; 2) कारण और उनके स्टैकट्रेस
वैलीजोन

अंतर काफी अपेक्षित है, क्योंकि printStackTrace()कभी नहीं परिवर्तित करना सवाल का एक हिस्सा था।
एंड्रे लेब्डेंको

2

यदि आप बाहरी लाइब्रेरी का उपयोग नहीं करना चाहते हैं और आप 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();
}

2

पुराना सवाल है, लेकिन मैं सिर्फ उस विशेष मामले को जोड़ना चाहूंगा जहां आप सभी स्टैक को प्रिंट नहीं करना चाहते हैं , कुछ हिस्सों को हटाकर जिन्हें आप वास्तव में रुचि नहीं रखते हैं, कुछ वर्गों या पैकेजों को छोड़कर।

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कार्यान्वयन विवरण पर निर्भर करता है (परिवर्तन की संभावना नहीं है, लेकिन फिर भी)।


1
हां, यह अच्छी तरह से काम करता है और वास्तव में काफी उपयोगी विचार है।
21.42 पर gil.fernandes

2
 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)

1

मुझे आश्चर्य है कि किसी ने उल्लेख क्यों नहीं किया ExceptionUtils.getStackFrames(exception)

मेरे लिए यह अंत तक इसके सभी कारणों के साथ स्टैकट्रेस डंप करने का सबसे सुविधाजनक तरीका है:

String.join("\n", ExceptionUtils.getStackFrames(exception));

0

चेतावनी: यह विषय से थोड़ा हटकर हो सकता है, लेकिन अच्छी तरह से ...;)

मुझे नहीं पता कि मूल पोस्टर कारण क्या था क्योंकि पहली बार में स्टैक ट्रेस को स्ट्रिंग के रूप में चाहते हैं। जब स्टैक ट्रेस को SLF4J / लॉगबैक लॉग में समाप्त होना चाहिए, लेकिन कोई अपवाद नहीं था या यहां फेंक दिया जाना चाहिए कि मैं यहां क्या हूं:

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
}

मुझे यह पसंद है क्योंकि इसे बाहरी पुस्तकालय (आपके लॉगिंग बैकएंड के अलावा) की आवश्यकता नहीं है, जो कि ज्यादातर समय वैसे भी होगा, निश्चित रूप से)।


हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.