Elmah & Elmah.MVC - a .net Error Logging Modules and Handlers

What’s Elmah

Elmah,Error Logging Modules and Hanlders,是一个基于.net平台的日志管理和处理的工具包,可以与Asp.net Web应用项目进行集成,包括Asp.net Web MVC和Web Api。

Elmah可以帮助记录系统中没有处理的异常,同时它也提供Api允许开发人员记录当前上下文中捕获的异常;它的一个颇具特色的优点是,Elmah提供一个查看日志的Web网页,包含详细的异常Call-Stack,方便进行调试诊断问题;系统支持人员可以通过Web服务本地或远程访问,也可以下载日志到本地进行详细诊断;

image

这里要注意的一个问题就是远程访问的安全问题,毕竟日志会暴露系统很多的实现细节,比如cookie,访问Url等,一旦日志泄露,将会使得系统存在被侵入的风险。

从实现技术讲,Elmah捕捉异常的方式主要基于 Asp.net Http Pipeline中IHttpModule和IHttpHandler模块对请求、响应、上下文以及异常事件的处理能力,依赖Web.config对其进行配置,所以可以很容易的与系统集成。

Elmah支持日志的多种存储,可以以文件方式(xml)进行存储,也可以存储于SqlServer, Oracle, SQLite,mySql等数据库中。同时Elmah还支持邮件,Rss feed等方式分发日志。

Why Elmah

在.net领域中记录日志有log4net, Nlog, Elmah等多种选择,很长一段时间我们的系统(Asp.net Web应用)在使用Nlog。但是在引入Elmah后,我更喜欢Elmah一些。

基于Elmah核心库的Elmah.MVC扩展使得Elmah与Asp.net MVC的应用集成更简单,无痛配置,很容易的就使得系统可以基于当前HttpContext自动捕获未处理的异常记录日志;同时,Elmah提供查看异常日志详细信息的Web页面给它加分很多,相对于从浩瀚的文本内容中搜寻错误,Web页面要更便利;

另一方面,Elmah在NuGet Gallery的下载排行榜中非常活跃,经常处于top10 of the last 6 week的位置,也是我们选择它的一个原因。

Integrate Elmah.MVC

1.安装

在Visual Studio中选中需要使用Elmah的项目,在Reference -> Manage NuGet Packages,找到Elmah.MVC 包即可安装,如下图所示。

image

也可以通过VisualStudio的Package Manager Console.

installation lang: powershell
1
2
Install-Package Elmah.MVC

安装后会自动在Web.config文件中添加Elmah的配置项,包括记日志的相关modules和空白的elmah节点.

web.config
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
<sectionGroup name="elmah">
<section name="security" requirePermission="false" type="Elmah.SecuritySectionHandler, Elmah" />
<section name="errorLog" requirePermission="false" type="Elmah.ErrorLogSectionHandler, Elmah" />
<section name="errorMail" requirePermission="false" type="Elmah.ErrorMailSectionHandler, Elmah" />
<section name="errorFilter" requirePermission="false" type="Elmah.ErrorFilterSectionHandler, Elmah" />
</sectionGroup>
….
<appSettings>
<add key="elmah.mvc.disableHandler" value="false" />
<add key="elmah.mvc.disableHandleErrorFilter" value="false" />
<add key="elmah.mvc.requiresAuthentication" value="false" />
<add key="elmah.mvc.allowedRoles" value="*" />
<add key="elmah.mvc.route" value="elmah" />
</appSettings>
…..
<httpModules>
<add name="ErrorLog" type="Elmah.ErrorLogModule, Elmah" />
<add name="ErrorMail" type="Elmah.ErrorMailModule, Elmah" />
<add name="ErrorFilter" type="Elmah.ErrorFilterModule, Elmah" />
</httpModules>

<elmah></elmah>

2.Configuration

Elmah的配置主要包括日志的存储方式,安全方面,和ErrorLog的Filter。

