结合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中调用刚刚写得方法。当程序有异常错误的时候,会进入执行该方法。

然后,随便制造点异常错误,看看效果。

已经记录到日志了,而且十分详细的记录了,哪个模型,哪个属性异常了。这对我们平时开发的时候,可以直接看日志,就能知道哪个模型异常,不用断点调试。是不是很方便好用啊!

 

posted on 2018-03-08 15:28  潇潇@暮雨  阅读(464)  评论(0编辑  收藏  举报

导航