如何使用ELMAH手动logging错误
是否可以使用ELMAH进行以下操作?
logger.Log(" something");
我正在做这样的事情:
try { // Code that might throw an exception } catch(Exception ex) { // I need to log error here... }
ELMAH不会自动logging此exception,因为它已被处理。
直接的日志写入方法,从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); }
这两个解决scheme之间有一个区别:
-
Raise
方法将ELMAH过滤规则应用于exception。Log
方法不。 -
Raise
是基于订阅的,并且能够将一个exceptionlogging到多个logging器中。
我build议在你自己的一个简单的包装类包装电话给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 } } }
那么只要你需要logging一个错误就打电话给它。
try { ... } catch (Exception ex) { // log this and continue ErrorLog.LogError(ex, "Error sending email for order " + orderID); }
这有以下好处:
- 你不需要记住这个Elmah调用的这个稍微陈旧的语法
- 如果你有很多DLL,你不需要从每一个引用Elmah核心 – 只要把它放在你自己的“系统”DLL中。
- 如果你需要做任何特殊的处理,或者只是想放置一个断点来debugging错误,那么你只需要一个地方。
- 如果你离开Elmah,你可以改变一个地方。
- 如果你有遗留的错误日志logging,你想保留(我只是碰巧有一个简单的错误logging机制,绑定到一些用户界面,我不马上有时间去除)。
注意:我已经为上下文信息添加了“contextualMessage”属性。 你可以省略这个,如果你喜欢,但我觉得它非常有用。 Elmah会自动解开exception,这样底层的exception仍然会在日志中报告,但是当你点击它时,contextualMessage将会显示。
您可以使用Elmah.ErrorSignal()方法logging问题而不引发exception。
try { // Some code } catch(Exception ex) { // Log error Elmah.ErrorSignal.FromCurrentContext().Raise(ex); // Continue }
catch(Exception ex) { Elmah.ErrorSignal.FromCurrentContext().Raise(ex); }
是的,这是可能的。 ELMAH被devise为拦截未处理的exception。 但是,您可以通过ErrorSignal类向ELMAH发出exception信号。 这些exception不会被抛出(不要冒泡),而只会发送给ELMAH(以及ErrorSignal类的Raise事件的订阅者)。
一个小例子:
protected void ThrowExceptionAndSignalElmah() { ErrorSignal.FromCurrentContext().Raise(new NotSupportedException()); }
我正在寻找在线程中做同样的事情,我已经开始排队从我的MVC4应用程序的邮件,因为我没有HttpContext提供exception时可用。 要做到这一点,我结束了以下基于这个问题和另一个答案在这里find: elmah:没有HttpContext的exception?
在configuration文件中,我指定了一个应用程序名称:
<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)); } });
在某些情况下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); } } }
我正在尝试使用Signal.FromCurrentContext()将自定义消息写入elmah日志。 并发现这些例外是冒泡的,例如:
try { ... } catch (Exception ex) { Elmah.ErrorSignal.FromCurrentContext().Raise(ex); // this will write to the log AND throw the exception }
另外,我不明白如何elmah支持不同级别的日志logging – 是否有可能通过web.config设置closures详细日志logging?