2009-05-08 17 views
56

मैंने अभी ELMAH का उपयोग शुरू किया और एक प्रशंसक हूं। मेरी टीम बड़ी संख्या में वेब अनुप्रयोगों का समर्थन करती है और मैं विशेष रूप से उत्साहित हूं कि ईएलएमएएच हमें प्रत्येक एप्लिकेशन से अपवादों को उसी एमएस एसक्यूएल डेटाबेस तालिका में सहेजने देता है।कंसोल अनुप्रयोग में ELMAH का उपयोग

हम कुछ कंसोल, डीएलएल और डेस्कटॉप अनुप्रयोगों का भी समर्थन करते हैं। क्या इन ऐप्स में अपवादों को उसी स्थान पर अपवाद लॉग करने के लिए ELMAH DLL का उपयोग करना संभव है?

+0

मैं इसे विंडोज सेवा में भी लागू करने की योजना बना रहा हूं। अगर हम ऐसा करते हैं तो बस जांचना चाहते हैं कि कोई प्रदर्शन समस्या हो सकती है या कोई अन्य समस्या हो सकती है? ऐसा लगता है कि यह मुख्य रूप से वेब आधारित अनुप्रयोगों के लिए है। मुझे विंडोज़ अनुप्रयोगों में इसे कार्यान्वित करने के तरीके पर बहुत अधिक सामग्री नहीं मिली है।धन्यवाद सोनी – hangar18

उत्तर

64

हमारे पास बिल्कुल वही स्थिति है। हमारे सभी वेब अनुप्रयोगों के लिए ELMAH चल रहा है। उनमें से कुछ में कंसोल आधारित शेड्यूलर हैं।

  ErrorLog errorLog = ErrorLog.GetDefault(null); 
      errorLog.ApplicationName = "/LM/W3SVC/1/ROOT/AppName"; 
      errorLog.Log(new Error(ex)); 

ऊपर के साथ ही वास्तविक समस्या यह है कि आप सक्षम होने के लिए अपने config में कहीं आवेदन नाम रखने की जरूरत है:

स्रोत कोड के माध्यम से कुछ खुदाई करने के बाद, निम्नलिखित कोड काम करने के लिए लगता है ELMAH.axd व्यूअर पर प्रविष्टियों को देखने के लिए।

इसलिए हमारे सामान्य त्रुटि हैंडलिंग कोड में हम करते हैं:

 if (HttpContext.Current != null) 
      ErrorSignal.FromCurrentContext().Raise(ex); 
     else 
     { 
      ErrorLog errorLog = ErrorLog.GetDefault(null); 
      errorLog.ApplicationName = ErrorHandling.Application; 
      errorLog.Log(new Error(ex)); 
     } 
+0

बहुत अच्छा, मैं इसे आज़माउंगा। –

+2

हम्म - बहुत अच्छा है, लेकिन कंसोल ऐप में त्रुटि होने पर मुझे ईमेल भेजने के लिए प्रतीत नहीं होता है। कोई विचार? – teedyay

+3

असंभव, errorLog.Log अन्य सभी श्रोताओं को बाईपास करना प्रतीत होता है। किसी को भी बेहतर पता है? –

5

संपादित: यह किया जा सकता है - this उत्तर देखें।


मैं बहुत यदि आप ऐसा नहीं कर सकते हैं यकीन है। मैं प्रासंगिक सामग्री को आजमाऊंगा और खोदूँगा।

http://groups.google.com/group/elmah/browse_thread/thread/f214c4f782dc2bf4/d96fe43b60765f0c?lnk=gst&q=app#d96fe43b60765f0c

तो मैं गूगल समूह खोज क्या मिल सकता से यह केवल ASP.NET है कि यह संभव नहीं है ... के बाद से ELMAH HttpHandlers की (एक asp.net निर्माण) बंद काम करता है।