1) Storage

可配置基于Xml/SqlServer等的存储,只能定义一种,也就是errorLog节点只能出现一次。

web.config
1
2
3
4
5
6
7
8

<elmah>
<!-- save to xml file -->
<errorLog type="Elmah.XmlFileErrorLog, Elmah" logPath="~/Logs" />
<!-- save to database -->
<errorLog type="Elmah.SqlErrorLog, Elmah" connectionStringName="YourConnectionStringName" applicationName="YourWebsiteName" />
….
</elmah>

如果我们选用Xml文件存储,配置完后错误日志就会以Xml的形式存在于上述config定义的路径下,每一个异常对应一个XML存在。

image

2) Remote access for web view page

远程访问一旦打开就要同时配置访问的安全问题,具体可能根据项目的不同而不同。在我们的项目因为没有打开远程访问,所以允许所有用户可以查看日志。

web.config
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15

<system.web>

<location path="elmah">
<system.web>
<autorization>
<allow users= "*"/>
</authorization>
</system.web>
</location>
</system.web>
<elmah>
….
<security allowRemoteAccess="false" />
</elmah>

3.Filter

Elmah Filter主要用来过滤那些不需要关注的错误异常,主要基于ErrorLogFilterModule,可通过编程也可配置。

ErrorFilterModule takes care of subscribing to the Filtering event of the modules that precede it. When the logging and mailing modules fire their Filtering event, ErrorFilterModule runs through one or more assertions to decide whether to dismiss the exception or not. If the assertions test true, the exception is dismissed.

Dismissing an exception does not clear the error so it still continues to surface as an unhandled exception. Dismissing here means that the module will not log it.

下面给的例子在Web.config中进行配置,如果test的表达式满足,那么相关的Exception就不会被记录。

web.config
1
2
3
4
5
6
7
8
9
<elmah>
...
<errorFilter>
<test>
<equal binding="HttpStatusCode" value="404" type="Int32" />
</test>
</errorFilter>
</elmah>

4.Customized Error Log Message

Elmah根据系统抛出的异常以及当前Contxt记录日志,有时候缺省的call-stack并不能给我们带来足够的信息,我们可以通过override customizedException.ToString()方法从而可以记录更多的信息,以方便调试。

customzied exception#
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
public class MyException : Exception{
public MyException(MyModule module, Response response){
this.myModule = module;
this.response = response;
}

public oerride string ToString(){
return string.format("{0}{1}{2}", JSonConvert.SerializeObject(new {
name = myModule.Name,
info = myModule.Info,
statusCode = response.Statuscode,
…..
}),
Environment.NewLine,
base.ToString());
}
}

image

5.API to log with Custom Errors

Elmah除了能够自动捕获系统中未处理的异常,同时也提供ErrorLog和ErrorSignal API允许开发人员为系统中捕获的异常记录日志,比如对于一些系统已知的异常通常捕获并转向对用户友好的错误页面。Elmah的API可以让开发人员在处理异常的同时将其记录。

customzied exception#
1
2
3
Elmah.ErrorSignal.FromCurrentContext().Raise(exception);
Elmah.ErrorLog.GetDefault(HttpContext).Log(new Error(exception, httpContext));

Summary

Elmah的亮点在于集成简单和查询日志的Web服务,但是它有一个问题就是只能记录异常。如果要想追踪系统运行的流程,记录一些文本信息,可以通过其他方式进行。我自己的经验是在很长的系统维护周期中,异常以及其上下文是最能帮助我们发现和诊断问题。而其他的例如Audit之类的日志功能,我自己理解不属于Elmah解决问题的范畴,可以通过其他工具诸如Nlog,Log4j等方式。

参考
  1. https://code.google.com/p/elmah/
  2. http://www.codeproject.com/Articles/516626/Elmah
  3. http://msdn.microsoft.com/en-us/library/aa479332.aspx
Share Comments