ASP.NET MVC में लॉगिंग त्रुटियां


109

मैं वर्तमान में अपवादों को लॉग करने के लिए अपने ASP.NET MVC एप्लिकेशन में log4net का उपयोग कर रहा हूं। जिस तरह से मैं यह कर रहा हूं वह मेरे सभी नियंत्रकों को बेसकंट्रोलर वर्ग से विरासत में मिला है। BaseController के OnActionExecuting ईवेंट में, मैं कोई भी अपवाद लॉग करता हूँ जो हो सकता है:

protected override void OnActionExecuted(ActionExecutedContext filterContext)
{
    // Log any exceptions
    ILog log = LogManager.GetLogger(filterContext.Controller.GetType());

    if (filterContext.Exception != null)
    {
        log.Error("Unhandled exception: " + filterContext.Exception.Message +
            ". Stack trace: " + filterContext.Exception.StackTrace, 
            filterContext.Exception);
    }
}

यह बहुत अच्छा काम करता है यदि नियंत्रक क्रिया के दौरान एक अनहेल्दी अपवाद हुआ।

404 त्रुटियों के लिए, मेरे पास मेरे web.config में एक कस्टम त्रुटि है जैसे:

<customErrors mode="On">
    <error statusCode="404" redirect="~/page-not-found"/>
</customErrors>

और नियंत्रक क्रिया में जो "पृष्ठ-न-पाया" url को संभालता है, मैं अनुरोध किए जा रहे मूल url को लॉग करता हूं:

[AcceptVerbs(HttpVerbs.Get)]
public ActionResult PageNotFound()
{
    log.Warn("404 page not found - " + Utils.SafeString(Request.QueryString["aspxerrorpath"]));

    return View();
}

और यह भी काम करता है।

समस्या यह है कि मैं कैसे .aspx पृष्ठों पर खुद को त्रुटियों को लॉग करने के लिए है। मान लें कि मेरे पास पृष्ठों या कुछ इनलाइन कोड में से एक पर एक संकलन त्रुटि है जो अपवाद को फेंक देगा:

<% ThisIsNotAValidFunction(); %>
<% throw new Exception("help!"); %>

ऐसा प्रतीत होता है कि HandleError विशेषता सही ढंग से साझा किए गए फ़ोल्डर में मेरे Error.aspx पृष्ठ पर इसे पुनः भेज रही है, लेकिन यह निश्चित रूप से मेरे BaseController की OnActionExecuted विधि द्वारा नहीं पकड़ा जा रहा है। मैं सोच रहा था कि मैं शायद Error.aspx पेज पर लॉगिंग कोड डाल सकता हूं, लेकिन मैं इस स्तर पर त्रुटि जानकारी को पुनर्प्राप्त करने के तरीके के बारे में अनिश्चित हूं।


ELMAH के लिए +1। यहाँ एक ELMAH ट्यूटोरियल है जिसे मैंने आपको शुरू करने में मदद करने के लिए लिखा था। कस्टम त्रुटि पृष्ठों आदि के साथ समस्याओं से बचने के लिए ASP.NET MVC का उपयोग करते समय एल्माह एमवीसी पैकेज का उपयोग करना भी याद रखें
थॉमसऑरडाल

वहाँ कुछ उत्पादों है कि .NET क्षुधा में होने वाली सभी त्रुटियों को लॉग करेगा वहाँ Theres। वे ELMAH या log4net के रूप में निम्न-स्तर के नहीं हैं, लेकिन यदि आप सिर्फ त्रुटियों की निगरानी और निदान करने का प्रयास कर रहे हैं, तो एक टन समय बचाएं : बग्सनाग और एयरब्रैक इनमें से दो हैं जो मुझे पता है। .NET
डॉन पी

जवाबों:


103

मैं एल्मा में प्लगिंग करके आपके वेब एप्लिकेशन को सरल बनाने पर विचार करूंगा ।

आप अपनी परियोजना में एल्माह असेंबली को जोड़ते हैं और फिर अपने web.config को कॉन्फ़िगर करते हैं। यह तब नियंत्रक या पृष्ठ स्तर पर बनाए गए अपवादों को लॉग करेगा। इसे विभिन्न विभिन्न स्थानों (जैसे SQL सर्वर, ईमेल आदि) में प्रवेश करने के लिए कॉन्फ़िगर किया जा सकता है। यह एक वेब फ्रंटएंड भी प्रदान करता है, ताकि आप अपवाद के लॉग के माध्यम से ब्राउज़ कर सकें।

इसकी सबसे पहली बात मैं किसी भी asp.net mvc ऐप से जोड़ता हूं।

मैं अभी भी log4net का उपयोग करता हूं, लेकिन मैं इसे डीबग / जानकारी लॉग करने के लिए उपयोग करता हूं, और एल्माह को सभी अपवाद छोड़ देता हूं।

