Comment utiliser ELMAH pour enregistrer manuellement les erreurs

est-il possible de faire ce qui suit en utilisant ELMAH?

logger.Log(" something");

je fais quelque chose comme ça:

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

cette exception ne sera pas automatiquement enregistrée par ELMAH, car elle a été traitée.

250
demandé sur Peter Mortensen 2011-09-16 10:42:56

8 réponses

méthode D'écriture directe en logarithme, qui fonctionne depuis ELMAH 1.0:

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

ELMAH 1.2 introduit une API plus flexible:

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

il y a une différence entre les deux solutions:

  • Raise la méthode applique les règles de filtrage ELMAH à l'exception. La méthode Log ne l'est pas.
  • Raise est basé sur l'abonnement et est capable d'enregistrer une exception dans les plusieurs enregistreur.
396
répondu Andrey Kamaev 2014-03-21 10:52:34

je vous recommande d'emballer L'appel à Elmah dans une classe simple d'emballage.

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
        }
    }
}

alors il suffit de l'appeler chaque fois que vous avez besoin d'enregistrer une erreur.

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

les prestations sont les suivantes:

  • vous n'avez pas besoin de vous souvenir de cette syntaxe légèrement archaïque de L'appel D'Elmah
  • si vous avez beaucoup de DLLs, vous n'avez pas besoin de faire référence à Elmah Core à partir de chacun d'eux - et juste mettez ceci dans votre propre DLL "système".
  • si vous avez besoin de faire une manipulation spéciale ou si vous voulez simplement mettre un point de rupture pour déboguer les erreurs, vous avez tout cela en un seul endroit.
  • si jamais vous vous éloignez D'Elmah, vous pouvez juste changer un endroit.
  • si vous avez l'historique de journalisation des erreurs que vous voulez conserver (il se trouve que j'ai un simple mécanisme de journalisation des erreurs qui est lié à certains UIs que je n'ai pas immédiatement le temps de supprimer).

Note: j'ai ajouté une propriété 'contextualMessage' pour des informations contextuelles. Vous pouvez l'omettre si vous préférez, mais je trouve cela très utile. Elmah déballe automatiquement les exceptions de sorte que l'exception sous-jacente sera quand même signalée dans le log mais le message contextuel sera visible lorsque vous cliquez dessus.

88
répondu Simon_Weaver 2013-02-13 03:12:20

vous pouvez utiliser L'Elmah.ErrorSignal () méthode pour enregistrer un problème sans faire d'exception.

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

    // Continue
}
29
répondu bigtv 2017-10-17 07:56:57
catch(Exception ex)
{
    Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
}
19
répondu Darin Dimitrov 2011-09-16 06:48:42

Oui, c'est possible. ELMAH a été conçu pour intercepter les exceptions sans entrave. Cependant, vous pouvez signaler une exception à ELMAH via la classe ErrorSignal. Ces exceptions ne sont pas jetées (ne font pas de bulles), mais sont seulement envoyées à ELMAH (et aux abonnés de L'événement Raise de la classe ErrorSignal).

un petit exemple:

protected void ThrowExceptionAndSignalElmah()
{
    ErrorSignal.FromCurrentContext().Raise(new NotSupportedException());
}
14
répondu Christophe Geers 2011-09-16 06:55:54

je cherchais à faire la même chose dans un thread que j'avais commencé à mettre en file d'attente du courrier depuis mon application MVC4, comme tel je n'avais pas le HttpContext disponible quand une exception a été soulevée. Pour ce faire, je me suis retrouvé avec ce qui suit basé sur cette question et une autre réponse trouvée ici: elmah: exceptions sans HttpContext?

dans le fichier de configuration, j'ai spécifié un nom de demande:

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

puis en code (comme la réponse fournie ci-dessus, mais sans le HttpContext) vous pouvez passer null au lieu d'un HttpContext:

ThreadPool.QueueUserWorkItem(t => {
     try {
         ...
         mySmtpClient.Send(message);
     } catch (SomeException e) {
         Elmah.ErrorLog.GetDefault(null).Log(new Elmah.Error(e));
     }
 });
13
répondu Matthew 2017-05-23 12:26:33

parfois CurrentHttpContext peut ne pas être disponible.

Définir

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 { }
    }
}

Utiliser

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
répondu tchelidze 2018-05-18 05:45:37

j'essayais d'écrire des messages personnalisés dans les journaux d'elmah en utilisant le Signal.FromCurrentContext ().Soulever des(ex); et a constaté que ces exceptions sont bouillonnait, par exemple:

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

D'ailleurs je ne vois pas comment elmah supporte différents niveaux de journalisation - est-il possible de désactiver la journalisation verbeuse par un web.paramètre de configuration?

0
répondu Valery Gavrilov 2017-03-06 22:55:16