MVC使用 Elmah 日志记录组件

8/10/2015来源:ASP.NET技巧人气:3224

MVC使用 Elmah 日志记录组件

2015-06-12 16:10 by jiangys, ... 阅读, ... 评论, 收藏, 编辑

简介

ELMAH(ErrorLoggingModulesandHandlers)错误日志记录模块和处理程序,是一种应用广泛的错误日志工具是完全可插拔。它可以动态添加到一个正在运行的asp.netWeb应用程序,甚至是一台机器上的所有ASP.NETWeb应用程序,而无需重新编译或重新部署。

ELMAH既支持ASP.NETWebForms又支持ASP.NETMVC。你可以对ELMAH进行配置来存储各种不同的错误(xml文件,事件日志,access数据库,SQL数据库,Oracle数据库,或者计算机RAM。)你还可以让ELMAH在错误发生的时候,把错误信息email给你。

在默认情况下,在一个已经安装ELMAH的网站中,你可以通过请求的elmah.axd页面的方式来访问ELMAH。

使用方法

本篇来尝试Elmah在Asp.netMVC 5使用.

第一步:安装布署

首先Build空的Asp.netMVC 5 PRoject:

添加Elmah引用:

Elmah组建已经配置成功.其实这个过程做了两件事:

  • A:将Elmah.dll复制到程序的根目录的Bin文件夹下.并当前项目的引用.
  • B:向项目根目录下Web.Config文件添加如下内容

在webConfig文件中添加如下内容:

  <configSections>    <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>  </configSections><elmah>    <!--        See http://code.google.com/p/elmah/wiki/SecuringErrorLogPages for         more information on remote access and securing ELMAH.    -->    <security allowRemoteAccess="false" />  </elmah>  <location path="elmah.axd" inheritInChildapplications="false">    <system.web>      <httpHandlers>        <add verb="POST,GET,HEAD" path="elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" />      </httpHandlers>      <!--         See http://code.google.com/p/elmah/wiki/SecuringErrorLogPages for         more information on using ASP.NET authorization securing ELMAH.      <authorization>        <allow roles="admin" />        <deny users="*" />        </authorization>      -->    </system.web>    <system.webServer>      <handlers>        <add name="ELMAH" verb="POST,GET,HEAD" path="elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" preCondition="integratedMode" />      </handlers>    </system.webServer>  </location>

第二步:测试使用

HomeController.cs

using System;using System.Collections.Generic;using System.Linq;using System.Web;using System.Web.Mvc;namespace Elmah.Demo.Controllers{    public class HomeController : Controller    {        //        // GET: /Home/        public ActionResult Index()        {            return View();        }        [HttpPost]        public ActionResult GenerateError(string error)        {            throw new ApplicationException(error);        }    }}

index.cshtml

@{    Layout = null;    ViewBag.Title = "Index";}<div>    <input type="text" id="ErrorMsg" />    <button id="GenerateError">生成错误日志</button>    <a href="/elmah.axd" target="_blank">在elmah中查看错误日志</a></div><script src="~/Scripts/jquery-1.10.2.js"></script><script type="text/javascript">    $("#GenerateError").click(function () {        $.post("/Home/GenerateError?error=" + $("#ErrorMsg").val());    });</script>

运行效果如下:

如果不是Post方式,会报黄页,如:

来看看Elmah是否记录本次执行过程中出现的异常:

可以看到Elmah已经如期的扑捉到当前应用程序的异常.ELMAH在后台记录了错误信息,并为我们提供了查询错误日志信息的界面,只需要简单的操作,就完成了基本的需求.

存储方式

有人可能会问,上面的自动配置中,并没有指定存储日志的方式啊(当然这里还没介绍如何配置,但是从上面配置中,似乎也看不到有哪里指定了存储方 式),那这些数据存储在哪里了呢?答案是,NuGet安装ELMAH后,它是没有指定任何存储方式。而ELMAH认为,如果没有指定存储方式,那么就采用 默认的内存存储方式(也可以显式的指定)。但是这种存储方式只能作为调试阶段使用,生产环境下不应使用此方式,具体的缺点请看下面对内存存储方式的介绍。

接下来就具体介绍各种存储方式,分别以数据库存储、文件存储和内存存储为例,需要强调一点,ELMAH目前只支持一下三种方式中的任意一种,不支持同时采用多种记录方式。(想必也没这个必要)

1.内存存储方式

内存存储,顾名思义,将日志记录于操作系统分配给应用程序的内存中。应用程序的内存是与应用程序域相关的,这可以保证每个应用程序只能获取和记录属于自己 的日志信息。但是,一旦应用程序重启,之前记录的信息将会消失。最简单的例子,如果你用这种方式调试呢,默认是用ASP.NET Development Server作为web服务器,如果这时停止此服务器,则就满足上述条件了(如下图)。另外,断电,发布后IIS的重启等问题,都会导致记录的信息丢失。 因此,这种方式只能用于测试用。

其实Elmah处理原理.当我们请求页面报错时.在返回黄页错误时首先被 httpModules中名为ErrorLog模块进行拦截. 该模块将本次请求出错的信息保存起来.-默认是放置在内存中.便于即时调试.但用户输入elmah.axd要查看日志信息时. 首先httpHandlers捕获到该请求.并交给专门处理elmah.axd的处理程序.该模块把错误日志View返回给用户.可见Elmah核心技术 还是基于HttpModules和HttpHandlers来实现的.

2.文件存储方式

文件存储实际上ELMAH提供了xml文件的存储方式,每一个报错日志信息生成一个xml文件。配置相当简单:

  <elmah>    <!--        See http://code.google.com/p/elmah/wiki/SecuringErrorLogPages for         more information on remote access and securing ELMAH.    -->    <security allowRemoteAccess="false" />    <!--只有这一句就行了,其中logPath用于指定记录日志的文件夹位置-->    <errorLog type="Elmah.XmlFileErrorLog, Elmah" logPath="~/Static/Log/" />  </elmah>

该配置必需确认LogPath路径目录是完整存在的.测试会发现在本地文件中(\Elmah.Demo\Static\Log)会出现一个XML文件:

3. 数据库存储方式

在数据可视化和管理上数据库依然是最理想的选择.这里采用SQlServer2008 版本测试.在构建Elmah支持SQLServer数据支持需要如下三个操作:

  • a)告诉ELMAH使用哪种数据库作为存储数据库;
  • b)告诉ELMAH如何连接到数据库;
  • c)指定的数据库里,要包含ELMAH需要的表、视图和存储过程等(嵌入式数据库不需要此过程)。

