web-dev-qa-db-ger.com

Wie man ELMAH verwendet, um Fehler manuell zu protokollieren

Kann man mit ELMAH folgendes tun?

logger.Log(" something");

Ich mache so etwas:

try 
{
    // Code that might throw an exception 
}
catch(Exception ex)
{
    // I need to log error here...
}

Diese Ausnahme wird nicht automatisch von ELMAH protokolliert, da sie behandelt wurde.

254
Omu

Direktes Protokollschreibverfahren, das seit ELMAH 1.0 funktioniert:

try 
{
    some code 
}
catch(Exception ex)
{
    Elmah.ErrorLog.GetDefault(HttpContext.Current).Log(new Elmah.Error(ex));
}

ELMAH 1.2 führt eine flexiblere API ein:

try 
{
    some code 
}
catch(Exception ex)
{
    Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
}

Es gibt einen Unterschied zwischen den beiden Lösungen:

  • Die Raise-Methode wendet ELMAH-Filterregeln auf die Ausnahme an. Log-Methode funktioniert nicht.
  • Raise ist abonnementbasiert und kann eine Ausnahme in den verschiedenen Loggern protokollieren.
403
Andrey Kamaev

Ich würde empfehlen, den Anruf an Elmah in einer einfachen eigenen Wrapper-Klasse zu wickeln.

using Elmah;

public static class ErrorLog
{
    /// <summary>
    /// Log error to Elmah
    /// </summary>
    public static void LogError(Exception ex, string contextualMessage=null)
    {
        try
        {
            // log error to Elmah
            if (contextualMessage != null) 
            {
                // log exception with contextual information that's visible when 
                // clicking on the error in the Elmah log
                var annotatedException = new Exception(contextualMessage, ex); 
                ErrorSignal.FromCurrentContext().Raise(annotatedException, HttpContext.Current);
            }
            else 
            {
                ErrorSignal.FromCurrentContext().Raise(ex, HttpContext.Current);
            }

            // send errors to ErrorWS (my own legacy service)
            // using (ErrorWSSoapClient client = new ErrorWSSoapClient())
            // {
            //    client.LogErrors(...);
            // }
        }
        catch (Exception)
        {
            // uh oh! just keep going
        }
    }
}

Dann rufen Sie es einfach an, wenn Sie einen Fehler protokollieren möchten.

try {
   ...
} 
catch (Exception ex) 
{
    // log this and continue
    ErrorLog.LogError(ex, "Error sending email for order " + orderID);
}

Dies hat folgende Vorteile:

  • Sie müssen sich nicht an diese etwas archaische Syntax des Elmah-Aufrufs erinnern
  • Wenn Sie über viele DLLs verfügen, müssen Sie nicht von jedem einzelnen auf Elmah Core verweisen. Fügen Sie dies einfach in Ihre eigene 'System'-DLL ein.
  • Wenn Sie jemals eine spezielle Behandlung durchführen müssen oder nur einen Haltepunkt zum Debuggen von Fehlern angeben möchten, haben Sie alles an einem Ort.
  • Wenn Sie sich jemals von Elmah entfernen, können Sie einfach einen Ort wechseln.
  • Wenn Sie eine ältere Fehlerprotokollierung haben, möchten Sie diese beibehalten (ich habe einfach einen einfachen Fehlerprotokollierungsmechanismus, der an einige UIs gebunden ist, die ich nicht sofort entfernen kann).

Hinweis: Ich habe eine 'contextualMessage'-Eigenschaft für Kontextinformationen hinzugefügt. Sie können dies weglassen, wenn Sie möchten, aber ich finde es sehr nützlich. Elmah packt automatisch Ausnahmen aus, sodass die zugrunde liegende Ausnahme immer noch im Protokoll gemeldet wird. Wenn Sie jedoch darauf klicken, wird die contextualMessage angezeigt.

90
Simon_Weaver

Sie können die Elmah.ErrorSignal () - Methode verwenden, um ein Problem zu protokollieren, ohne eine Ausnahme auszulösen.

