http://www.cnblogs.com/jys509/p/4571298.html

简介

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

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

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

使用方法

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

第一步:安装布署

首先Build 空的Asp.net MVC 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=111111@a" 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
GO
SET ANSI_NULLS ON
GOCREATE PROCEDURE dbo.ELMAH_GetErrorXml
(@Application NVARCHAR(60),@ErrorId UNIQUEIDENTIFIER
)
ASSET NOCOUNT ONSELECT AllXml
FROM ELMAH_Error
WHEREErrorId = @ErrorId
ANDApplication = @ApplicationGO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GOSET QUOTED_IDENTIFIER ON
GO
SET ANSI_NULLS ON
GOCREATE PROCEDURE dbo.ELMAH_GetErrorsXml
(@Application NVARCHAR(60),@PageIndex INT = 0,@PageSize INT = 15,@TotalCount INT OUTPUT
)
AS SET NOCOUNT ONDECLARE @FirstTimeUTC DateTime
DECLARE @FirstSequence int
DECLARE @StartRow int
DECLARE @StartRowIndex int-- Get the ID of the first error for the requested pageSET @StartRowIndex = @PageIndex * @PageSize + 1
SET ROWCOUNT @StartRowIndexSELECT  @FirstTimeUTC = TimeUTC,@FirstSequence = Sequence
FROM ELMAH_Error
WHERE   Application = @Application
ORDER BY TimeUTC DESC, Sequence DESC-- Now set the row count to the requested page size and get
-- all records below it for the pertaining application.SET ROWCOUNT @PageSizeSELECT @TotalCount = COUNT(1)
FROM ELMAH_Error
WHERE Application = @ApplicationSELECT errorId, application,host, type,source,message,[user],statusCode, CONVERT(VARCHAR(50), TimeUtc, 126) + 'Z' time
FROM ELMAH_Error error
WHEREApplication = @Application
AND TimeUTC <= @FirstTimeUTC
AND Sequence <= @FirstSequence
ORDER BYTimeUTC DESC, Sequence DESC
FORXML AUTOGO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GOSET QUOTED_IDENTIFIER ON
GO
SET ANSI_NULLS ON
GOCREATE PROCEDURE dbo.ELMAH_LogError
(@ErrorId UNIQUEIDENTIFIER,@Application NVARCHAR(60),@Host NVARCHAR(30),@Type NVARCHAR(100),@Source NVARCHAR(60),@Message NVARCHAR(500),@User NVARCHAR(50),@AllXml NTEXT,@StatusCode INT,@TimeUtc DATETIME
)
ASSET NOCOUNT ONINSERT
INTOELMAH_Error(ErrorId,Application,Host,Type,Source,Message,[User],AllXml,StatusCode,TimeUtc)
VALUES(@ErrorId,@Application,@Host,@Type,@Source,@Message,@User,@AllXml,@StatusCode,@TimeUtc)GO
SET QUOTED_IDENTIFIER OFF
GO
SET ANSI_NULLS ON
GO

执行sQL语句完成后会在当前数据库看到表:

当再次运行应用程序.在Throw ArgumentNullException时查询数据库:

简单总结一下各种方式:

  • 数据库存储方式,配置相对麻烦,但对于大规模日志的记录,效率最好;
  • 文件存储方式,配置相对简单,每日志一个文件,当数据量很大后,可能会导致巨量文件带来的效率问题;
  • 内存存储,配置最简单,但是鉴于以上原因,不应使用于生产环境。

补充

在使用Elmah过程发一下一些特点.这里需要说明一下.

Elmah是通过Http Modules 和Http Handler来记录和展示程序捕获的异常. 但是如果你在应用程序中添加异常处理模块.Try-Catch Elmah是无法记录到的.或是在Catch后在Throw出来. 在整个应用程序异常链上. 只有最终的异常抛给了Asp.net运行时Elmah组件才能捕获到并记录.

有很多人认为加入Elmah组件后能够处理应用异常.其实本质上Elmah本质上是一个日志记录工具.并没有处理异常的能力.所以如果异常发生.不会改变原来应用程序给用户体验.依然还会出现黄色页面.

在官方Note明确提到一个例外:

ELMAH捕获异常是基于HttpApplication对象的Error事件。

如果软件项目中的一些处理导致了HttpApplication事件无法被触发(比如在发生异常后,还没来得及执行Application_Error,就执行了Server.ClearError()方法,

会阻止Error事件的触发,再比如,如果一个异常被try-catch捕获到,并且没有再次throw,那么异常也是不会最终触发Error事件)

日志记录工具还是不少的,比如著名的Log4net。Log4Net包含了主要有四种重要的组件,分别是Logge, Repository, Appender以及 Layout.功能强大.可以自定义日志输出级别.具体操作可以参考我的另一遍文章:

