结合log4net,实现全局异常捕获.
今天给大家分享的是:
1.项目集成log4net。
2.结合log4net实现全局异常捕获。
当然,第一步肯定是集成log4net了。
Nuget将log4net引用进来,如图:
然后,在Global文件中的Application_Start进行初始化配置
只有一句代码,重点是Log4net.config.具体配置在它里面。这个可以到官网去下载一份,然后根据自己具体需求稍微改动下就OK。下面是我的配置文件:
<?xml version="1.0" encoding="utf-8"?> <configuration> <configSections> <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net"/> </configSections> <system.web> <compilation debug="true" targetFramework="4.5.2" /> <httpRuntime targetFramework="4.5.2" /> </system.web> <log4net> <!-- 将日志利用ADO.NET记录到数据库中 --> <appender name="AdoNetAppender_SQLServer" type="log4net.Appender.AdoNetAppender"> <!-- 缓冲区大小 --> <bufferSize value="1" /> <!-- 引用信息 --> <connectionType value="System.Data.SqlClient.SqlConnection, System.Data, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"/> <!-- 连接到SQL Server的数据库连接字符串 --> <connectionString value="Data Source=.; Initial Catalog=hl_db; User ID=sa; Password=9o0p-[=];" /> <!-- 插入Log表的SQL语句 --> <commandText value="INSERT INTO dbo.Log ([Date],[Thread],[Level],[Logger],[Message],[Exception]) VALUES (@log_date, @thread, @log_level, @logger, @message, @exception)" /> <parameter> <parameterName value="@log_date" /> <dbType value="DateTime" /> <layout type="log4net.Layout.RawTimeStampLayout" /> </parameter> <parameter> <parameterName value="@thread" /> <dbType value="String" /> <size value="255" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%thread" /> </layout> </parameter> <parameter> <parameterName value="@log_level" /> <dbType value="String" /> <size value="50" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%level" /> </layout> </parameter> <parameter> <parameterName value="@logger" /> <dbType value="String" /> <size value="255" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%logger" /> </layout> </parameter> <parameter> <parameterName value="@message" /> <dbType value="String" /> <size value="4000" /> <layout type="log4net.Layout.PatternLayout"> <conversionPattern value="%message" /> </layout> </parameter> <parameter> <parameterName value="@exception" /> <dbType value="String" /> <size value="2000" /> <layout type="log4net.Layout.ExceptionLayout" /> </parameter> </appender> <root> <!-- 控制级别,由低到高:ALL|DEBUG|INFO|WARN|ERROR|FATAL|OFF --> <!-- 比如定义级别为INFO,则INFO级别向下的级别,比如DEBUG日志将不会被记录 --> <!-- 如果没有定义LEVEL的值,则缺省为DEBUG --> <level value="ALL" /> <!-- 将日志利用ADO.NET记录到数据库中 --> <appender-ref ref="AdoNetAppender_SQLServer" /> </root> </log4net> </configuration>
注意到里面的插入SQL语句吗?
当写日志的时候就是调用的这个模板,所以你得先去数据库建好对应的表。
建表sql拿去:
CREATE TABLE [dbo].[Log]( [Id] [INT] IDENTITY(1,1) NOT NULL, [Date] [DATETIME] NOT NULL, [Thread] [VARCHAR](255) NOT NULL, [Level] [VARCHAR](50) NOT NULL, [Logger] [VARCHAR](255) NOT NULL, [Message] [VARCHAR](MAX) NOT NULL, [Exception] [VARCHAR](MAX) NULL ) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
接下来项目属性文件中还要配置这句话,才行喔!
到此,log4net已经配置好了。接下来就是利用它去写日志了,下面是我捕获全局异常,然后用log4net记录日志的例子:
还是回到Global文件中,写一个捕获异常的方法:
#region 全局捕获错误信息,并记录到日志 public void CatchError() { Exception ex = Server.GetLastError(); HttpException httpex = ex as HttpException; if (httpex != null && httpex.ErrorCode == 404) { return; } DbEntityValidationException vaildex = ex as DbEntityValidationException; StringBuilder sb = new StringBuilder(); if (vaildex != null) { vaildex.EntityValidationErrors.ToList().ForEach(error => { error.ValidationErrors.ToList().ForEach(err => { sb.AppendLine(error.Entry.Entity.ToString() + ":" + err.ErrorMessage); }); }); // 记录日志 NGTEST.Frameworks.Log4Context.InStance.Error(sb.ToString()); } else { // 记录日志 NGTEST.Frameworks.Log4Context.InStance.Error(ex.Message,ex); } } #endregion
当前,这里的Log4Context是我为了使用方便,自己封装了一下,代码如下:
using System; using System.Collections.Generic; using System.Linq; using System.Web; namespace NGTEST.Frameworks { /// <summary> /// 日志上下文 /// </summary> public class Log4Context { private static log4net.ILog _log; public static log4net.ILog InStance { get { if (_log == null) _log =log4net.LogManager.GetLogger(System.Reflection.MethodBase.GetCurrentMethod().DeclaringType); return _log; } } } }
然后在Application_Error中调用刚刚写得方法。当程序有异常错误的时候,会进入执行该方法。
然后,随便制造点异常错误,看看效果。
已经记录到日志了,而且十分详细的记录了,哪个模型,哪个属性异常了。这对我们平时开发的时候,可以直接看日志,就能知道哪个模型异常,不用断点调试。是不是很方便好用啊!