Google:http://code.google.com/p/elmah/
Demo:http://code.google.com/p/elmah/wiki/DotNetSlackersArticle
Elman:http://nuget.org/packages/elmah(Install-Package elmah)
Compact:http://nuget.org/packages/elmah.sqlservercompact(Install-Package elmah.sqlservercompact)
安装
最简单的方式通过Nuget获得
我的环境是MVC4所以安装Elamh.MVC,因为这样会为我们默认配置好大部分的配置,当然也可以安装Elamh(如配置 Adding ELMAH to your ASP.NET Web Site),也可以安装XML,MongDB,MSSQL,MYSQL,Fiter等配置
Elmah.MVC 依赖与Elmah.corelibrary
"Could not load type 'Elmah.ErrorLogModule' from assembly 'Elmah'." 这个错误花了好长时间,开始我以为是IIS6与IIS7配置问题,最后发现是项目名与Elmah重复了
http://stackoverflow.com/questions/8409581/could-not-load-type-elmah-errorlogmodule-from-assembly-elmah
这里我故意写了句代码
public ActionResult Index() { ViewBag.Message = "修改此模板以快速启动你的 ASP.NET MVC 应用程序。"; int num = Convert.ToInt32("Irving"); return View(); });
访问:http://localhost:16899/ 显示错误
当然可以配置不显示错误
<customErrors defaultRedirect="/Error" mode="RemoteOnly"> <error redirect="/Error/NotFound" statusCode="404" /> <error redirect="/Error/Error" statusCode="500" /> <customErrors/>
或者将异常抛出去
public ActionResult Index() { ViewBag.Message = "修改此模板以快速启动你的 ASP.NET MVC 应用程序。"; try { int num = Convert.ToInt32("Irving"); } catch (Exception e) { ErrorSignal.FromCurrentContext().Raise(e); } return View(); }
访问:http://localhost:16899/elmah
可以查看详情,以XML 或者JSON方式显示
储存方式
Memory
<elmah> <errorLog type="Elmah.MemoryErrorLog, Elmah" size="100" /> </elmah>
这个没有什么好说的,正式环境不推荐使用
XML
<elmah> <errorLog type="Elmah.XmlFileErrorLog, Elmah" logPath="~/App_Data/ElmahXML_Logs" /> </elmah>
<errorMail from="sender@domain.com" to="receiver@domain.com" cc="copy@domain.com" subject="Your Subject" async="true or false" smtpPort="25" smtpServer="smtp.domain.com" userName="username" password="password" /> </elmah>
有关stmp协议看这里 http://help.163.com/09/1223/14/5R7P6CJ600753VB8.html?b08ene1
SQLite
<connectionStrings> <add name="ElmahDB" connectionString="data source=~/App_Data/Elmah.db" /> </connectionStrings> <elmah> <errorLog type="Elmah.SQLiteErrorLog, Elmah" connectionStringName="ElmahDB" /> </elmah>
没有测试
MSSQL
<elmah> <errorLog type="Elmah.SqlErrorLog, Elmah" connectionStringName="ElmahConnText" /> </elmah> <connectionStrings> <add name="ElmahConnText" connectionString="Data Source=.;Initial Catalog=ElmahDB;User ID=sa;Password=123"/> </connectionStrings>
这里需要手动插件表,脚本如下 或者 Install-Package elmah.sqlservercompact
/* ELMAH - Error Logging Modules and Handlers for ASP.NET Copyright (c) 2004-9 Atif Aziz. All rights reserved. Author(s): Atif Aziz, http://www.raboof.com Phil Haacked, http://haacked.com Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except in compliance with the License. You may obtain a copy of the License at http://www.apache.org/licenses/LICENSE-2.0 Unless required by applicable law or agreed to in writing, software distributed under the License is distributed on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License for the specific language governing permissions and limitations under the License. */ -- ELMAH DDL script for Microsoft SQL Server 2000 or later. -- $Id: SQLServer.sql 677 2009-09-29 18:02:39Z azizatif $ DECLARE @DBCompatibilityLevel INT DECLARE @DBCompatibilityLevelMajor INT DECLARE @DBCompatibilityLevelMinor INT SELECT @DBCompatibilityLevel = cmptlevel FROM master.dbo.sysdatabases WHERE name = DB_NAME() IF @DBCompatibilityLevel <> 80 BEGIN SELECT @DBCompatibilityLevelMajor = @DBCompatibilityLevel / 10, @DBCompatibilityLevelMinor = @DBCompatibilityLevel % 10 PRINT N' =========================================================================== WARNING! --------------------------------------------------------------------------- This script is designed for Microsoft SQL Server 2000 (8.0) but your database is set up for compatibility with version ' + CAST(@DBCompatibilityLevelMajor AS NVARCHAR(80)) + N'.' + CAST(@DBCompatibilityLevelMinor AS NVARCHAR(80)) + N'. Although the script should work with later versions of Microsoft SQL Server, you can ensure compatibility by executing the following statement: ALTER DATABASE [' + DB_NAME() + N'] SET COMPATIBILITY_LEVEL = 80 If you are hosting ELMAH in the same database as your application database and do not wish to change the compatibility option then you should create a separate database to host ELMAH where you can set the compatibility level more freely. If you continue with the current setup, please report any compatibility issues you encounter over at: http://code.google.com/p/elmah/issues/list =========================================================================== ' END GO /* ------------------------------------------------------------------------ TABLES ------------------------------------------------------------------------ */ 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] GO ALTER TABLE [dbo].[ELMAH_Error] WITH NOCHECK ADD CONSTRAINT [PK_ELMAH_Error] PRIMARY KEY NONCLUSTERED ([ErrorId]) ON [PRIMARY] GO ALTER TABLE [dbo].[ELMAH_Error] ADD CONSTRAINT [DF_ELMAH_Error_ErrorId] DEFAULT (NEWID()) FOR [ErrorId] GO CREATE NONCLUSTERED INDEX [IX_ELMAH_Error_App_Time_Seq] ON [dbo].[ELMAH_Error] ( [Application] ASC, [TimeUtc] DESC, [Sequence] DESC ) ON [PRIMARY] GO /* ------------------------------------------------------------------------ STORED PROCEDURES ------------------------------------------------------------------------ */ SET QUOTED_IDENTIFIER ON GO SET ANSI_NULLS ON GO CREATE PROCEDURE [dbo].[ELMAH_GetErrorXml] ( @Application NVARCHAR(60), @ErrorId UNIQUEIDENTIFIER ) AS SET NOCOUNT ON SELECT [AllXml] FROM [ELMAH_Error] WHERE [ErrorId] = @ErrorId AND [Application] = @Application GO SET QUOTED_IDENTIFIER OFF GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO SET ANSI_NULLS ON GO CREATE PROCEDURE [dbo].[ELMAH_GetErrorsXml] ( @Application NVARCHAR(60), @PageIndex INT = 0, @PageSize INT = 15, @TotalCount INT OUTPUT ) AS SET NOCOUNT ON DECLARE @FirstTimeUTC DATETIME DECLARE @FirstSequence INT DECLARE @StartRow INT DECLARE @StartRowIndex INT SELECT @TotalCount = COUNT(1) FROM [ELMAH_Error] WHERE [Application] = @Application -- Get the ID of the first error for the requested page SET @StartRowIndex = @PageIndex * @PageSize + 1 IF @StartRowIndex <= @TotalCount BEGIN SET ROWCOUNT @StartRowIndex SELECT @FirstTimeUTC = [TimeUtc], @FirstSequence = [Sequence] FROM [ELMAH_Error] WHERE [Application] = @Application ORDER BY [TimeUtc] DESC, [Sequence] DESC END ELSE BEGIN SET @PageSize = 0 END -- Now set the row count to the requested page size and get -- all records below it for the pertaining application. SET ROWCOUNT @PageSize SELECT errorId = [ErrorId], application = [Application], host = [Host], type = [Type], source = [Source], message = [Message], [user] = [User], statusCode = [StatusCode], time = CONVERT(VARCHAR(50), [TimeUtc], 126) + 'Z' FROM [ELMAH_Error] error WHERE [Application] = @Application AND [TimeUtc] <= @FirstTimeUTC AND [Sequence] <= @FirstSequence ORDER BY [TimeUtc] DESC, [Sequence] DESC FOR XML AUTO GO SET QUOTED_IDENTIFIER OFF GO SET ANSI_NULLS ON GO SET QUOTED_IDENTIFIER ON GO SET ANSI_NULLS ON GO CREATE 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 ) AS SET NOCOUNT ON INSERT INTO [ELMAH_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
ErrorFiltering
我们可以通过代码的方式过滤错误,如我们不想在应用程序发生404错误的时候记录日志,我们只需要在Global.asax文件中自定义
这里我启用XML与Email两种方式
<elmah> <security allowRemoteAccess="1" /> <!--XML方式--> <errorLog type="Elmah.XmlFileErrorLog, Elmah" logPath="~/App_Data/ElmahXML_Logs"/> <!--Email方式--> <errorMail from="xxx@163.com" to="xxx@qq.com" subject="ERROR From Elmah:" async="true" smtpPort="25" smtpServer="smtp.163.com" userName="xxx.com" password="xxx> <!--内存方式--> <!--<errorLog type="Elmah.MemoryErrorLog, Elmah"/>--> <!--MSSQL方式--> <!--<errorLog type="Elmah.SqlErrorLog, Elmah" connectionStringName="ElmahConnText" />--> </elmah>
allowRemoteAccess 中0表示允许本地浏览,1表示允许本地与远程,其他方式没有试(RSS MYSQL ORACEL等)
protected void ErrorLog_Filtering(object sender, ExceptionFilterEventArgs e) { FilterError404Exception(e); FilterErrorValidationException(e); FilterErrorNotFileException(e); } protected void ErrorMail_Filtering(object sender, ExceptionFilterEventArgs e) { FilterError404Exception(e); } /// <summary> /// 处理404 /// </summary> /// <param name="e"></param> void FilterError404Exception(ExceptionFilterEventArgs e) { if (e.Exception.GetBaseException() is HttpException) { HttpException ex = (HttpException)e.Exception.GetBaseException(); if (ex.GetHttpCode() == 404) { e.Dismiss(); } } } /// <summary> /// 处理 HttpRequestValidationException /// </summary> /// <param name="args"></param> void FilterErrorValidationException(ExceptionFilterEventArgs args) { if (args.Exception.GetBaseException() is HttpRequestValidationException) { args.Dismiss(); } } void FilterErrorNotFileException(ExceptionFilterEventArgs e) { if (e.Exception.GetBaseException() is FileNotFoundException) { e.Dismiss(); } }
IIS配置
II6与IIS7+异同,这个貌似跟集成模式与经典模式有关系,MVC中如果是用Nuget安装的话,应该不用考虑这个问题,如果有问题参考下面链接
安全性
可以配置<security>节点设置allowRemoteAccess为0,这样就不能够通过远程的方式进行访问,如果想既支持远程查看日志又能够保证安全性,首先设置allowRemoteAccess为1然后需要我们对elmah.axd路径进行权限控制,可以在<loaction>节点下进行相关配置(Form验证)。
<location path="elmah.axd"> <system.web> <httpHandlers> <add verb="POST,GET,HEAD" path="elmah.axd" type="Elmah.ErrorLogPageFactory, Elmah" /> </httpHandlers> <authorization> <allow roles="Irving" /> <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>
http://www.troyhunt.com/2012/01/aspnet-session-hijacking-with-google.html
这篇文章非常好,之前有一篇文章讨论 From验证安全性 machineconfig中的key不被篡改的话,能够确保安全性,链接找不到了
ElmahR
ElmahR是一个集成了SignalR技术,可以把错误的消息推送到浏览器上,可以在这里看DEMO :http://elmahr.apphb.com/?log=1
ElmahR = ELMAH + SignalR (1.0.0 released!)
http://www.codeproject.com/Articles/377394/ElmahR-equals-ELMAH-plus-SignalR-released
Streaming logs with SignalR 2.0
http://www.codeproject.com/Articles/758633/Streaming-logs-with-SignalR
更新:新版本已支持APS.NET MVC 性能路由的调试
Refer:
ASP.NET MVC
http://www.asp.net/web-forms/tutorials/deployment/deploying-web-site-projects/logging-error-details-with-elmah-cs
http://www.codeproject.com/Articles/26468/ELMAH-Error-Loggin-Module-and-Handler-For-unhandle
http://volaresystems.com/Blog/post/2009/08/23/Handling-Exceptions-in-ASPNET-MVC.aspx
http://www.hanselman.com/blog/NuGetPackageOfTheWeek7ELMAHErrorLoggingModulesAndHandlersWithSQLServerCompact.aspx
http://www.codecapers.com/post/Error-Handling-in-MVC-with-ELMAH.aspx
http://www.cnblogs.com/lerit/archive/2011/03/29/1998396.htmlASP.NET WEBFROM
http://www.asp.net/web-forms/tutorials/deployment/deploying-web-site-projects/logging-error-details-with-asp-net-health-monitoring-cs
http://msdn.microsoft.com/en-us/library/aa479332.aspx
http://www.itscodingtime.com/itscodingtime/post/Adding-ELMAH-to-your-ASPNET-Web-Site.aspxErrorFiltering
http://code.google.com/p/elmah/wiki/ErrorFilteringSecuring
http://code.google.com/p/elmah/wiki/SecuringErrorLogPages
http://www.troyhunt.com/2012/01/aspnet-session-hijacking-with-google.html
http://www.beletsky.net/2011/03/integrating-elmah-to-aspnet-mvc-in.html
http://stackoverflow.com/questions/1245364/securing-elmah-in-asp-net-website (备注)IIS
http://www.asp.net/mvc/tutorials/older-versions/deployment/using-asp-net-mvc-with-different-versions-of-iis-cs
http://www.cnblogs.com/apsnet/archive/2012/04/28/2474730.html