使用处理异常的过滤器 HandleErrorAttribute
1.新建一个类继承自 HandleErrorAttribute,然后重写OnException这个方法
将错误信息写入队列中
public class MyExceptionAttribute : HandleErrorAttribute { public static Queue<Exception> ExecptionQueue = new Queue<Exception>(); /// <summary> /// 可以捕获异常数据 /// </summary> /// <param name="filterContext"></param> public override void OnException(ExceptionContext filterContext) { base.OnException(filterContext); Exception ex = filterContext.Exception; //写到队列 ExecptionQueue.Enqueue(ex); //跳转到错误页面. filterContext.HttpContext.Response.Redirect("/Error.html"); } }
只要程序出错就会执行这个方法。
2.注册定义好的异常过虑器
打开App_Start文件夹中FilterConfig.cs修改
public class FilterConfig { public static void RegisterGlobalFilters(GlobalFilterCollection filters) { // filters.Add(new HandleErrorAttribute()); filters.Add(new MyExceptionAttribute()); } }
验证一下:在1中定义的过虑器的ex行打一个断点,然后在控制器的action中增加一段出错的代码
public ActionResult Index() { int a = Convert.ToInt16("aaa"); return Content(a.ToString()); // return View(); }
运行可以看到效果:
3.开启一个新的线程不断的读取队列,通过Log4把消息写入日志文件
读取消息应该在程序开始的时候就开始执行,在Global.asax.cs中添加代码
protected void Application_Start() { log4net.Config.XmlConfigurator.Configure();//读取了配置文件中关于Log4Net配置信息. AreaRegistration.RegisterAllAreas(); WebApiConfig.Register(GlobalConfiguration.Configuration); FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters); RouteConfig.RegisterRoutes(RouteTable.Routes); BundleConfig.RegisterBundles(BundleTable.Bundles); //开启一个线程,扫描异常信息队列。 string filePath = Server.MapPath("/Log/"); ThreadPool.QueueUserWorkItem((a) => { while (true) { //判断一下队列中是否有数据 if (MyExceptionAttribute.ExecptionQueue.Count() > 0) { Exception ex=MyExceptionAttribute.ExecptionQueue.Dequeue(); if (ex != null) { //将异常信息写到日志文件中。 //string fileName = DateTime.Now.ToString("yyyy-MM-dd"); //File.AppendAllText(filePath+fileName+".txt",ex.ToString(),System.Text.Encoding.UTF8); ILog logger = LogManager.GetLogger("errorMsg"); logger.Error(ex.ToString()); } else { //如果队列中没有数据,休息 Thread.Sleep(3000); } } else { //如果队列中没有数据,休息 Thread.Sleep(3000); } } },filePath); }
4.配置Log4
1 <configuration> 2 <configSections> 3 <!--Log4Net配置--> 4 <section name="log4net" type="log4net.Config.Log4NetConfigurationSectionHandler, log4net" /> 5 </configSections> 6 <log4net> 7 <!-- OFF, FATAL, ERROR, WARN, INFO, DEBUG, ALL --> 8 <!-- Set root logger level to ERROR and its appenders --> 9 <root> 10 <level value="ALL" /> 11 <appender-ref ref="SysAppender" /> 12 </root> 13 <!-- Print only messages of level DEBUG or above in the packages --> 14 <logger name="WebLogger"> 15 <level value="DEBUG" /> 16 </logger> 17 <appender name="SysAppender" type="log4net.Appender.RollingFileAppender,log4net"> 18 <!--文件路径--> 19 <param name="File" value="App_Data/" /> 20 <!--文件追加--> 21 <param name="AppendToFile" value="true" /> 22 <!--备份类型--> 23 <param name="RollingStyle" value="Date" /> 24 <!--文件名称--> 25 <param name="DatePattern" value=""Logs_"yyyyMMdd".txt"" /> 26 <!--是否固定名称--> 27 <param name="StaticLogFileName" value="false" /> 28 <layout type="log4net.Layout.PatternLayout,log4net"> 29 <param name="ConversionPattern" value="%d [%t] %-5p %c - %m%n" /> 30 <param name="Header" value=" ----------------------header-------------------------- " /> 31 <param name="Footer" value=" ----------------------footer-------------------------- " /> 32 </layout> 33 </appender> 34 <appender name="consoleApp" type="log4net.Appender.ConsoleAppender,log4net"> 35 <layout type="log4net.Layout.PatternLayout,log4net"> 36 <param name="ConversionPattern" value="%d [%t] %-5p %c - %m%n" /> 37 </layout> 38 </appender> 39 </log4net> 40 <!--Log4Net配置结束--> 41 </configuration>