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é gérée.
Méthode d'écriture directe du journal, fonctionnant 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
applique les règles de filtrage ELMAH à l'exception. La méthode Log
ne fonctionne pas.Raise
est basé sur un abonnement et peut enregistrer une exception dans plusieurs enregistreurs.Je recommanderais de placer l'appel à Elmah dans une classe de wrapper simple.
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
}
}
}
Ensuite, appelez-le chaque fois que vous devez enregistrer une erreur.
try {
...
}
catch (Exception ex)
{
// log this and continue
ErrorLog.LogError(ex, "Error sending email for order " + orderID);
}
Cela présente les avantages suivants:
Remarque: j'ai ajouté une propriété 'contextualMessage' pour les informations contextuelles. Vous pouvez l'omettre si vous préférez, mais je le trouve très utile. Elmah décompresse automatiquement les exceptions afin que l'exception sous-jacente soit toujours signalée dans le journal, mais que le message contextuel soit visible lorsque vous cliquez dessus.
Vous pouvez utiliser la méthode Elmah.ErrorSignal () pour enregistrer un problème sans déclencher une 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 non gérées. Cependant, vous pouvez signaler une exception à ELMAH via la classe ErrorSignal. Ces exceptions ne sont pas levées (ne font pas de bulles), mais sont uniquement 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 fil. J'avais commencé à mettre les messages en attente à partir de mon application MVC4; par conséquent, je n'avais pas le HttpContext disponible lorsqu'une exception était déclenchée. Pour ce faire, je me suis retrouvé avec ce qui suit sur la base de cette question et d’une autre réponse trouvée ici: elmah: des exceptions sans HttpContext?
Dans le fichier de configuration, j'ai spécifié un nom d'application:
<elmah>
<security allowRemoteAccess="false" />
<errorLog type="Elmah.SqlErrorLog, Elmah" connectionStringName="ELMAH" applicationName="myApplication"/>
</elmah>
Ensuite, dans le code (comme la réponse fournie ci-dessus, mais sans le HttpContext), vous pouvez passer null à la place 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 { }
}
}
Utilisation
public class MyClass
{
readonly ILogger _logger;
public MyClass(ILogger logger)
{
_logger = logger;
}
public void MethodOne()
{
try
{
}
catch (Exception ex)
{
_logger.LogError(ex, withinHttpContext: false);
}
}
}
Je suis sur noyau ASP.NET et j'utilise ElmahCore.
Pour consigner manuellement les erreurs avec HttpContext (dans le contrôleur), écrivez simplement:
using ElmahCore;
...
HttpContext.RiseError(new Exception("Your Exception"));
Dans une autre partie de votre application sans HttpContext:
using ElmahCore;
...
ElmahExtensions.RiseError(new Exception("Your Exception"));
J'essayais d'écrire des messages personnalisés dans les journaux elmah à l'aide de Signal.FromCurrentContext (). Raise (ex); et a constaté que ces exceptions sont remontées, par exemple:
try
{
...
}
catch (Exception ex)
{
Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
// this will write to the log AND throw the exception
}
En outre, je ne vois pas comment elmah prend en charge différents niveaux de journalisation - est-il possible de désactiver la journalisation détaillée par un paramètre web.config?