त्रुटियों को मैन्युअल रूप से लॉग करने के लिए ELMAH का उपयोग कैसे करें


259

क्या ईएलएमएएच का उपयोग करके निम्नलिखित करना संभव है?

logger.Log(" something");

मैं कुछ इस तरह कर रहा हूँ:

try 
{
    // Code that might throw an exception 
}
catch(Exception ex)
{
    // I need to log error here...
}

यह अपवाद स्वचालित रूप से ELMAH द्वारा लॉग नहीं किया जाएगा, क्योंकि यह नियंत्रित किया गया था।


1
भविष्य के संदर्भ के लिए, मैंने ठीक उसी के बारे में एक पोस्ट लिखी है: प्रोग्रामिंग त्रुटियों को तार्किक रूप से लॉग करना । मेरे ELMAH ट्यूटोरियल को इस बारे में कुछ जानकारी भी है।
थॉमसआर्डल

जवाबों:


412

एल्माह 1.0 के बाद से काम करने वाली सीधी लॉग राइटिंग विधि:

try 
{
    some code 
}
catch(Exception ex)
{
    Elmah.ErrorLog.GetDefault(HttpContext.Current).Log(new Elmah.Error(ex));
}

ELMAH 1.2 एक अधिक लचीला एपीआई पेश करता है:

try 
{
    some code 
}
catch(Exception ex)
{
    Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
}

दो समाधानों के बीच एक अंतर है:

  • Raiseविधि अपवाद के लिए ELMAH फ़िल्टरिंग नियम लागू करती है। Logविधि नहीं है।
  • Raise आधारित सदस्यता है और कई लॉगर में एक अपवाद लॉग करने में सक्षम है।

1
आपकी विधि और दूसरों के बीच क्या अंतर है?
ओमू

3
ये एल्माह में त्रुटि को लॉग करते हैं जिससे एप्लिकेशन काम करना बंद कर देता है। यह आपको सामान्य अपवादों को पकड़ने, उन्हें ठीक से संभालने की अनुमति देता है, लेकिन फिर भी उन्हें लॉग करने में सक्षम है।
PCasagrande

7
मैंने पाया कि Elmah.ErrorSignal तब लॉगिंग नहीं कर रहा था जब POST में Mvc4 .Net 4.5 के लिए असुरक्षित Html शामिल है, मेरे उदाहरण में एक SignInResponseMessage के साथ Windows Access Control Services से एक POST वापस। Elmah.ErrorLog.GetDefault ने उस परिदृश्य में काम किया
एडम

1
असुरक्षित एचटीएमएल के साथ मेरा भी यही मुद्दा था।
ErrorLog.GetDefault

4
उपयोग करते समय एक बड़ा चेतावनी Elmah.ErrorLog.Log(): यदि लॉग कॉल विफल हो जाती है, तो संभवत: यह संपूर्ण वेब ऐप को नीचे लाती है। Raise()चुपचाप विफल रहता है। उदाहरण के लिए: यदि सर्वर-साइड पर मिसकॉन्फ़िगरेशन समस्या है (जैसे एल्मा डिस्क को त्रुटियों को बचाने के लिए कॉन्फ़िगर किया गया है, लेकिन लॉग फ़ोल्डर में सही पहुंच नहीं है), तो .Log()विधि फेंक देगी। (यह डिबगिंग के लिए अच्छा है, उदाहरण के लिए, .Raise()कुछ भी लॉग इन क्यों नहीं किया जाता है?)
क्रिस्टियन डियाकोन्सु

91

मैं आपको कॉल करने की सलाह दूंगा एल्माह को अपने स्वयं के एक साधारण रैपर क्लास में।

using Elmah;

public static class ErrorLog
{
    /// <summary>
    /// Log error to Elmah
    /// </summary>
    public static void LogError(Exception ex, string contextualMessage=null)
    {
        try
        {
            // log error to Elmah
            if (contextualMessage != null) 
            {
                // log exception with contextual information that's visible when 
                // clicking on the error in the Elmah log
                var annotatedException = new Exception(contextualMessage, ex); 
                ErrorSignal.FromCurrentContext().Raise(annotatedException, HttpContext.Current);
            }
            else 
            {
                ErrorSignal.FromCurrentContext().Raise(ex, HttpContext.Current);
            }

            // send errors to ErrorWS (my own legacy service)
            // using (ErrorWSSoapClient client = new ErrorWSSoapClient())
            // {
            //    client.LogErrors(...);
            // }
        }
        catch (Exception)
        {
            // uh oh! just keep going
        }
    }
}

इसके बाद जब भी आपको कोई त्रुटि लॉग करने की आवश्यकता हो तो इसे कॉल करें।

try {
   ...
} 
catch (Exception ex) 
{
    // log this and continue
    ErrorLog.LogError(ex, "Error sending email for order " + orderID);
}