इसके साथ, ऐसे तरीके हैं जिन्हें आप इसे कंसोल एप्लिकेशन पर उपयोग कर सकते हैं।

ErrorSignal.FromCurrentContext().Raise(new NotSupportedException()); 

यह अपवाद संचालक और संकेतन में अपने पूरे आवेदन लपेटकर मतलब होगा: ELMAH ताकि आप अपने अपवाद हैंडलिंग में ELMAH लपेट सकते हैं और फिर के माध्यम से एक त्रुटि संकेत, त्रुटियों को बढ़ाने के लिए एक तरीका प्रदान करता है। यह आपको इसे कम करने के लिए कुछ tweaking ले सकता है, लेकिन मुझे लगता है कि यह पूरी तरह से संभव है।

यदि आपको इसकी आवश्यकता हो, तो यह ELMAH code repository का लिंक है।

+0

धन्यवाद। मैं समझता हूं कि यह इसके चारों ओर नहीं बनाया गया था, लेकिन ऐसा लगता है कि दूसरों की आवश्यकता हो सकती है, एक सामान्य त्रुटि साझा करने के लिए डीबी –

-5

ELMAH त्रुटि लॉगिंग मॉड्यूल और हैंडलर के लिए खड़ा है - निश्चित रूप से, चर्चा करते हुए, IHttpModule और IHttpHandler करने के लिए।

कंसोल अनुप्रयोग HTTP का उपयोग नहीं करते हैं, इसलिए आमतौर पर HTTP के लिए बनाए गए मॉड्यूल और हैंडलर से अधिक लाभ नहीं उठा पाएंगे।

75

हमें हमारी एएसपी.NET साइट के अतिरिक्त एक कंसोल ऐप और विंडोज सेवा से लॉग इन करने की क्षमता की आवश्यकता है। मैंने जवाब (ErrorLog.GetDefault(null);) का उपयोग किया जो तब तक अच्छा काम करता था जब तक मुझे ईमेल करने की आवश्यकता नहीं थी।

तो, मेरा समाधान यहां है। यह लॉग, ईमेल, ट्वीट और फ़िल्टरिंग (कॉन्फ़िगरेशन फ़ाइल और कोड दोनों में) को संभालता है। मैंने मुख्य कॉल को अपवाद के विस्तार के रूप में भी लपेट लिया है, इसलिए इसे catch(Exception ex) { ex.LogToElmah(); }

कोड में फ़िल्टर करने के लिए, संबंधित को हुक करें।छनन घटना: ElmahExtension.ErrorLog.Filtering += new ExceptionFilterEventHandler(ErrorLog_Filtering);

कोड:

using System; 
using System.Web; 
using Elmah; 
namespace System 
{ 
    public static class ElmahExtension 
    { 
     public static void LogToElmah(this Exception ex) 
     { 
      if (HttpContext.Current != null) 
      { 
       ErrorSignal.FromCurrentContext().Raise(ex); 
      } 
      else 
      { 
       if (httpApplication == null) InitNoContext(); 
       ErrorSignal.Get(httpApplication).Raise(ex); 
      } 
     } 

      private static HttpApplication httpApplication = null; 
      private static ErrorFilterConsole errorFilter = new ErrorFilterConsole(); 

      public static ErrorMailModule ErrorEmail = new ErrorMailModule(); 
      public static ErrorLogModule ErrorLog = new ErrorLogModule(); 
      public static ErrorTweetModule ErrorTweet = new ErrorTweetModule(); 

      private static void InitNoContext() 
      { 
       httpApplication = new HttpApplication(); 
       errorFilter.Init(httpApplication); 

       (ErrorEmail as IHttpModule).Init(httpApplication); 
       errorFilter.HookFiltering(ErrorEmail); 

       (ErrorLog as IHttpModule).Init(httpApplication); 
       errorFilter.HookFiltering(ErrorLog);     

       (ErrorTweet as IHttpModule).Init(httpApplication); 
       errorFilter.HookFiltering(ErrorTweet); 
      } 

