سؤال

لقد بدأت للتو في استخدام ELMAH وأنا من المعجبين به.يدعم فريقي عددًا كبيرًا من تطبيقات الويب، وأنا متحمس بشكل خاص لأن ELMAH يتيح لنا حفظ الاستثناءات من كل تطبيق في نفس جدول قاعدة بيانات MS SQL.

نحن ندعم أيضًا عددًا قليلاً من تطبيقات وحدة التحكم وDLL وسطح المكتب.هل من الممكن استخدام ELMAH DLL لتسجيل الاستثناءات في هذه التطبيقات إلى نفس الموقع؟

هل كانت مفيدة؟

المحلول

لدينا بالضبط نفس الوضع هنا. تشغيل ELMAH لجميع التطبيقات على شبكة الإنترنت. وهناك عدد قليل منهم يكون المنظمون على أساس وحدة التحكم.

وبعد القيام ببعض الحفر خلال التعليمات البرمجية المصدر، يبدو أن التعليمات البرمجية التالية إلى العمل:

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

والمشكلة الحقيقية الوحيدة مع ما ورد أعلاه هو أنك بحاجة للحفاظ على اسم التطبيق في مكان ما في التكوين الخاص لتكون قادرة على مشاهدة الإدخالات على المشاهد 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));
        }

نصائح أخرى

ونحن بحاجة إلى القدرة على تسجيل من تطبيق وحدة التحكم وخدمة ويندوز بالإضافة إلى موقع ASP.NET لدينا. لقد استخدمت الجواب (ErrorLog.GetDefault(null);) التي عملت بشكل جيد حتى أنا في حاجة إلى البريد الإلكتروني أيضا.

وهكذا، وهنا هو بلدي الحل. أنه يتعامل مع سجل والبريد الإلكتروني وتويتر والتصفية (سواء في ملف التكوين وفي التعليمات البرمجية). لقد ملفوفة أيضا الدعوة الرئيسية كامتداد لاستثناء لذلك يمكن أن يسمى مثل: catch(Exception ex) { ex.LogToElmah(); }

لتصفية في التعليمات البرمجية، ربط المقابلة .Filtering الحدث: 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"/>. الرجوع إلى هذا المقتطف أن كنت تريد أن تبقي <errorMail async="true"/> في ملف التكوين الخاص بك (ليتم استخدامها عند HttpContext.Current غير متاح ).

إذا كنت ترغب فقط في البريد الإلكتروني سجل دون 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="from@email.com" to="to@email.com" />
  </elmah>

وإعدادات بروتوكول نقل البريد من اختيارك.

وكل ذلك. : -)

يحرر:هذا يستطيع يجب القيام به - انظر هذا إجابة.


أنا متأكد من أنك لا تستطيع أن تفعل هذا.سأحاول وحفر المواد ذات الصلة.

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

إذن مما يمكنني العثور عليه من البحث في مجموعة Google هو أنه ليس من الممكن ...وبما أن ELMAH يعمل خارج HttpHandlers (بنية asp.net)، فهو ASP.NET فقط.

ومع ذلك، هناك طرق يمكنك من خلالها الاستفادة منها في تطبيق وحدة التحكم.يوفر ELMAH طريقة لرفع الأخطاء، بحيث يمكنك تضمين ELMAH في معالجة الاستثناءات ثم الإشارة إلى خطأ عبر:

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

قد يعني هذا تغليف التطبيق بالكامل في معالج الاستثناء والإشارة.قد يتطلب الأمر بعض التغيير والتبديل للحصول عليه، لكنني أعتقد أنه ممكن تمامًا.

وفي حال كنت بحاجة لذلك، وهذا هو الرابط إلى مستودع رمز ELMAH.

لتلك التي تحتاج إلى إجابة براين فرصة لاستدار إلى 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"))

وستعمل إذا كان يتم استدعاء بعد تهيئة ()

حسنا، لأنني لا أستطيع التعليق أنا ما بعد هذا إلى هنا، وربما شخص ما سوف نرى ذلك.

وبعد اتباع طريقة براين وcommentors وكنت قادرا على الحصول على البريد الإلكتروني يعمل ولكن ما زلت لم رؤية الرسائل SQL يتم تسجيل، حتى ولو كنت قد حددت اسم التطبيق. ما لم أكن أدرك أن كانوا في الواقع يتم تسجيل أنا فقط لم رؤيتهم لأن APPLICATIONNAME يجب أن يكون نفس الملف web.config الخاص بك من أجل أن يكون قادرا على مشاهدته.

وبلدي الملف web.config لم يكن لديهم APPLICATIONNAME محددة، لذلك كان التعثر إلى "/ LM / W3SVC / 2 / ROOT"، الذي هو في الأساس ما علق "asgeo1"، على الرغم من أنني لم أكن أدرك أنه كان لابد من نفسه.

وبما أنني لم يكن لديك حقا أي أخطاء كنت المعنية، وتكوين APPLICATIONNAME في بلدي الملف web.config وبلدي app.config أن تكون هي نفسها، والآن كل شيء يظهر وكأنه بطل.

<errorLog type="Elmah.SqlErrorLog, Elmah" connectionStringName="ELMAH" applicationName="MyAppName" />

وELMAH لتقف على وحدات تسجيل خطأ ومعالجات - اشارة، بطبيعة الحال، إلى IHttpModule وIHttpHandler

. التطبيقات

وحدة التحكم لا تستخدم HTTP، لذلك عادة لا تكون قادرة على الاستفادة من ذلك بكثير من وحدات معالجات بنيت لHTTP.

مرخصة بموجب: CC-BY-SA مع الإسناد
لا تنتمي إلى StackOverflow
scroll top