其中a和b步骤需要在web.config中指定,c则需要在数据库中添加相关对象。

web.config配置如下(httpModules以及httpHandlers就不贴了,这里只给出ELMAH记录日志于sqlserver数据库的配置):

  <connectionStrings>    <add name="elmah-sqlserver" connectionString="server=.;database=MvcTest;user id=sa;passWord[email protected]" providerName="System.Data.SqlClient" />  </connectionStrings>  <elmah>    <!--        See http://code.google.com/p/elmah/wiki/SecuringErrorLogPages for         more information on remote access and securing ELMAH.    -->    <security allowRemoteAccess="false" />    <!--只有这一句就行了,其中logPath用于指定记录日志的文件夹位置-->    <!--<errorLog type="Elmah.XmlFileErrorLog, Elmah" logPath="~/Static/Log/" />-->    <!-- 告诉elmah,我要采用sqlserver来记录我的日志,连接那个数据库的字符串名为myconnectionString。-->    <errorLog type="Elmah.SqlErrorLog, Elmah" connectionStringName="elmah-sqlserver" />  </elmah>

创建数据库,在该数据执行如下SQL语句.请参考官方的连接.

Elmah SQL Server Script File:http://code.google.com/p/elmah/source/browse/src/Elmah/SQLServer.sql

脚本:

CREATE TABLE dbo.ELMAH_Error(    ErrorId     UNIQUEIDENTIFIER NOT NULL,    Application NVARCHAR(60) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,    Host        NVARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,    Type        NVARCHAR(100) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,    Source      NVARCHAR(60) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,    Message     NVARCHAR(500) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,    [User]      NVARCHAR(50) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL,    StatusCode  INT NOT NULL,    TimeUtc     DATETIME NOT NULL,    Sequence    INT IDENTITY (1, 1) NOT NULL,    AllXml      NTEXT COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]GOALTER TABLE dbo.ELMAH_Error WITH NOCHECK ADD     CONSTRAINT PK_ELMAH_Error PRIMARY KEY NONCLUSTERED    (        ErrorId    )  ON [PRIMARY] GOALTER TABLE dbo.ELMAH_Error ADD     CONSTRAINT DF_ELMAH_Error_ErrorId DEFAULT (newid()) FOR [ErrorId]GOCREATE NONCLUSTERED INDEX IX_ELMAH_Error_App_Time_Seq ON dbo.ELMAH_Error(    [Application] ASC,    [TimeUtc] DESC,    [Sequence] DESC) ON [PRIMARY]GOSET QUOTED_IDENTIFIER ON GOSET ANSI_NULLS ON GOCREATE PROCEDURE dbo.ELMAH_GetErrorXml(    @Application NVARCHAR(60),    @ErrorId UNIQUEIDENTIFIER)ASSET NOCOUNT ONSELECT     AllXmlFROM     ELMA