关于面向切面编程的部分内容-错误处理机制

开发 后端 项目管理
但是把错误信息写到内存是很快。写到硬盘上就有一堆的问题。比如说读写慢、并发问题。

错误处理机制。

面对多个web服务器,多线程处理,我们想把错误信息记录到一个txt文档中。

但是把错误信息写到内存是很快。写到硬盘上就有一堆的问题。比如说读写慢、并发问题。

今天我们就利用这个实现错误处理 此文以MVC为例

1、首先要在  golable  文件的  protected void Application_Start()


注册一个错误处理机制。

MVC中自带一个  过滤器

FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);

image

这里面 我们看到这个过滤器

2、其实就是在 app_Start文件夹下面 的 FilterConfig.cs 文件

image

3、 打开FilterConfig.cs文件

就写了一个注册事件。我们看得到 这个是对错误处理机制

image

(当然 ,你们看到的是  HandleErrorAttribute 这个类)

4、所以你们可能觉得奇怪,我们来查看MyExceptionAttribut的定义看一下

image

继承了HandleErrorAttribute

这里我把这个类的代码贴一下


 

  1. public class MyExceptionAttribute : HandleErrorAttribute 
  2.     { 
  3.         //  private static object obj = new object(); 
  4.         public static ConcurrentQueue<Exception> ExceptionQueue = new ConcurrentQueue<Exception>();//定义队列 
  5.  
  6.         /// <summary> 
  7.         /// 在该方法中捕获异常。 
  8.         /// </summary> 
  9.         /// <param name="filterContext"></param> 
  10.         public override void OnException(ExceptionContext filterContext) 
  11.         { 
  12.  
  13.             base.OnException(filterContext); 
  14.             Exception ex = filterContext.Exception;//捕获异常信息。 
  15.             //将异常信息写到队列中。 
  16.             ExceptionQueue.Enqueue(ex); 
  17.             //跳转到错误页面. 
  18.             filterContext.HttpContext.Response.Redirect("/Error.html"); 
  19.  
  20.            
  21.  
  22.         } 
  23.     } 
  24.  
  25.   

主要是定义一个静态 队列  ConcurrentQueue

(当然你也可以用 Queue。但是微软说 这个ConcurrentQueue 比 Queue  安全。好像是线程安全的,一堆堆的理论,说白了就是用ConcurrentQueue 更安全)

这样所有的错误就都在这个队列里面了。(就是内存)

这样总不行吧。内存 断电就没有了的啊。

所以我们要想把资料存到 硬盘中。

5、现在又要在

  golable  文件的  protected void Application_Start()


中注册一个消费线程(这句话后面会解释,看不懂就继续)就是在 protected void Application_Start()中加入这些代码,***放最前面。

内容就是线程池开启一个线程 从刚刚定义的 MyExceptionAttribute的 ExceptionQueue队列里面取出项来。