      private class ErrorFilterConsole : ErrorFilterModule 
      { 
       public void HookFiltering(IExceptionFiltering module) 
       { 
        module.Filtering += new ExceptionFilterEventHandler(base.OnErrorModuleFiltering); 
       } 
      } 
    } 
} 

इसके अलावा, आप इस काम करने के लिए अपनी परियोजना में System.Web.dll के लिए एक संदर्भ जोड़ने की आवश्यकता होगी।

संपादित करें: टिप्पणियों के अनुसार, यह कोड केवल ईमेल भेजेगा यदि आपकी कॉन्फ़िगरेशन फ़ाइल में <errorMail async="false"/> है। this code snippet का संदर्भ लें, क्या आप अपनी कॉन्फ़िगरेशन फ़ाइल में <errorMail async="true"/> रखना चाहते हैं (जब HttpContext.Current उपलब्ध हो तब उपयोग किया जाना चाहिए)।

+0

बहुत बढ़िया पोस्ट। यह मेरे लिए पूरी तरह से काम किया। बस मेरे app.config और चिकनी नौकायन में web.config से सामान्य सामान रखना पड़ा! –

+6

यह एक यूनिट परीक्षण में मेरे लिए काम नहीं कर रहा था जब तक कि मैं सेट करता हूं। मैंने पहले एसिंक को सत्य पर सेट किया था। –

+0

पोस्ट के लिए धन्यवाद - महान काम किया! हमने ErrorLog_Filtering, ErrorLog_Logged, ErrorMail_Filtering, ErrorMail_Mailing, ErrorMail_Mailed, ErrorMail_Disposing मेल को उचित कक्षाओं (ExceptionFilterEventHandler, ErrorLoggedEventHandler, आदि) का उपयोग करके मेल करें – Zugwalt

9

तुम सिर्फ बगैर http लॉग ईमेल करने के लिए चाहते हैं, तो आप इस तरह कर सकते हैं:

public class MyElmahMail: ErrorMailModule 
    { 
     public MyElmahMail() 
     { 
//this basically just gets config from errorMail (app.config) 
      base.OnInit(new HttpApplication()); 
     } 
     public void Log(Error error) 
     { 
//just send the email pls 
      base.ReportError(error); 
     } 
    } 

//to call it 
var mail = new MyElmahMail(); 
mail.Log(new Error(new NullReferenceException()));//whatever exception u want to log 

और app.config के मामले में

//Under configSections 
    <sectionGroup name="elmah"> 
     <section name="security" requirePermission="false" type="Elmah.SecuritySectionHandler, Elmah" /> 
     <section name="errorLog" requirePermission="false" type="Elmah.ErrorLogSectionHandler, Elmah" /> 
     <section name="errorMail" requirePermission="false" type="Elmah.ErrorMailSectionHandler, Elmah" /> 
     <section name="errorFilter" requirePermission="false" type="Elmah.ErrorFilterSectionHandler, Elmah" /> 
    </sectionGroup> 

और

<elmah> 
    <errorLog type="Elmah.XmlFileErrorLog, Elmah" logPath="C:\Elmah.Error" applicationName="MyAwesomeApp" /> 
    <errorMail from="[email protected]" to="[email protected]" /> 
    </elmah> 

और आपकी पसंद की smtp सेटिंग्स।

सब कुछ किया गया। :-)

+1

उत्तर नीचे हाथ! eeeeverything कोशिश करने के बाद यह पहले कोशिश की! –

2

उन है कि ब्रायन संभावना के जवाब VB.NET में पोर्ट की जरूरत के लिए:

