ASP.NET 2.0中的健康监测系统(Health Monitoring)(2) - 通过Email发送监测信息
原文发布日期:2007.03.21
作者:
Scott Mitchell
翻译:
webabcd
介绍
ASP.NET 2.0的健康监测系统是用来监测运营环境中ASP.NET程序的运行状况的。 它的工作就是记录事件信息到指定的日志源。 .NET 2.0框架中包含有多种可以被健康监测系统使用的内置事件,这些事件可以监测到程序的开始和停止、未处理异常、验证失败的信息等等。 .NET框架中也提供了记录这些事件的方法,你可以把这些事件信息记录到Windows事件日志、微软的SQL Server数据库、
WMI、email或ASP.NET的页面跟踪系统。 在
上一篇文章中我们看到(译者注:
中文在这里),当使用即拿即用(out-of-the-box)的事件和日志源的时候,只要通过配置Web.config就可以让健康监测系统正常地工作起来,而不需要写任何代码。
本文中,我们将继续研究内嵌的事件和日志源来。 具体来说,我们将会了解如何使用WebFailureAuditEvent事件,在安全审核失败的时候就会触发这个事件。 我们也会知道如何使用
SimpleMailWebEventProvider,顾名思义,就是通过email发送事件信息。 继续往下看,你会知道得更多!
监测安全审核
上一篇文章中,我们已经讨论过,所有的健康监测系统用到的事件必须继承自
WebBaseEvent类。 在
System.Web.Management命名空间中,你会发现WebBaseEvent类有很多不同的子类,不同的子类中有不同类型的事件。 下图可以让你快速地了解各种事件的层次关系。 它显示了健康监测系统的一些(不是所有)内置事件。 其中暗绿色的是与安全审核相关的事件,我们将在本文中一起探讨这些事件。
要使健康监测系统能够记录这些事件,我们需要在Web.config里的<healthMonitoring>节点下,对<eventMappings>和<rules>做一些配置。找到<eventMappings>节点,并使其映射一个名字到指定的事件。 在上一篇文章中,我们看到了两个事件,分别是程序lifetime事件和错误事件。 所以,在<eventMappings>节点下已经有了两个<add>元素。
本文中,我们会继续捕获未处理异常,但是不再需要程序的lifetime事件了。 另外,我们需要捕获到所有验证失败的事件,所以,<eventMappings>节点将变成如下这样:
<
configuration
>
<
system
.web
>
<
healthMonitoring
enabled
="true"
>
<
eventMappings
>
<
clear
/>
<!--
记录所有错误事件
-->
<
add
name
="All Errors"
type
="System.Web.Management.WebBaseErrorEvent"
startEventCode
="0"
endEventCode
="2147483647"
/>
<!--
记录验证失败的事件
-->
<
add
name
="Auth Failure Audits"
type
="System.Web.Management.WebAuthenticationFailureAuditEvent"
startEventCode
="0"
endEventCode
="2147483647"
/>
</
eventMappings
>
</
healthMonitoring
>
</
system.web
>
</
configuration
>
与上面配置中的第2个<add>元素的名为“Auth Failure Audits”的节点相关联的是
WebAuthenticationFailureAuditEvent类。 该项设置用名为“Auth Failure Audits”的节点来关联到验证失败的事件。 如果我们想捕获所有的安全审核失败的信息,就要用
WebFailureAuditEvent来代替上面的type属性的值。 另外插一句,如果指定type为
WebAuditEvent的话,审核成功和审核失败的事件都将会被记录。
除了在<eventMappings>节点中标记一个人性化的名称到一个指定类型的事件外,我们还需要在<rules>节点中指出当相关事件发生的时候需要使用的日志源。 <rules>节点的作用是映射<eventMappings>节点中的一个事件到<providers>节点中的一个日志源。 下面的配置中,将“All Errors”和“Auth Failure Audits”都映射到了“SqlWebEventProvider”,它会记录事件到App_Data文件夹下的ASPNETDB.MDF数据库。
<
configuration
>
<
system
.web
>
<
healthMonitoring
enabled
="true"
>
<
eventMappings
>
</
eventMappings
>
<
providers
>
<
clear
/>
<
add
connectionStringName
="LocalSqlServer"
maxEventDetailsLength
="1073741823"
buffer
="false"
name
="SqlWebEventProvider"
type
="System.Web.Management.SqlWebEventProvider"
/>
</
providers
>
<
rules
>
<
clear
/>
<
add
name
="All Errors SQL"
eventName
="All Errors"
provider
="SqlWebEventProvider"
profile
="Default"
minInstances
="1"
maxLimit
="Infinite"
minInterval
="00:00:00"
/>
<
add
name
="Auth Failure Audits SQL"
eventName
="Auth Failure Audits"
provider
="SqlWebEventProvider"
profile
="Default"
minInstances
="1"
maxLimit
="Infinite"
minInterval
="00:00:00"
/>
</
rules
>
</
healthMonitoring
>
</
system.web
>
</
configuration
>
请注意<rules>节点中设置的minInterval属性。 该属性的值用于指定相同的事件在多长时间的间隔后才能被再次记录。 在上面的示例中,我把minInterval的值设置为“00:00:00”,其意味着即使发生了相同的事件也都会被记录,打个比方说,如果10秒内某一事件发生了5次,那么这5个事件都会被记录。 当然,你也可以修改这个值。 如果你把minInterval的值设为“00:00:30”,那么首次被触发的事件会被记录。 如果相同的事件在10秒后再次被触发,那么该事件是不会被记录的,因为还没有到我们设置的30秒的间隔时间。 如果要求一旦有事件发生就需要记录的话,那么就要确保minInterval的值为“00:00:00”, 否则可以给minInterval设置成一个较高的合适的值。
在本文结尾处你可以下载到一个Demo程序,它使用了ASP.NET 2.0的Membership特性和ASP.NET 2.0的与安全相关的web控件实现了用户管理的功能。 在Login.aspx页中要求用户输入用户名和密码。 如果登录失败的话,无论是因为用户名、密码不正确,还是因为用户被锁定,WebAuthenticationFailureAuditEvent事件都将会被自动地触发。 我们的程序里配置的是记录事件到SQL Server数据库,其截屏如下。(
关于Membership的更多信息请参看Examining ASP.NET 2.0's Membership, Roles, and Profile)
注意,当登录失败的时候,会记录下登录失败的用户名。
接收通过Email发送的事件通知
.NET 2.0框架中除了提供Windows事件日志和SQL Server数据库作为数日志源外,还提供了用email发送日志信息的Provider。 分别是如下两个Provider:
·
SimpleMailWebEventProvider – 发送一个包括事件信息的无格式文本邮件。 这个Provider只能非常有限地对邮件的内容做一些自定义修改。
·
TemplatedMailWebEventProvider – 调用一个ASP.NET页面来生成邮件的内容。 它允许你使用控件,并且可以格式化email内容的信息。
接下来让我们来修改一下健康监测系统的配置信息,以使验证失败的信息可以记录到数据库中,并且发送相应的email给管理员。 我们将使用SimpleMailWebEventProvider来发送email,因为它比较简单,并且不需要为email模板再另外创建一个ASP.NET页。
无论使用这二者中的哪一个Provider,我们首先都必须在Web.config文件中的<system.net>节点下设置好SMTP。 如果不做这个设置或者设置错误,那么健康监测系统就不会正常工作。 具体如何设置请参看
在ASP.NET 2.0中发送邮件(译者注:
我写的在这里)。
设置好SMTP后,在<providers>节点下添加一个Provider – SimpleMailWebEventProvider,并且在<rules>节点下关联相关的事件到这个
<
configuration
>
<
system
.web
>
<
healthMonitoring
enabled
="true"
>
<
eventMappings
>
</
eventMappings
>
<
providers
>
<
clear
/>
<
add
type
="System.Web.Management.SimpleMailWebEventProvider"
name
="EmailWebEventProvider"
from
="[email protected]"
to
="[email protected]"
bodyHeader
="!!! HEALTH MONITORING WARNING!!!"
bodyFooter
="Brought to you by Acme Warning Systems"
buffer
="false"
/>
</
providers
>
<
rules
>
<
clear
/>
<
add
name
="Auth Failure Audits Email"
eventName
="Auth Failure Audits"
provider
="EmailWebEventProvider"
profile
="Default"
minInstances
="1"
maxLimit
="Infinite"
minInterval
="00:00:00"
/>
</
rules
>
</
healthMonitoring
>
</
system.web
>
<
system
.net
>
<
mailSettings
>
<
smtp
>
<
network
host
="relayServerHostname"
port
="portNumber"
userName
="username"
password
="password"
/>
</
smtp
>
</
mailSettings
>
</
system.net
>
</
configuration
>
像上面这样配置好后,任何时候发生了验证失败的事件,其相关数据都将会记录到数据库中,并且发送邮件到“[email protected]”。
SimpleMailWebEventProvider目前的配置是,一旦发生了验证失败的事件,就马上自动地发送邮件。 其实,我们也可以做一下缓冲处理。 例如,你可以每隔一段时间处理一次缓冲的内容,也可以在缓冲的内容到一定数量的时候处理缓冲的内容。 我们将在以后的文章中研究“缓冲”这个功能。
结论
.NET 2.0框架中的健康监测系统中,不但可以监测到程序的lifetime事件和与错误相关的事件,而且还可以监测到安全审核成功或失败的事件。 本文中,我们一起探讨了WebAuthenticationFailureAuditEvent事件,在验证失败的时候就会触发它。 如果用户用无效的信息登录系统,那么实现Membership的Provider就会触发这个事件。 例如,SqlMembershipProvider的ValidateUser方法需要两个参数,分别是用户名和密码,它会根据验证的结果返回一个布尔值。 除了返回一个布尔值外,这个方法也会触发WebAuthenticationSuccessAuditEvent事件或者WebAuthenticationFailureAuditEvent事件。
我们也看到了SimpleMailWebEventProvider的用法,它会通过email发送日志。 当某一事件发生的时候(如未处理异常,验证失败等等),这个Provider就会发送邮件到指定的地址。
祝编程愉快!
===========================
可以定义自己的事件处理程序类继承于WebBaseEvent类就可以了.以下是个自己的自定义事件类
public class UserComstomEvent : System.Web.Management.WebBaseEvent
{
public UserComstomEvent(string message, object eventSource, int eventCode):base(message,eventSource,eventCode)
{
//...
}
}
void methodname()
{
try
{
//....
}
catch(Exception e)
{
if (HealthMonitoringManager.Enabled)
{
WebBaseEvent.Raise(new UserComstomEvent("My Error message", null, 5000, e));
}
}
or:
if (HealthMonitoringManager.Enabled)
{
UserComstomEvent myevent = new UserComstomEvent("My error message", null, 5000);
myevent.Raise();
}
}