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.
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éthodeLog
ne l'est pas. -
Raise
est basé sur l'abonnement et est capable d'enregistrer une exception dans les plusieurs enregistreur.
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.
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
}
catch(Exception ex)
{
Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
}
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());
}
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));
}
});
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);
}
}
}
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?