문제

방금 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 Viewer의 항목을 볼 수 있도록 구성의 어딘가에 응용 프로그램 이름을 유지해야한다는 것입니다.

그래서 우리의 일반적인 오류 처리 코드에서 우리는 다음을 수행합니다.

        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 사이트 외에 콘솔 앱과 Windows 서비스에서 로그인 할 수있는 기능이 필요했습니다. 나는 대답을 사용했다 (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>

선택한 SMTP 설정.

모두 완료되었습니다. :-)

편집하다: 이것 할 수 있다 완료 - 참조하십시오 이것 대답.


나는 당신이 이것을 할 수 없다고 확신합니다. 관련 자료를 찾아 보겠습니다.

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

따라서 Google 그룹을 검색 할 수있는 것은 불가능하다는 것입니다 ... Elmah는 httphandlers (ASP.NET 구성)에서 일하기 때문에 ASP.NET 전용입니다.

그 말로, 콘솔 애플리케이션에서 활용할 수있는 방법이 있습니다. Elmah는 오류를 제기하는 방법을 제공하므로 예외 처리에서 Elmah를 감싸고 다음을 통해 오류를 표시 할 수 있습니다.

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

이것은 예외 핸들러 및 신호로 전체 응용 프로그램을 포장하는 것을 의미합니다. 그것을 내려 놓는 데 약간의 조정이 필요할 수도 있지만, 나는 그것이 완전히 가능하다고 생각합니다.

필요한 경우, 이것이 링크입니다. Elmah 코드 저장소.

Brian Chance의 답변이 필요한 사람들을 위해 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"))

초기화 () 이후에 호출되면 작동합니다.

글쎄, 내가 언급 할 수 없기 때문에 여기에 이것을 게시하고 누군가가 그것을 볼 것입니다.

Brian의 방법과 댓글 작성자를 따른 후에는 이메일 작업을 할 수 있었지만 ApplicationName을 설정했지만 SQL 메시지가 기록되는 것을 보지 못했습니다. 내가 깨닫지 못한 것은 그들이 실제로 기록되고 있다는 것입니다. ApplicationName은 web.config와 동일해야하기 때문에 그것을 보지 못했습니다.

내 web.config에는 ApplicationName이 지정되지 않았으므로 "/lm/w3svc/2/root"로 기본적으로 표시되었습니다. 기본적으로 "ASGEO1"이 댓글을 달았습니다.

내가 걱정했던 오류가 실제로 없었기 때문에 web.config에서 ApplicationName을 구성하고 app.config가 동일하게 구성되었으며 이제 모든 것이 챔피언처럼 나타납니다.

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

Elmah는 오류 로깅 모듈 및 핸들러를 나타냅니다. IHttpModule 그리고 IHttpHandler.

콘솔 애플리케이션은 HTTP를 사용하지 않으므로 일반적으로 HTTP 용 모듈 및 핸들러에서 많은 혜택을받을 수 없습니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top