asp.net-mvc - एएसपी.नेट एमवीसी[हैंडलरर]विशेषता के साथ काम करने के लिए ELMAH कैसे प्राप्त करें?




logging (8)

मैं अपने एएसपी.नेट एमवीसी अनुप्रयोग में त्रुटियों को लॉग करने के लिए ELMAH का उपयोग करने की कोशिश कर रहा हूं, हालांकि जब मैं अपने नियंत्रकों पर [हैंडलरर] विशेषता का उपयोग करता हूं तो ELMAH होने पर किसी भी त्रुटि को लॉग नहीं करता है।

जैसा कि मैं अनुमान लगा रहा हूं क्योंकि ELMAH केवल अनचाहे त्रुटियों को लॉग करता है और [HandleError] विशेषता त्रुटि को संभालने में सक्षम होती है इसलिए इस प्रकार इसे लॉग करने की आवश्यकता नहीं होती है।

मैं कैसे संशोधित करूं या विशेषता को संशोधित करने के बारे में कैसे जाउंगा ताकि ELMAH यह जान सके कि कोई त्रुटि हुई और लॉग इन करें ..

संपादित करें: मुझे यह सुनिश्चित करने दें कि हर कोई समझता है, मुझे पता है कि मैं उस विशेषता को संशोधित कर सकता हूं जो मैं पूछ रहा हूं ... ELMAH हैंडलर विशेषता का उपयोग करते समय बाईपास हो जाता है जिसका अर्थ यह नहीं होगा कि यह एक त्रुटि थी क्योंकि इसे संभाला गया था पहले से ही विशेषता से ... मैं जो पूछ रहा हूं वह ईएलएमएएच को त्रुटि देखने और इसे लॉग करने के लिए एक तरीका है, हालांकि विशेषता ने इसे संभाला है ... मैंने चारों ओर खोज की है और इसे लॉग इन करने के लिए मजबूर करने के लिए कॉल करने के लिए कोई भी तरीका नहीं दिख रहा है त्रुटि....


Answers

अब NuGet में एक ELMAH.MVC पैकेज है जिसमें एटीफ द्वारा एक बेहतर समाधान और एक नियंत्रक भी शामिल है जो एमवीसी रूटिंग के भीतर एल्मा इंटरफ़ेस को नियंत्रित करता है (अब उस axd का उपयोग करने की आवश्यकता नहीं है)
उस समाधान (और यहां सभी के साथ) की समस्या यह है कि एक तरीका या दूसरा एल्मा त्रुटि हैडलर वास्तव में त्रुटि को संभालने में सक्षम है, जिसे आप कस्टमरर टैग के रूप में सेट अप करना चाहते हैं या त्रुटिहैंडर या अपने स्वयं के त्रुटि हैंडलर के माध्यम से
सबसे अच्छा समाधान आईएमएचओ एक फ़िल्टर बनाना है जो अन्य सभी फ़िल्टरों के अंत में कार्य करेगा और पहले से संभाले गए ईवेंट लॉग इन करेगा। Elmah मॉड्यूल को अन्य त्रुटियों को लॉग इन करने का ख्याल रखना चाहिए जो एप्लिकेशन द्वारा अनचाहे हैं। यह आपको स्वास्थ्य मॉनीटर और अन्य सभी मॉड्यूल का उपयोग करने की अनुमति देगा जिसे त्रुटि घटनाओं को देखने के लिए एएसपीनेट में जोड़ा जा सकता है

मैंने elmah.mvc के अंदर ErrorHandler पर परावर्तक के साथ यह लिखा है

public class ElmahMVCErrorFilter : IExceptionFilter
{
   private static ErrorFilterConfiguration _config;

   public void OnException(ExceptionContext context)
   {
       if (context.ExceptionHandled) //The unhandled ones will be picked by the elmah module
       {
           var e = context.Exception;
           var context2 = context.HttpContext.ApplicationInstance.Context;
           //TODO: Add additional variables to context.HttpContext.Request.ServerVariables for both handled and unhandled exceptions
           if ((context2 == null) || (!_RaiseErrorSignal(e, context2) && !_IsFiltered(e, context2)))
           {
            _LogException(e, context2);
           }
       }
   }

   private static bool _IsFiltered(System.Exception e, System.Web.HttpContext context)
   {
       if (_config == null)
       {
           _config = (context.GetSection("elmah/errorFilter") as ErrorFilterConfiguration) ?? new ErrorFilterConfiguration();
       }
       var context2 = new ErrorFilterModule.AssertionHelperContext((System.Exception)e, context);
       return _config.Assertion.Test(context2);
   }

   private static void _LogException(System.Exception e, System.Web.HttpContext context)
   {
       ErrorLog.GetDefault((System.Web.HttpContext)context).Log(new Elmah.Error((System.Exception)e, (System.Web.HttpContext)context));
   }


   private static bool _RaiseErrorSignal(System.Exception e, System.Web.HttpContext context)
   {
       var signal = ErrorSignal.FromContext((System.Web.HttpContext)context);
       if (signal == null)
       {
           return false;
       }
       signal.Raise((System.Exception)e, (System.Web.HttpContext)context);
       return true;
   }
}

