关于面向切面编程的部分内容-错误处理机制
错误处理机制。
面对多个web服务器,多线程处理,我们想把错误信息记录到一个txt文档中。
但是把错误信息写到内存是很快。写到硬盘上就有一堆的问题。比如说读写慢、并发问题。
今天我们就利用这个实现错误处理 此文以MVC为例
1、首先要在 golable 文件的 protected void Application_Start()
注册一个错误处理机制。
MVC中自带一个 过滤器
FilterConfig.RegisterGlobalFilters(GlobalFilters.Filters);
这里面 我们看到这个过滤器
2、其实就是在 app_Start文件夹下面 的 FilterConfig.cs 文件
3、 打开FilterConfig.cs文件
就写了一个注册事件。我们看得到 这个是对错误处理机制
(当然 ,你们看到的是 HandleErrorAttribute 这个类)
4、所以你们可能觉得奇怪,我们来查看MyExceptionAttribut的定义看一下
继承了HandleErrorAttribute
这里我把这个类的代码贴一下
- public class MyExceptionAttribute : HandleErrorAttribute
- {
- // private static object obj = new object();
- public static ConcurrentQueue<Exception> ExceptionQueue = new ConcurrentQueue<Exception>();//定义队列
- /// <summary>
- /// 在该方法中捕获异常。
- /// </summary>
- /// <param name="filterContext"></param>
- public override void OnException(ExceptionContext filterContext)
- {
- base.OnException(filterContext);
- Exception ex = filterContext.Exception;//捕获异常信息。
- //将异常信息写到队列中。
- ExceptionQueue.Enqueue(ex);
- //跳转到错误页面.
- filterContext.HttpContext.Response.Redirect("/Error.html");
- }
- }
主要是定义一个静态 队列 ConcurrentQueue
(当然你也可以用 Queue。但是微软说 这个ConcurrentQueue 比 Queue 安全。好像是线程安全的,一堆堆的理论,说白了就是用ConcurrentQueue 更安全)
这样所有的错误就都在这个队列里面了。(就是内存)
这样总不行吧。内存 断电就没有了的啊。
所以我们要想把资料存到 硬盘中。
5、现在又要在
golable 文件的 protected void Application_Start()
中注册一个消费线程(这句话后面会解释,看不懂就继续)就是在 protected void Application_Start()中加入这些代码,***放最前面。
内容就是线程池开启一个线程 从刚刚定义的 MyExceptionAttribute的 ExceptionQueue队列里面取出项来。
将错误信息最加到文件后面。如果队列为空,就线程停留3秒。
- string filePath = Server.MapPath("/Log/");
- ThreadPool.QueueUserWorkItem((a) =>
- {
- while (true)//注意:线程不能结束。后面写到队列中的数据没法处理。
- {
- // 这里可以加一条 if (MyExceptionAttribute.ExceptionQueue.Count() > 0)
- //{ 发送邮件到管理员}
- if (MyExceptionAttribute.ExceptionQueue.Count() > 0)
- {
- // Exception ex= MyExceptionAttribute.ExceptionQueue.Dequeue();//从队列中取出数据.
- Exception ex = null;
- bool isResult = MyExceptionAttribute.ExceptionQueue.TryDequeue(out ex);
- if (ex != null && isResult)
- {
- string fullPath = filePath + DateTime.Now.ToString("yyyy-MM-dd") + ".txt";
- File.AppendAllText(fullPath, ex.ToString());
- // ILog logger = LogManager.GetLogger("errorMsg");
- // logger.Error(ex.ToString());
- }
- else
- {
- Thread.Sleep(3000);
- }
- }
- else
- {
- Thread.Sleep(3000);//避免造成CPU的空转。
- }
- }
- }, filePath);
6、总结。
这个就是一个生产者消费者的模式。
生产者就是 产生错误的源头。 消费者就是注册保存日志的方法。
中间有一个仓库就是 那个静态错误队列。
可以看到 系统产生的错误临时存放于内存中。然后一个新的线程 去读写静态错误队列。
正常情况 需要在错误队列里面加一个错误队列数字大于1000条的时候 发警告到邮箱的功能。那样感觉有点问题复杂化了,毕竟这里只是讲错误处理。
7、log4net 我前面讲过的一个开源框架 记录错误很好。
这里提供一个连接 log4net配置方法你可以把那个一起并到这里。那么就会有
把protected void Application_Start()中添加 的代码
改成。注意是改成:
- log4net.Config.XmlConfigurator.Configure();
- //开始一个线程,查看异常队列
- string filePath = Server.MapPath("/Log/");
- ThreadPool.QueueUserWorkItem((a) =>
- {
- while (true)//注意:线程不能结束。后面写到队列中的数据没法处理。
- {
- if (MyExceptionAttribute.ExceptionQueue.Count() > 0)
- {
- // Exception ex= MyExceptionAttribute.ExceptionQueue.Dequeue();//从队列中取出数据.
- Exception ex = null;
- bool isResult = MyExceptionAttribute.ExceptionQueue.TryDequeue(out ex);
- if (ex != null && isResult)
- {
- string fullPath = filePath + DateTime.Now.ToString("yyyy-MM-dd") + ".txt";
- //File.AppendAllText(fullPath, ex.ToString());
- ILog logger = LogManager.GetLogger("errorMsg");
- logger.Error(ex.ToString());
- }
- else
- {
- Thread.Sleep(3000);
- }
- }
- else
- {
- Thread.Sleep(3000);//避免造成CPU的空转。
- }
- }
- }, filePath);
这样就会按照你的要求把错误日志记录到
app_data文件夹下面。(前提是你有未处理的错误 。呵呵)
看到下图就成功了
题外话(
没有就自己创一个 var s=3/0;
这样就可以了。
)
相关文章
- 向使用 SAML 和 ADFS 的 Open Distro for Elasticsearch Kibana 添加单点登录
- 使用 AWS ParallelCluster 运行 Ansys Fluent 的最佳实践
- java Adapter模式
- Amazon Polly 推出神经文本转语音和新闻播音员语音风格
- 推出 PartiQL:适合所有数据的一种查询语言
- 通过 AWS IoT Device Defender 检测异常设备行为防止非法入侵 | AWS 上的物联网
- 如何使用 AWS IoT Greengrass 在边缘安装面部识别模型 | AWS 上的物联网
- 利用 AWS IoT Device Management 服务轻松部署设备组 | AWS 上的物联网
- 将 AWS IoT Greengrass 作为 Snap 部署到边缘设备 | AWS 上的物联网
- 边缘机器学习:借助 AWS IoT Greengrass 使用和重新训练图像分类模型(第 1 部分)| AWS 上的物联网
- 边缘机器学习:借助 AWS IoT Greengrass 使用和重新训练图像分类模型(第 2 部分) | AWS 上的物联网
- 在零售场景中使用 AWS IoT Device Management 处理订单请求 | AWS 上的物联网
- 使用 KEPServerEX 将不同的工业设备和应用程序从工厂车间连接到 AWS | AWS 上的物联网
- AWS CloudFormation 更新 – 公共覆盖路线图 CDK 优势
- 现已开放 – AWS 中东(巴林)
- 用 AWS IoT Device Management 进行连续作业 | AWS 上的物联网
- 利用 Lambda 与 SQS 实现动态补充 CloudFront 海外源站资源
- 基于 Route53 构建混合 DNS 系统
- 使用 GitOps 在无服务器时代构建现代 CI/CD 管道
- 将 GitHub 凭证与 Teleport 结合进行 EKS 身份验证