try
{
    // Some code
}
catch(Exception ex)
{
    // Log error
    Elmah.ErrorSignal.FromCurrentContext().Raise(ex);

    // Continue
}
29
bigtv
catch(Exception ex)
{
    Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
}
19
Darin Dimitrov

Ja, es ist möglich. ELMAH wurde entwickelt, um nicht behandelte Ausnahmen abzufangen. Sie können jedoch über die Klasse ErrorSignal eine Ausnahme an ELMAH melden. Diese Ausnahmen werden nicht ausgelöst (blase nicht auf), sondern nur an ELMAH (und an Abonnenten des Raise-Ereignisses der ErrorSignal-Klasse).

Ein kleines Beispiel:

protected void ThrowExceptionAndSignalElmah()
{
    ErrorSignal.FromCurrentContext().Raise(new NotSupportedException());
}
14

Ich habe versucht, dasselbe in einem Thread zu tun, mit dem ich Mail aus meiner MVC4-Anwendung in eine Warteschlange gestellt hatte, da mir HttpContext nicht zur Verfügung stand, als eine Ausnahme ausgelöst wurde. Um dies zu tun, endete ich mit der folgenden Frage basierend auf dieser Frage und einer anderen Antwort, die hier zu finden ist: elmah: Ausnahmen ohne HttpContext?

In der Konfigurationsdatei habe ich einen Anwendungsnamen angegeben:

<elmah>
    <security allowRemoteAccess="false" />
    <errorLog type="Elmah.SqlErrorLog, Elmah" connectionStringName="ELMAH" applicationName="myApplication"/>   
</elmah>

Dann können Sie im Code (wie in der Antwort oben, aber ohne den HttpContext) null anstelle eines HttpContext übergeben:

ThreadPool.QueueUserWorkItem(t => {
     try {
         ...
         mySmtpClient.Send(message);
     } catch (SomeException e) {
         Elmah.ErrorLog.GetDefault(null).Log(new Elmah.Error(e));
     }
 });
13
Matthew

Manchmal ist CurrentHttpContext nicht verfügbar. 

Definieren

public class ElmahLogger : ILogger
{
    public void LogError(Exception ex, string contextualMessage = null, bool withinHttpContext = true)
    {
        try
        {
            var exc = contextualMessage == null 
                      ? ex 
                      : new ContextualElmahException(contextualMessage, ex);
            if (withinHttpContext)
                ErrorSignal.FromCurrentContext().Raise(exc);
            else
                ErrorLog.GetDefault(null).Log(new Error(exc));
        }
        catch { }
    }
}

Benutzen

public class MyClass
{
    readonly ILogger _logger;

    public MyClass(ILogger logger)
    {
        _logger = logger;
    }

    public void MethodOne()
    {
        try
        {

        }
        catch (Exception ex)
        {
            _logger.LogError(ex, withinHttpContext: false);
        }
    }
}
3
tchelidze

Ich bin auf ASP.NET-Kern und ich verwende ElmahCore.

Um Fehler manuell zu protokollieren mit HttpContext (in der Steuerung), schreiben Sie einfach:

using ElmahCore;
...
HttpContext.RiseError(new Exception("Your Exception"));

In einem anderen Teil Ihrer Anwendung ohne HttpContext:

using ElmahCore;
...
ElmahExtensions.RiseError(new Exception("Your Exception"));
1
A. Morel

Ich habe versucht, benutzerdefinierte Meldungen mit Hilfe von Signal.FromCurrentContext () in elmah-Protokolle zu schreiben. Raise (ex); und festgestellt, dass diese Ausnahmen sprudeln, zB:

try
{
    ...
}
catch (Exception ex)
{
    Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
    // this will write to the log AND throw the exception
}

Außerdem sehe ich nicht, wie elmah verschiedene Protokollierungsstufen unterstützt. Kann ich die ausführliche Protokollierung mit einer web.config-Einstellung ausschalten?

0
Valery Gavrilov