अब, अपने फ़िल्टर कॉन्फ़िगरेशन में आप ऐसा कुछ करना चाहते हैं:

    public static void RegisterGlobalFilters(GlobalFilterCollection filters)
    {
        //These filters should go at the end of the pipeline, add all error handlers before
        filters.Add(new ElmahMVCErrorFilter());
    }

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

अब, सुनिश्चित करें कि आपके webconfig में elmah के लिए ऐप्स सेटिंग्स इस तरह दिखते हैं:

<add key="elmah.mvc.disableHandler" value="false" /> <!-- This handles elmah controller pages, if disabled elmah pages will not work -->
<add key="elmah.mvc.disableHandleErrorFilter" value="true" /> <!-- This uses the default filter for elmah, set to disabled to use our own -->
<add key="elmah.mvc.requiresAuthentication" value="false" /> <!-- Manages authentication for elmah pages -->
<add key="elmah.mvc.allowedRoles" value="*" /> <!-- Manages authentication for elmah pages -->
<add key="elmah.mvc.route" value="errortracking" /> <!-- Base route for elmah pages -->

यहां महत्वपूर्ण है "elmah.mvc.disableHandleErrorFilter", यदि यह गलत है तो यह elmah.mvc के अंदर हैंडलर का उपयोग करेगा जो वास्तव में डिफ़ॉल्ट हैंडलरर हैडलर का उपयोग कर अपवाद को संभालेगा जो आपकी कस्टमरर सेटिंग्स को अनदेखा कर देगा

यह सेटअप आपको कक्षाओं और विचारों में अपने स्वयं के त्रुटि हैंडलर टैग सेट करने की अनुमति देता है, जबकि अभी भी ElmahMVCErrorFilter के माध्यम से उन त्रुटियों को लॉग इन करते हुए, elmah मॉड्यूल के माध्यम से अपने web.config पर कस्टम एरर कॉन्फ़िगरेशन जोड़कर, अपने स्वयं के त्रुटि हैंडलर भी लिखते हैं। केवल एक चीज जो आपको करने की ज़रूरत है वह याद रखना है कि कोई भी फ़िल्टर नहीं जोड़ना जो वास्तव में हमारे द्वारा लिखे गए एल्मा फ़िल्टर से पहले त्रुटि को संभालेगा। और मैं उल्लेख करना भूल गया: elmah में कोई डुप्लीकेट नहीं।


आप उपरोक्त कोड ले सकते हैं और एक कस्टम नियंत्रक फैक्ट्री पेश करके एक कदम आगे जा सकते हैं जो प्रत्येक नियंत्रक में हैंडलरर विथइल्मा विशेषता को इंजेक्ट करता है।

अधिक जानकारी के लिए एमवीसी में लॉग इन करने पर मेरी ब्लॉग श्रृंखला देखें। पहला लेख एल्माह स्थापित करने और एमवीसी के लिए चल रहा है।

लेख के अंत में डाउनलोड करने योग्य कोड का एक लिंक है। उम्मीद है की वो मदद करदे।

http://dotnetdarren.wordpress.com/


मैं एएसपी.नेट एमवीसी में नया हूं। मुझे एक ही समस्या का सामना करना पड़ा, मेरे Erorr.vbhtml में मेरा काम करने योग्य है (यह काम करता है अगर आपको केवल एल्मा लॉग का उपयोग करके त्रुटि लॉग करने की आवश्यकता है)

@ModelType System.Web.Mvc.HandleErrorInfo

    @Code
        ViewData("Title") = "Error"
        Dim item As HandleErrorInfo = CType(Model, HandleErrorInfo)
        //To log error with Elmah
        Elmah.ErrorLog.GetDefault(HttpContext.Current).Log(New Elmah.Error(Model.Exception, HttpContext.Current))
    End Code

<h2>
    Sorry, an error occurred while processing your request.<br />

    @item.ActionName<br />
    @item.ControllerName<br />
    @item.Exception.Message
</h2> 

यह बस है!


आप OnException को उप-वर्गीकृत कर सकते हैं और इसके OnException सदस्य (प्रतिलिपि की कोई आवश्यकता नहीं) को ओवरराइड कर सकते हैं ताकि यह OnException साथ अपवाद लॉग करे और केवल तभी जब मूल कार्यान्वयन इसे संभाल सके। आपको आवश्यक कोड की न्यूनतम मात्रा निम्नानुसार है:

using System.Web.Mvc;
using Elmah;

public class HandleErrorAttribute : System.Web.Mvc.HandleErrorAttribute
{
    public override void OnException(ExceptionContext context)
    {
        base.OnException(context);
        if (!context.ExceptionHandled) 
            return;
        var httpContext = context.HttpContext.ApplicationInstance.Context;
        var signal = ErrorSignal.FromContext(httpContext);
        signal.Raise(context.Exception, httpContext);
    }
}

