Log4j को स्टैकट्रेस कैसे भेजें?


152

कहते हैं कि आप एक अपवाद को पकड़ते हैं और मानक आउटपुट पर निम्न प्राप्त करते हैं (जैसे, कहते हैं, कंसोल) यदि आप एक 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 );
}

जवाबों:


262

आप सीधे लकड़हारे को अपवाद देते हैं, जैसे

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

यह स्टैक ट्रेस रेंडर करने के लिए log4j तक है।


32
लकड़हारा अपने पहले तर्क के लिए एक वस्तु लेता है और इसे () को आगे बढ़ाएगा। हालाँकि दूसरा तर्क थ्रोबल है और स्टैक ट्रेस प्रदर्शित करता है।
पीटर लॉरी

1
मुझे कभी नहीं पता है कि पहली स्ट्रिंग में क्या सामान करना है, आमतौर पर मैं सिर्फ log.error(e.getLocalizedMessage(), e)वही कर रहा हूं जो पूरी तरह से बेमानी है। क्या यह पहले तर्क के लिए एक अशक्त संभालती है?
मार्क पीटर्स 16

5
@ मर्क: इसे एक संदेश देने की कोशिश करें जो अपवाद के संदेश की तुलना में संदर्भ के लिए अधिक प्रासंगिक है, उदाहरण के लिए यह वास्तव में उस समय क्या करने की कोशिश कर रहा था?
स्कैफ़मैन

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

1
@skaffman: वास्तव में मैं उपयोग कर log4j-1.2.8.jarरहा हूं और मैं stackTraceअपनी लॉग फ़ाइल पर सभी मुद्रित करना चाहता था, इसलिए मैंने ऊपर दिए गए प्रयास की तरह उल्लेख किया है, लेकिन यह केवल मेरी लॉग फ़ाइल पर प्रिंट कर रहा है nullPointerException। मैं अपने कोड पर उपयोग किया गया था e.printStackTrace()यह सभी ट्रेस प्रिंट करता है। यह कोलावरी क्यों?
युबराज

9

यदि आप एक अपवाद को शामिल किए बिना स्टैकट्रेस लॉग करना चाहते हैं, तो बस यह करें:

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

3
System.lineSeparator () के लिए +1, इससे मुझे एक स्टैकट्रेस को प्रिंट करने में मदद मिली, जो मुझे एक दूरस्थ सेवा से प्रतिक्रिया के रूप में मिली
स्टेफ़नी

1
मैंने क्या खोजा है, लेकिन आपको
स्ट्रींगबर्ल का

9

आप स्टैक ट्रेस को स्ट्रिंग के रूप में भी प्राप्त कर सकते हैं ExceptionUtils.getStackTrace

देखें: ExceptionUtils.java

मैं इसका उपयोग केवल सरल log.debugरखने के लिए करता हूं log.error


4

सिर्फ इसलिए कि यह मेरे साथ हुआ और उपयोगी हो सकता है। अगर तुम यह करते हो

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

आपको अपवाद के शीर्षलेख मिलेंगे और पूरे स्टैकट्रेस नहीं। क्योंकि लकड़हारा यह सोचेगा कि आप एक स्ट्रिंग से गुजर रहे हैं। {}जैसा कि स्केफमैन ने कहा बिना करो


1
निश्चित रूप से आपको यहाँ पूरे स्टैक ट्रेस मिलेंगे, हालाँकि {} मुद्रित किया जाएगा शब्दशः भी (बिना किसी प्रतिस्थापन के)?
k1eran

1
इतना यकीन नहीं है मेरे दोस्त! यह मेरे लिए काम नहीं किया, मुझे केवल हेडर मिला। यह log4j के संस्करण पर निर्भर हो सकता है
iberbeu