इसके निम्नलिखित लाभ हैं:

  • आपको एल्म कॉल के इस थोड़े पुरातन वाक्यविन्यास को याद रखने की आवश्यकता नहीं है
  • यदि आपके पास कई DLL हैं, तो आपको हर एक से Elmah Core को संदर्भित करने की आवश्यकता नहीं है - और इसे अपने स्वयं के 'DLL' सिस्टम में डालें।
  • यदि आपको कभी कोई विशेष हैंडलिंग करने की आवश्यकता होती है या आप केवल एक ही स्थान पर डिबग त्रुटियों के लिए एक विराम बिंदु में रखना चाहते हैं।
  • यदि आप कभी भी एल्माह से दूर जाते हैं तो आप बस एक जगह बदल सकते हैं।
  • यदि आपके पास विरासत त्रुटि लॉगिंग है जिसे आप बनाए रखना चाहते हैं (मैं बस एक साधारण त्रुटि लॉगिंग तंत्र है जो कुछ UI में बंधा हुआ है जिसे मेरे पास हटाने का समय नहीं है)।

नोट: मैंने प्रासंगिक जानकारी के लिए एक 'प्रासंगिक' मेसेजेज 'संपत्ति जोड़ी है। आप इसे पसंद कर सकते हैं यदि आप चाहें, लेकिन मुझे यह बहुत उपयोगी लगता है। एल्माह स्वचालित रूप से अपवादों को हटा देता है इसलिए अंतर्निहित अपवाद अभी भी लॉग में रिपोर्ट किया जाएगा, लेकिन जब आप उस पर क्लिक करते हैं तो प्रासंगिकता दिखाई देगी।


1
बहुत बढ़िया जवाब। हो सकता है कि एएलएमएएच बॉक्स से बाहर कुछ समान लागू करे। कभी-कभी बिना संदर्भ के किसी त्रुटि को डीबग करना वास्तव में मुश्किल होता है।
18

2
मुझे सब पसंद है लेकिन किसी भी माध्यमिक त्रुटियों को निगलने के साथ // uh oh! just keep going। यदि मेरी त्रुटि हैंडलिंग विफल हो रही है तो मैं जानना चाहता हूं। मैं चाहता हूं कि यह कुछ शोर करे।
जेरेमी कुक

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

1
यह एक विस्तार विधि के रूप में और भी बेहतर होगा।
स्टीफन कैनेडी

1
आप सोच रहे होंगे: नहीं, मैं कितनी मैन्युअल त्रुटियों से लॉग इन करने की कोशिश कर सकता था? मैंने सोचा था कि, लगभग एक साल पहले। लंबी कहानी छोटी: इस आवरण का उपयोग करें!
nmit026

29

किसी अपवाद को उठाए बिना किसी समस्या को लॉग करने के लिए आप Elmah.ErrorSignal () पद्धति का उपयोग कर सकते हैं।

try
{
    // Some code
}
catch(Exception ex)
{
    // Log error
    Elmah.ErrorSignal.FromCurrentContext().Raise(ex);

    // Continue
}


14

हाँ यह संभव है। ELMAH को बिना किसी अपवाद के अवरोधन के लिए डिज़ाइन किया गया था। हालाँकि आप ErrorSignal वर्ग के माध्यम से ELMAH के लिए एक अपवाद का संकेत कर सकते हैं। उन अपवादों को फेंका नहीं जाता है (बुलबुला न करें), लेकिन केवल ईएलएमएएच (और एररसिग्नल क्लास के राइज़ इवेंट के ग्राहकों को) को भेजे जाते हैं।

एक छोटा सा उदाहरण:

protected void ThrowExceptionAndSignalElmah()
{
    ErrorSignal.FromCurrentContext().Raise(new NotSupportedException());
}

13

मैं अपने MVC4 एप्लिकेशन के भीतर से मेल को पंक्तिबद्ध करने के लिए शुरू किया था एक धागे में मैं एक ही बात करने के लिए देख रहा था, जैसे कि एक अपवाद उठाया जब मैं HttpContext उपलब्ध नहीं था। ऐसा करने के लिए मैं इस सवाल के आधार पर निम्नलिखित के साथ समाप्त हो गया और एक और जवाब यहाँ पर मिला: elmah: HttpContext के बिना अपवाद?

कॉन्फ़िगरेशन फ़ाइल में मैंने एक एप्लिकेशन नाम निर्दिष्ट किया है:

<elmah>
    <security allowRemoteAccess="false" />
    <errorLog type="Elmah.SqlErrorLog, Elmah" connectionStringName="ELMAH" applicationName="myApplication"/>   
</elmah>

फिर कोड में (ऊपर दिए गए उत्तर की तरह, लेकिन HttpContext के बिना) आप HttpContext के बजाय नल पास कर सकते हैं:

