是否可以使用ELMAH执行以下操作?
logger.Log(" something");
我正在做这样的事情:
try
{
// Code that might throw an exception
}
catch(Exception ex)
{
// I need to log error here...
}
ELMAH不会自动记录此异常,因为它已被处理。
答案 0 :(得分:405)
直接日志写入方法,自ELMAH 1.0开始工作:
try
{
some code
}
catch(Exception ex)
{
Elmah.ErrorLog.GetDefault(HttpContext.Current).Log(new Elmah.Error(ex));
}
ELMAH 1.2引入了更灵活的API:
try
{
some code
}
catch(Exception ex)
{
Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
}
两种解决方案之间存在差异:
Raise
方法将ELMAH过滤规则应用于异常。 Log
方法没有。Raise
是基于订阅的,可以将一个例外记录到多个记录器中。答案 1 :(得分:90)
我建议在一个你自己的简单包装类中包含对Elmah的调用。
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
}
}
}
然后只要您需要记录错误就调用它。
try {
...
}
catch (Exception ex)
{
// log this and continue
ErrorLog.LogError(ex, "Error sending email for order " + orderID);
}
这有以下好处:
注意:我为上下文信息添加了“contextualMessage”属性。如果您愿意,可以省略它,但我发现它非常有用。 Elmah自动解包异常,因此仍然会在日志中报告基础异常,但是当您单击它时,contextualMessage将会显示。
答案 2 :(得分:29)
您可以使用Elmah.ErrorSignal()方法记录问题而不会引发异常。
try
{
// Some code
}
catch(Exception ex)
{
// Log error
Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
// Continue
}
答案 3 :(得分:19)
catch(Exception ex)
{
Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
}
答案 4 :(得分:14)
是的,有可能。 ELMAH旨在拦截未处理的异常。但是,您可以通过ErrorSignal类向ELMAH发出异常信号。这些异常不会被抛出(不要冒泡),而只是发送给ELMAH(以及ErrorSignal类的Raise事件的订阅者)。
一个小例子:
protected void ThrowExceptionAndSignalElmah()
{
ErrorSignal.FromCurrentContext().Raise(new NotSupportedException());
}
答案 5 :(得分:13)
我希望在我开始在我的MVC4应用程序中对邮件进行排队的线程中执行相同的操作,因此在引发异常时我没有HttpContext可用。为此,我根据这个问题找到了以下内容,并在此处找到了另一个答案:elmah: exceptions without HttpContext?
在配置文件中,我指定了一个应用程序名称:
<elmah>
<security allowRemoteAccess="false" />
<errorLog type="Elmah.SqlErrorLog, Elmah" connectionStringName="ELMAH" applicationName="myApplication"/>
</elmah>
然后在代码中(如上面提供的答案,但没有HttpContext),你可以传递null而不是HttpContext:
ThreadPool.QueueUserWorkItem(t => {
try {
...
mySmtpClient.Send(message);
} catch (SomeException e) {
Elmah.ErrorLog.GetDefault(null).Log(new Elmah.Error(e));
}
});
答案 6 :(得分:3)
有时CurrentHttpContext
可能无法使用。
<强>定义强>
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 { }
}
}
使用强>
public class MyClass
{
readonly ILogger _logger;
public MyClass(ILogger logger)
{
_logger = logger;
}
public void MethodOne()
{
try
{
}
catch (Exception ex)
{
_logger.LogError(ex, withinHttpContext: false);
}
}
}
答案 7 :(得分:2)
我在 ASP.NET核心上,并且使用 ElmahCore 。
要使用HttpContext手动记录错误 (在控制器中),只需编写:
using ElmahCore;
...
HttpContext.RiseError(new Exception("Your Exception"));
在应用程序的另一部分,没有HttpContext :
using ElmahCore;
...
ElmahExtensions.RiseError(new Exception("Your Exception"));
答案 8 :(得分:0)
我试图使用Signal.FromCurrentContext()将自定义消息写入elmah日志.Raise(ex);并发现这些例外是冒泡的,例如:
try
{
...
}
catch (Exception ex)
{
Elmah.ErrorSignal.FromCurrentContext().Raise(ex);
// this will write to the log AND throw the exception
}
此外我没有看到elmah如何支持不同级别的日志记录 - 是否可以通过web.config设置关闭详细日志记录?
答案 9 :(得分:0)
使用了此行,效果很好。
try{
//Code which may throw an error
}
catch(Exception ex){
ErrorLog.GetDefault(HttpContext.Current).Log(new Elmah.Error(ex));
}