@iberbeu सही है क्योंकि Throwable.toString()स्टैकट्रेस वापस नहीं आती है। (मान लें कि आप एक

4

स्कैफ़मैन का उत्तर निश्चित रूप से सही उत्तर है। जैसे सभी लकड़हारा तरीकों error(), warn(), info(), debug()एक दूसरे पैरामीटर के रूप में फेंकने योग्य ले:

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

हालाँकि, आप स्ट्रीट्रेस को स्ट्रिंग के रूप में भी निकाल सकते हैं। कभी-कभी यह उपयोगी हो सकता है यदि आप "{}" प्लेसहोल्डर का उपयोग करके फ़ॉर्मेटिंग सुविधा का लाभ उठाना चाहते हैं - विधि देखें void info(String var1, Object... var2);इस मामले में कहें कि आपके पास स्ट्रिंग के रूप में स्टैकट्रेस है, तो आप वास्तव में ऐसा कुछ कर सकते हैं:

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

मैंने वास्तव में एक ओपन सोर्स लाइब्रेरी लिखी है जिसमें स्टैकट्रेस के निष्कर्षण की उपयोगिता है, स्ट्रींग के कुछ शोर को स्मार्टली फिल्टर करने के विकल्प के साथ स्ट्रिंग के रूप में। Ie यदि आप उस पैकेज उपसर्ग को निर्दिष्ट करते हैं जिसे आप अपने निकाले गए स्टैकट्रेस में रुचि रखते हैं तो कुछ अप्रासंगिक भागों से फ़िल्टर किया जाएगा और आपको बहुत ही संरक्षित जानकारी के साथ छोड़ देगा। यहां लेख का लिंक दिया गया है जो बताता है कि पुस्तकालय में क्या उपयोगिताओं हैं और इसे कहां प्राप्त करना है (दोनों मावेन कलाकृतियों और गिट स्रोतों के रूप में) और साथ ही इसका उपयोग कैसे करें। ओपन सोर्स जावा लाइब्रेरी स्टैक ट्रेस फ़िल्टरिंग के साथ, साइलेंट स्ट्रिंग पार्सिंग यूनिकोड कनवर्टर और संस्करण की तुलना पैराग्राफ " स्टैकट्रेस शोर फ़िल्टर " देखें


1
एक दफन लेकिन अच्छा जवाब।
पायने

धन्यवाद, @पेने। मैं एक अच्छी प्रतिक्रिया की सराहना करता हूं
माइकल गैन्टमैन

2

यह उत्तर पूछे गए प्रश्न से संबंधित नहीं हो सकता है लेकिन प्रश्न के शीर्षक से संबंधित है।

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

1

Log4j 2 में, आप एक अपवाद से एक स्टैकट्रेस लॉग करने के लिए Logger.catching () का उपयोग कर सकते हैं ।

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

0

यह अच्छा log4j त्रुटि / अपवाद लॉगिंग होगा - स्प्लंक / अन्य लॉगिंग / मॉनिटरिंग एस / डब्ल्यू द्वारा पठनीय। सब कुछ कुंजी-मूल्य जोड़ी का रूप है। log4j एक्सेप्शन obj से स्टैक ट्रेस मिलेगाe

    try {
          ---
          ---
    } catch (Exception e) {
        log.error("api_name={} method={} _message=\"error description.\" msg={}", 
                  new Object[]{"api_name", "method_name", e.getMessage(), e});
    }


-1

आप bellow कोड का उपयोग कर सकते हैं:

import org.apache.logging.log4j.Logger;
import org.apache.logging.log4j.LogManager;

public class LogWriterUtility {
    Logger log;

    public LogWriterUtility(Class<?> clazz) {
        log = LogManager.getLogger(clazz);
    }

public void errorWithAnalysis( Exception exception) {

        String message="No Message on error";
        StackTraceElement[] stackTrace = exception.getStackTrace();
        if(stackTrace!=null && stackTrace.length>0) {
            message="";
            for (StackTraceElement e : stackTrace) {
                message += "\n" + e.toString();
            }
        }
        log.error(message);


    }

}

यहाँ आप कॉल कर सकते हैं: LogWriterUtility.errorWithAnalysis( YOUR_EXCEPTION_INSTANCE);

यह आपके लॉग में स्टैकट्रेस प्रिंट करेगा।


-2

इसे बनाएं class:

public class StdOutErrLog {

private static final Logger logger = Logger.getLogger(StdOutErrLog.class);

public static void tieSystemOutAndErrToLog() {
    System.setOut(createLoggingProxy(System.out));
    System.setErr(createLoggingProxy(System.err));
}

public static PrintStream createLoggingProxy(final PrintStream realPrintStream) {
    return new PrintStream(realPrintStream) {
        public void print(final String string) {
            logger.info(string);
        }
        public void println(final String string) {
            logger.info(string);
        }
    };
}
}

इसे अपने कोड में कॉल करें

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