Imports System 
Imports System.Web 
Imports Elmah 
Namespace System 
    Public NotInheritable Class ElmahExtension 
     Private Sub New() 
     End Sub 
     <System.Runtime.CompilerServices.Extension> _ 
     Public Shared Sub LogToElmah(ex As Exception) 
      If HttpContext.Current IsNot Nothing Then 
       ErrorSignal.FromCurrentContext().Raise(ex) 
      Else 
       If httpApplication Is Nothing Then 
        InitNoContext() 
       End If 
       ErrorSignal.[Get](httpApplication).Raise(ex) 
      End If 
     End Sub 

     Private Shared httpApplication As HttpApplication = Nothing 
     Private Shared errorFilter As New ErrorFilterConsole() 

     Public Shared ErrorEmail As New ErrorMailModule() 
     Public Shared ErrorLog As New ErrorLogModule() 
     Public Shared ErrorTweet As New ErrorTweetModule() 

     Private Shared Sub InitNoContext() 
      httpApplication = New HttpApplication() 
      errorFilter.Init(httpApplication) 

      TryCast(ErrorEmail, IHttpModule).Init(httpApplication) 
      errorFilter.HookFiltering(ErrorEmail) 

      TryCast(ErrorLog, IHttpModule).Init(httpApplication) 
      errorFilter.HookFiltering(ErrorLog) 

      TryCast(ErrorTweet, IHttpModule).Init(httpApplication) 
      errorFilter.HookFiltering(ErrorTweet) 
     End Sub 



    Private Class ErrorFilterConsole 
     Inherits Elmah.ErrorFilterModule 


     Public Sub HookFiltering([module] As Elmah.IExceptionFiltering) 
      AddHandler [module].Filtering, New Elmah.ExceptionFilterEventHandler(AddressOf MyBase.OnErrorModuleFiltering) 
     End Sub 

    End Class 


    End Class 
End Namespace 

हालांकि, सिर्फ डेटाबेस के लिए त्रुटियों प्रवेश करने के लिए, इस के लिए पर्याप्त होगा:

If System.Web.HttpContext.Current Is Nothing Then 
    Dim req As System.Web.HttpRequest = New System.Web.HttpRequest(String.Empty, "https://www.domain.tld", Nothing) 
    Dim res As System.Web.HttpResponse = New System.Web.HttpResponse(Nothing) 
    System.Web.HttpContext.Current = New System.Web.HttpContext(req, res) 

    'Dim request As System.Web.Hosting.SimpleWorkerRequest = New System.Web.Hosting.SimpleWorkerRequest("/blah", "c:\inetpub\wwwroot\blah", "blah.html", Nothing, New System.IO.StringWriter()) 
    'System.Web.HttpContext.Current = New System.Web.HttpContext(request) 

    System.Web.HttpContext.Current.ApplicationInstance = New System.Web.HttpApplication() 

    Dim ErrorLog As New Elmah.ErrorLogModule() 
    TryCast(ErrorLog, System.Web.IHttpModule).Init(System.Web.HttpContext.Current.ApplicationInstance) 
End If 

के रूप में एक पूर्ण समाधान:

Public parent As Elmah.ServiceProviderQueryHandler = Nothing 




' http://stackoverflow.com/questions/5981750/configuring-elmah-with-sql-server-logging-with-encrypted-connection-string 
Public Function Elmah_MS_SQL_Callback(objContext As Object) As System.IServiceProvider 
    Dim container As New System.ComponentModel.Design.ServiceContainer(parent(objContext)) 
    Dim strConnectionString As String = COR.SQL.MS_SQL.GetConnectionString() 

    Dim log As Elmah.SqlErrorLog = New Elmah.SqlErrorLog(strConnectionString) 
    'Dim strApplicationName = System.Web.Compilation.BuildManager.GetGlobalAsaxType().BaseType.Assembly().FullName 
    Dim strApplicationName As String = System.Reflection.Assembly.GetExecutingAssembly().FullName 
    If Not String.IsNullOrEmpty(strApplicationName) Then 
     log.ApplicationName = strApplicationName.Substring(0, strApplicationName.IndexOf(",")) 
    End If 

    container.AddService(GetType(Elmah.ErrorLog), log) 
    Return container 