आप इस प्रश्न में अधिक जानकारी भी पा सकते हैं कि आप अपने ASP.NET ऐप में त्रुटियों (अपवाद) को कैसे लॉग करते हैं?


3
मैंने हाल ही में एल्माह का उपयोग करना शुरू किया है और यह मेरे द्वारा उपयोग किए गए सबसे चालाक और सरलतम अपवादों में से एक है। मैंने एक पोस्ट पढ़ते हुए कहा कि MS को ASP.net में शामिल करना चाहिए और मैं सहमत हूं।
dtc

14
मुझे ऐप के लिए ELMAH और log4net दोनों की आवश्यकता क्यों है। प्रवेश? एक भी हल क्यों नहीं?
VJAI

अगर मेरे पास एन-टियर आर्किटेक्चर है तो भी क्या यह काम करेगा? नियंत्रक - सेवाएं - रिपॉजिटरी?
a.farkas2508

2
ELMAH ओवर-रेटेड है।
रॉनी ओवरबीए

क्या ELMAH मुफ्त में है?
डलास

38

आप Global.asax में OnError इवेंट में हुक कर सकते हैं।

कुछ इस तरह:

/// <summary>
/// Handles the Error event of the Application control.
/// </summary>
/// <param name="sender">The source of the event.</param>
/// <param name="e">The <see cref="System.EventArgs"/> instance containing the event data.</param>
protected void Application_Error(object sender, EventArgs e)
{
    if (Server != null)
    {
        Exception ex = Server.GetLastError();

        if (Response.StatusCode != 404 )
        {
            Logging.Error("Caught in Global.asax", ex);
        }

    }


}

3
यह सभी अपवादों को पकड़ना चाहिए। मैं इसे सबसे अच्छा अभ्यास मानता हूं।
आंद्रेई रैनिया

4
ReSharper के मूल्य विश्लेषण के अनुसार, Serverहमेशा गैर-शून्य रहेगा।
ड्रू नोक

6
404 को अनदेखा करना मेरे लिए उस तरह से काम नहीं किया जिस तरह से आपने इसे लिखा था। मैंने लिखाif (ex is HttpException && ((HttpException)ex).GetHttpCode() == 404) return;
पाउलोया

21

MVC3
Create Attribute जोकि HandleErrorInfoAttribute से विरासत में मिला है और इसमें लॉगिंग की आपकी पसंद शामिल है

public class ErrorLoggerAttribute : HandleErrorAttribute 
{
    public override void OnException(ExceptionContext filterContext)
    {
        LogError(filterContext);
        base.OnException(filterContext);
    }

    public void LogError(ExceptionContext filterContext)
    {
       // You could use any logging approach here

        StringBuilder builder = new StringBuilder();
        builder
            .AppendLine("----------")
            .AppendLine(DateTime.Now.ToString())
            .AppendFormat("Source:\t{0}", filterContext.Exception.Source)
            .AppendLine()
            .AppendFormat("Target:\t{0}", filterContext.Exception.TargetSite)
            .AppendLine()
            .AppendFormat("Type:\t{0}", filterContext.Exception.GetType().Name)
            .AppendLine()
            .AppendFormat("Message:\t{0}", filterContext.Exception.Message)
            .AppendLine()
            .AppendFormat("Stack:\t{0}", filterContext.Exception.StackTrace)
            .AppendLine();

        string filePath = filterContext.HttpContext.Server.MapPath("~/App_Data/Error.log");

        using(StreamWriter writer = File.AppendText(filePath))
        {
            writer.Write(builder.ToString());
            writer.Flush();
        }
    }

Global.asax RegisterGlobalFilters में जगह विशेषता

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

1

क्या आपने हैंडलेयर विशेषता का विस्तार करने के बारे में सोचा है? इसके अलावा, स्कॉट के पास नियंत्रकों / कार्यों पर फ़िल्टर इंटरसेप्टर्स के बारे में एक अच्छा ब्लॉग पोस्ट है


1

Error.aspx दृश्य इस तरह परिभाषित किया गया है:

namespace MvcApplication1.Views.Shared
{
    public partial class Error : ViewPage<HandleErrorInfo>
    {
    }
}

HandleErrorInfo में तीन गुण हैं: स्ट्रिंग ActionName स्ट्रिंग नियंत्रक नाम अपवाद अपवाद

आपको हैंड्रेलरइन्फो को एक्सेस करने में सक्षम होना चाहिए और इसलिए दृश्य के भीतर अपवाद।


0

आप HttpContext.Error की जांच करने की कोशिश कर सकते हैं, लेकिन मुझे इस पर यकीन नहीं है।

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