Log4net配置与使用

提供源码,源码默认是内存存储方式,需要改为文件或者数据库,请更改<elmah> 节点下已经注释掉的相应配置即可。点击去下载

Elmah 日志记录组件相关推荐

  1. MVC使用 Elmah 日志记录组件

    简介 ELMAH(Error Logging Modules and Handlers)错误日志记录模块和处理程序,是一种应用广泛的错误日志工具是完全可插拔.它可以动态添加到一个正在运行的ASP.NE ...

  2. 小巧的日志记录组件 - 开源研究系列文章

    今天给大家带来一个小巧的日志记录组件LogHelper.这个组件是由Log4Net这个组件的由来而来的,不过只是写入.txt文本文件而已.如果能够对大家的项目有帮助那就更好了. 首先,打开.SLN解决 ...

  3. 日志记录组件[Log4net]详细介绍(转)

    一 Log4net简介 Log4net是基于.net开发的一款非常著名的记录日志开源组件.他最早是2001年7月由NeoWorks Limited启动的项目,基本的框架源于另外的一个非常著名的姐妹组件 ...

  4. Apache日志记录组件Log4j出现反序列化漏洞 黑客可以执行任意代码 所有2.x版本均受影响...

    开源的东西用的人多了,自然漏洞就多.Apache用于日志记录的组件Log4j使用非常灵活,在相当多的开源项目中都有使用,此次漏洞影响所有Apache Log4j 2.*系列版本: Apache Log ...

  5. html 日志记录组件,使用HTML自定义格式的Log4j.properties进行日志记录

    我需要帮助编辑Apache Log4j文件的输出. 我正在使用html布局来保存创建的日志.这里是我的log4j.properties代码:使用HTML自定义格式的Log4j.properties进行 ...

  6. Nlog日志记录组件使用

    前面做的项目都是用的log4或者用个文件类写入文件中记录日志,这个nlog用着很方便,同时也有net core的版本,一步一步操作吧 1,nuget 中找到nlog并下载安装,注意框架版本,也可以去官 ...

  7. Log4Net异常日志记录在asp.net mvc3.0的应用

    前言 log4net是.Net下一个非常优秀的开源日志记录组件.log4net记录日志的功能非常强大.它可以将日志分不同的等级,以不同的格式,输出到不同的媒介.本文主要是简单的介绍如何在Visual ...

  8. 考虑题4所示的日志记录_基于Log4Net实现日志信息双向存储

    1.引言 在上位机开发中,日志记录是必不可少的,我们可以通过日志记录做日志分析及错误追踪.初学者会采用txt文本写入来实现日志保存,但是文本写入不是线程安全,当存在多个线程同时写入日志时,就会出现一些 ...

  9. com+组件日志记录(log4net)

    网上找了一个操作powershell的com+组件源码,配置好后,发现启用邮箱不稳定.因此在代码中用log4net加入异常日志记录.如下: private static readonly ILog l ...

最新文章

  1. Oracle 用户表空间的创建和授权
  2. python中isinstance(3、object)_Python中为什么推荐使用isinstance来进行类型判断?而不是type...
  3. 简述mysql的概念及作用_数据库 简答题
  4. centos7 卸载Qt5
  5. 10个程序员才懂的灯谜,你能猜对几个?
  6. 布局中常见的居中问题
  7. oracle rac实例切换,RAC+单实例DG的切换
  8. axure画扇形_axure实现粗略饼状图
  9. 涉及到各种场景-英语小记-最爱的一篇
  10. wifi(华硕天选2)找不到怎么办
  11. CPU卡PSAM卡 响应指令错误码
  12. html如何实现左右布局,前端中的左右布局实现
  13. STM32C8T6 流水灯的实现(库函数版)
  14. GIS技术在林业管理应用中有哪些功能?
  15. loaded the “XXXView“ nib but the view outlet was not set 解决方案
  16. HyperLedger超级账本智能合约部署问题
  17. QNAP 威联通磁盘分区探索与数据导出
  18. 工坊实验室 | CALCULATE 的嵌套使用
  19. 如果数据有质量,地球将成黑洞?
  20. RNDIS设备开发手记

热门文章

  1. Kubernetes Ingress 日志分析与监控的最佳实践
  2. mysql5.6更改datadir数据存储目录
  3. 微软发布屏蔽Win10升级的官方办法
  4. ButterKnife基本使用
  5. 利用html5标签audio在不同客户端下适配播放音频
  6. KubeEdge向左,K3S向右
  7. React学习手记5-细说组件state
  8. shllter自动和手动实例
  9. java基础-java反射机制
  10. Absolute Uninstaller是类似于标准的Windows添加/删除卸载工具