आधार कार्यान्वयन पहले लागू किया जाता है, जिससे इसे अपवाद को चिह्नित करने का मौका दिया जाता है। केवल अपवाद संकेत दिया गया है। उपर्युक्त कोड सरल है और यदि ऐसे वातावरण में उपयोग किया जाता है जो HttpContext उपलब्ध नहीं हो सकता है, जैसे परीक्षण। नतीजतन, आप कोड चाहते हैं जो कि अधिक रक्षात्मक है (थोड़ी देर की लागत पर):

using System.Web;
using System.Web.Mvc;
using Elmah;

public class HandleErrorAttribute : System.Web.Mvc.HandleErrorAttribute
{
    public override void OnException(ExceptionContext context)
    {
        base.OnException(context);
        if (!context.ExceptionHandled       // if unhandled, will be logged anyhow
            || TryRaiseErrorSignal(context) // prefer signaling, if possible
            || IsFiltered(context))         // filtered?
            return;

        LogException(context);
    }

    private static bool TryRaiseErrorSignal(ExceptionContext context)
    {
        var httpContext = GetHttpContextImpl(context.HttpContext);
        if (httpContext == null)
            return false;
        var signal = ErrorSignal.FromContext(httpContext);
        if (signal == null)
            return false;
        signal.Raise(context.Exception, httpContext);
        return true;
    }

    private static bool IsFiltered(ExceptionContext context)
    {
        var config = context.HttpContext.GetSection("elmah/errorFilter")
                        as ErrorFilterConfiguration;

        if (config == null)
            return false;

        var testContext = new ErrorFilterModule.AssertionHelperContext(
                              context.Exception, 
                              GetHttpContextImpl(context.HttpContext));
        return config.Assertion.Test(testContext);
    }

    private static void LogException(ExceptionContext context)
    {
        var httpContext = GetHttpContextImpl(context.HttpContext);
        var error = new Error(context.Exception, httpContext);
        ErrorLog.GetDefault(httpContext).Log(error);
    }

    private static HttpContext GetHttpContextImpl(HttpContextBase context)
    {
        return context.ApplicationInstance.Context;
    }
}

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

आपको यह भी ध्यान रखना पड़ सकता है कि यदि एकाधिक HandleErrorAttribute उदाहरण प्रभावी हैं तो डुप्लिकेट लॉगिंग नहीं होती है, लेकिन उपर्युक्त दो उदाहरणों को शुरू करना चाहिए।


एक पूरी तरह से वैकल्पिक समाधान एमवीसी HandleErrorAttribute उपयोग नहीं करना है, और इसके बजाय एएसपी.Net त्रुटि हैंडलिंग पर निर्भर है, जिसे एल्माह के साथ काम करने के लिए डिज़ाइन किया गया है।

आपको App_Start \ FilterConfig (या Global.asax) से डिफ़ॉल्ट वैश्विक हैंडलरर एट्रिब्यूट को हटाने की आवश्यकता है, और फिर अपने Web.config में एक त्रुटि पृष्ठ सेट अप करें:

<customErrors mode="RemoteOnly" defaultRedirect="~/error/" />

ध्यान दें, यह एक एमवीसी रूटेड यूआरएल हो सकता है, इसलिए जब कोई त्रुटि होती है तो उपरोक्त त्रुटि ErrorController.IndexErrorController.Index कार्रवाई पर रीडायरेक्ट करेगा।


मेरे लिए ईमेल लॉगिंग काम करना बहुत महत्वपूर्ण था। कुछ समय बाद मुझे पता चला कि इसे आतिफ उदाहरण में कोड की केवल 2 पंक्तियों की आवश्यकता है।

public class HandleErrorWithElmahAttribute : HandleErrorAttribute
{
    static ElmahMVCMailModule error_mail_log = new ElmahMVCMailModule();

    public override void OnException(ExceptionContext context)
    {
        error_mail_log.Init(HttpContext.Current.ApplicationInstance);
        [...]
    }
    [...]
}

मुझे उम्मीद है कि यह किसी की मदद करेगा :)


क्षमा करें, लेकिन मुझे लगता है कि स्वीकृत उत्तर एक ओवरकिल है। आपको बस इतना करना है:

public class ElmahHandledErrorLoggerFilter : IExceptionFilter
{
    public void OnException (ExceptionContext context)
    {
        // Log only handled exceptions, because all other will be caught by ELMAH anyway.
        if (context.ExceptionHandled)
            ErrorSignal.FromCurrentContext().Raise(context.Exception);
    }
}

और फिर इसे पंजीकृत करें (ऑर्डर महत्वपूर्ण है) Global.asax.cs में:

public static void RegisterGlobalFilters (GlobalFilterCollection filters)
{
    filters.Add(new ElmahHandledErrorLoggerFilter());
    filters.Add(new HandleErrorAttribute());
}

अगर आपकी विधि को एचटीएमएल वापस करने की ज़रूरत नहीं है और उसे कुछ और करना है तो आप रेजर में सहायक विधि के बजाय लैम्ब्डा का उपयोग कर सकते हैं

@{
    ViewBag.Title = "Index";
    Layout = "~/Views/Shared/_Layout.cshtml";

    Func<int,int,int> Sum = (a, b) => a + b;
}

<h2>Index</h2>

@Sum(3,4)






asp.net-mvc logging elmah