End Function ' Elmah_MS_SQL_Callback 




Public Function Elmah_PG_SQL_Callback(objContext As Object) As System.IServiceProvider 
    Dim container As New System.ComponentModel.Design.ServiceContainer(parent(objContext)) 
    Dim strConnectionString As String = COR.SQL.MS_SQL.GetConnectionString() 

    Dim log As Elmah.PgsqlErrorLog = New Elmah.PgsqlErrorLog(strConnectionString) 
    'Dim strApplicationName = System.Web.Compilation.BuildManager.GetGlobalAsaxType().BaseType.Assembly().FullName 
    Dim strApplicationName As String = System.Reflection.Assembly.GetExecutingAssembly().FullName 
    If Not String.IsNullOrEmpty(strApplicationName) Then 
     log.ApplicationName = strApplicationName.Substring(0, strApplicationName.IndexOf(",")) 
    End If 

    container.AddService(GetType(Elmah.ErrorLog), log) 
    Return container 
End Function ' Elmah_PG_SQL_Callback 


' http://weblogs.asp.net/stevewellens/archive/2009/02/01/debugging-a-deployed-site.aspx 
Public Sub Initialize() 

    If System.Web.HttpContext.Current Is Nothing Then 
     Dim req As System.Web.HttpRequest = New System.Web.HttpRequest(String.Empty, "https://www.domain.tld", Nothing) 
     Dim res As System.Web.HttpResponse = New System.Web.HttpResponse(Nothing) 
     System.Web.HttpContext.Current = New System.Web.HttpContext(req, res) 

     'Dim request As System.Web.Hosting.SimpleWorkerRequest = New System.Web.Hosting.SimpleWorkerRequest("/blah", "c:\inetpub\wwwroot\blah", "blah.html", Nothing, New System.IO.StringWriter()) 
     'System.Web.HttpContext.Current = New System.Web.HttpContext(request) 

     System.Web.HttpContext.Current.ApplicationInstance = New System.Web.HttpApplication() 

     Dim ErrorLog As New Elmah.ErrorLogModule() 
     TryCast(ErrorLog, System.Web.IHttpModule).Init(System.Web.HttpContext.Current.ApplicationInstance) 
    End If 



    parent = Elmah.ServiceCenter.Current 

    If SQL.IsMsSql Then 
     Elmah.ServiceCenter.Current = AddressOf Elmah_MS_SQL_Callback 
    End If 

    If SQL.IsPostGreSql Then 
     Elmah.ServiceCenter.Current = AddressOf Elmah_PG_SQL_Callback 
    End If 
End Sub ' InitializeElmah 

और

+०१२३५१६४१०६१
Elmah.ErrorSignal.FromCurrentContext().Raise(New NotImplementedException("Test")) 

अगर यह प्रारंभ के बाद कहा जाता है काम करेंगे()

1

ठीक है, के बाद से मैं टिप्पणी नहीं कर सकता मैं यहाँ इस नीचे पोस्ट करेंगे और शायद किसी को इसे देखेंगे।

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

मेरे web.config में एप्लिकेशन नाम निर्दिष्ट नहीं था, इसलिए यह "/ एलएम/डब्ल्यू 3 एसवीसी/2/रूट" के लिए डिफ़ॉल्ट था, जो मूल रूप से "asgeo1" टिप्पणी करता था, हालांकि मुझे नहीं पता था कि यह होना चाहिए वही।

चूंकि मुझे वास्तव में कोई त्रुटि नहीं थी, जिसके बारे में मुझे चिंता थी, मैंने अपने web.config में applicationName कॉन्फ़िगर किया और मेरा app.config वही होना और अब सब कुछ एक चैंप की तरह दिखाई देता है।

<errorLog type="Elmah.SqlErrorLog, Elmah" connectionStringName="ELMAH" applicationName="MyAppName" /> 
संबंधित मुद्दे