ThreadPool.QueueUserWorkItem(t => {
     try {
         ...
         mySmtpClient.Send(message);
     } catch (SomeException e) {
         Elmah.ErrorLog.GetDefault(null).Log(new Elmah.Error(e));
     }
 });

मुझे आपका समाधान पसंद है; हालाँकि, मैं "एल्माह" को हल करने में असमर्थ हूँ। मेरे प्रोजेक्ट में। मैंने "एल्माह का उपयोग करते हुए" जोड़ने की कोशिश की; मेरे कोड में, लेकिन यह मेरे वर्तमान संदर्भ में मौजूद नहीं है।
तायर्स

@ टैरेस आपका packages.configलुक कैसा लगता है? क्या आप कुछ इस तरह देखते हैं <package id="elmah" version="1.2.2" targetFramework="net45" /> <package id="elmah.corelibrary" version="1.2.2" targetFramework="net45" /> <package id="elmah.sqlserver" version="1.2" targetFramework="net45" />':? क्या आपने NuGET के साथ इंस्टाल किया?
मैथ्यू

मैं हां कहना चाहूंगा, लेकिन मेरी परियोजना वर्तमान में स्रोत नियंत्रण में बंद है। मैं परियोजना में नमूना विन्यास फाइल से मैन्युअल रूप से एल्माह लागू किया।
तानाशाह

@Taersious इसे मैन्युअल रूप से कर रही हैं, तो आप Elmah संदर्भ परियोजना के लिए का उपयोग कर ... मैं इसे किसी भी तरह से काम करने के लिए उम्मीद करेंगे लागू करने से पहले जोड़ने था, लेकिन मुझे पता है कि जब nuget यह कहते लाइनों के ऊपर जोड़ दिए जाते हैंpackages.config
मैथ्यू

3

कभी-कभी CurrentHttpContextउपलब्ध नहीं हो सकता है।

परिभाषित करें

public class ElmahLogger : ILogger
{
    public void LogError(Exception ex, string contextualMessage = null, bool withinHttpContext = true)
    {
        try
        {
            var exc = contextualMessage == null 
                      ? ex 
                      : new ContextualElmahException(contextualMessage, ex);
            if (withinHttpContext)
                ErrorSignal.FromCurrentContext().Raise(exc);
            else
                ErrorLog.GetDefault(null).Log(new Error(exc));
        }
        catch { }
    }
}

उपयोग

public class MyClass
{
    readonly ILogger _logger;

    public MyClass(ILogger logger)
    {
        _logger = logger;
    }

    public void MethodOne()
    {
        try
        {

        }
        catch (Exception ex)
        {
            _logger.LogError(ex, withinHttpContext: false);
        }
    }
}

2

मैं ASP.NET कोर पर हूं और मैं ElmahCore का उपयोग करता हूं

HttpContext के साथ त्रुटियों को मैन्युअल रूप से लॉग करने के लिए (नियंत्रक में) बस लिखें:

using ElmahCore;
...
HttpContext.RiseError(new Exception("Your Exception"));

HttpContext के बिना आपके आवेदन के दूसरे भाग में :

using ElmahCore;
...
ElmahExtensions.RiseError(new Exception("Your Exception"));

0

मैं सिग्नल के माध्यम से एल्माह लॉग में कस्टम संदेश लिखने की कोशिश कर रहा था। सिग्नल। क्रॉनिक कॉंटेक्स्ट () (राइज़ (एक्स)); और पाया कि इन अपवादों को बुदबुदाया जाता है, जैसे:

try
{
    ...
}
catch (Exception ex)
{
    Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
    // this will write to the log AND throw the exception
}

इसके अलावा मैं यह नहीं देखता कि एल्म लॉगिंग के विभिन्न स्तरों का समर्थन कैसे करता है - क्या वेब.कॉन्फ़िग सेटिंग द्वारा वर्बोज़ लॉगिंग को बंद करना संभव है?


1
यदि आप एक अपवाद को पकड़ते हैं और इसे फिर से नहीं फेंकते हैं, तो अपवाद बुलबुला नहीं है। शायद मुझे गलतफहमी है? ELMAH लॉगिंग के विभिन्न स्तरों का समर्थन नहीं करता है। यह केवल त्रुटियों के लिए है।
थॉमसआर्डल

धन्यवाद, थॉमस। ठीक यही मैं पुष्टि करने की कोशिश कर रहा था
वलेरी गवरिलोव

0

इस लाइन का इस्तेमाल किया और यह पूरी तरह से ठीक काम करता है।

 try{
            //Code which may throw an error
    }
    catch(Exception ex){
            ErrorLog.GetDefault(HttpContext.Current).Log(new Elmah.Error(ex));
    }
हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.