将错误信息最加到文件后面。如果队列为空,就线程停留3秒。


 

  1. string filePath = Server.MapPath("/Log/"); 
  2.             ThreadPool.QueueUserWorkItem((a) => 
  3.             { 
  4.  
  5.                 while (true)//注意:线程不能结束。后面写到队列中的数据没法处理。 
  6.                 { 
  7.  
  8.     // 这里可以加一条   if (MyExceptionAttribute.ExceptionQueue.Count() > 0) 
  9. //{  发送邮件到管理员} 
  10.                     if (MyExceptionAttribute.ExceptionQueue.Count() > 0
  11.                     { 
  12.                         // Exception ex= MyExceptionAttribute.ExceptionQueue.Dequeue();//从队列中取出数据. 
  13.                         Exception ex = null
  14.                         bool isResult = MyExceptionAttribute.ExceptionQueue.TryDequeue(out ex); 
  15.                         if (ex != null && isResult) 
  16.                         { 
  17.                             string fullPath = filePath + DateTime.Now.ToString("yyyy-MM-dd") + ".txt"
  18.                             File.AppendAllText(fullPath, ex.ToString()); 
  19.                          //   ILog logger = LogManager.GetLogger("errorMsg"); 
  20.                           //  logger.Error(ex.ToString()); 
  21.                         } 
  22.                         else 
  23.                         { 
  24.                             Thread.Sleep(3000); 
  25.                         } 
  26.                     } 
  27.                     else 
  28.                     { 
  29.                         Thread.Sleep(3000);//避免造成CPU的空转。 
  30.                     } 
  31.                 } 
  32.  
  33.   
  34.  
  35.             }, filePath); 

6、总结。

这个就是一个生产者消费者的模式。

生产者就是 产生错误的源头。 消费者就是注册保存日志的方法。

中间有一个仓库就是    那个静态错误队列。

可以看到 系统产生的错误临时存放于内存中。然后一个新的线程 去读写静态错误队列。

正常情况 需要在错误队列里面加一个错误队列数字大于1000条的时候  发警告到邮箱的功能。那样感觉有点问题复杂化了,毕竟这里只是讲错误处理。

7、log4net 我前面讲过的一个开源框架 记录错误很好。

这里提供一个连接    log4net配置方法你可以把那个一起并到这里。那么就会有

把protected void Application_Start()中添加 的代码

改成。注意是改成:

 

  1. log4net.Config.XmlConfigurator.Configure(); 
  2.             //开始一个线程,查看异常队列 
  3.             string filePath = Server.MapPath("/Log/"); 
  4.             ThreadPool.QueueUserWorkItem((a) => 
  5.             { 
  6.  
  7.                 while (true)//注意:线程不能结束。后面写到队列中的数据没法处理。 
  8.                 { 
  9.                     if (MyExceptionAttribute.ExceptionQueue.Count() > 0
  10.                     { 
  11.                         // Exception ex= MyExceptionAttribute.ExceptionQueue.Dequeue();//从队列中取出数据. 
  12.                         Exception ex = null
  13.                         bool isResult = MyExceptionAttribute.ExceptionQueue.TryDequeue(out ex); 
  14.                         if (ex != null && isResult) 
  15.                         { 
  16.                             string fullPath = filePath + DateTime.Now.ToString("yyyy-MM-dd") + ".txt"
  17.                             //File.AppendAllText(fullPath, ex.ToString()); 
  18.                             ILog logger = LogManager.GetLogger("errorMsg"); 
  19.                             logger.Error(ex.ToString()); 
  20.                         } 
  21.                         else 
  22.                         { 
  23.                             Thread.Sleep(3000); 
  24.                         } 
  25.                     } 
  26.                     else 
  27.                     { 
  28.                         Thread.Sleep(3000);//避免造成CPU的空转。 
  29.                     } 
  30.                 } 
  31.  
  32.   
  33.  
  34.             }, filePath); 

这样就会按照你的要求把错误日志记录到

app_data文件夹下面。(前提是你有未处理的错误 。呵呵)

看到下图就成功了

image

题外话(

没有就自己创一个   var s=3/0;

这样就可以了。

 

责任编辑:王雪燕 来源: 博客园
相关推荐

2009-06-19 16:20:14

ASP.NET错误处理

2009-07-31 11:28:42

错误处理机制ASP.NET

2021-03-02 09:12:25

Java异常机制

2009-07-19 09:05:03

魔兽世界审批

2023-04-20 11:30:12

2012-04-13 09:32:19

微软路线图

2012-02-10 10:32:33

JavaSpring

2020-08-20 10:16:56

Golang错误处理数据

2009-08-24 09:46:40

面向切面编程AOP

2021-09-27 15:33:48

Go 开发技术

2020-09-15 08:28:17

JavaScript错误处理

2021-04-14 07:08:14

Nodejs错误处理

2021-09-27 10:04:03

Go程序处理

2011-03-17 09:20:05

异常处理机制

2023-10-26 15:49:53

Go日志

2024-03-27 08:18:02

Spring映射HTML

2020-09-14 08:35:36

JavaScript编程开发

2013-09-17 10:37:03

AOPAOP教程理解AOP

2014-11-17 10:05:12

Go语言

2021-04-29 09:02:44

语言Go 处理
点赞
收藏

51CTO技术栈公众号