一.把异常信息Logging到数据库
在日志和监测应用程序块中,有朋友提意见说希望能够把异常信息Logging到数据库中,在这里介绍一下具体的实现方法。
1.创建相关的数据库环境:
我们可以用日志和监测应用程序块自带的SQL语句来创建相关的数据库环境:
创建数据库:
CREATE DATABASE [Logging]  ON (NAME = N'Logging', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL\data\Logging.mdf' , SIZE = 1, FILEGROWTH = 10%) LOG ON (NAME = N'Logging_log', FILENAME = N'C:\Program Files\Microsoft SQL Server\MSSQL\data\Logging_log.LDF' , FILEGROWTH = 10%)
创建表:
CREATE TABLE [dbo].[Log] (
    [LogID] [int] IDENTITY (1, 1) NOT NULL ,
    [EventID] [int] NULL ,
    [Category] [nvarchar] (64) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
    [Priority] [int] NOT NULL ,
    [Severity] [nvarchar] (32) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
    [Title] [nvarchar] (256) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
    [Timestamp] [datetime] NOT NULL ,
    [MachineName] [nvarchar] (32) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
    [AppDomainName] [nvarchar] (2048) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
    [ProcessID] [nvarchar] (256) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
    [ProcessName] [nvarchar] (2048) COLLATE SQL_Latin1_General_CP1_CI_AS NOT NULL ,
    [ThreadName] [nvarchar] (2048) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
    [Win32ThreadId] [nvarchar] (128) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
    [Message] [nvarchar] (2048) COLLATE SQL_Latin1_General_CP1_CI_AS NULL ,
    [FormattedMessage] [ntext] COLLATE SQL_Latin1_General_CP1_CI_AS NULL 
) ON [PRIMARY] TEXTIMAGE_ON [PRIMARY]
GO
创建存储过程:
 1CREATE PROCEDURE WriteLog
 2(
 3    @EventID int, 
 4    @Category nvarchar(64),
 5    @Priority int, 
 6    @Severity nvarchar(32), 
 7    @Title nvarchar(256), 
 8    @Timestamp datetime,
 9    @MachineName nvarchar(32), 
10    @AppDomainName nvarchar(2048),
11    @ProcessID nvarchar(256),
12    @ProcessName nvarchar(2048),
13    @ThreadName nvarchar(2048),
14    @Win32ThreadId nvarchar(128),
15    @Message nvarchar(2048),
16    @FormattedMessage ntext
17)
18AS 
19
20    INSERT INTO [Log] (
21        EventID,
22        Category,
23        Priority,
24        Severity,
25        Title,
26        [Timestamp],
27        MachineName,
28        AppDomainName,
29        ProcessID,
30        ProcessName,
31        ThreadName,
32        Win32ThreadId,
33        Message,
34        FormattedMessage
35    )
36    VALUES (
37        @EventID, 
38        @Category, 
39        @Priority, 
40        @Severity, 
41        @Title, 
42        @Timestamp,
43        @MachineName, 
44        @AppDomainName,
45        @ProcessID,
46        @ProcessName,
47        @ThreadName,
48        @Win32ThreadId,
49        @Message,
50        @FormattedMessage)
51GO
该SQL语句默认的路径为C:\Program Files\Microsoft Enterprise Library\src\Logging\Sinks\Database\Scripts,直接运行CreateLoggingDatabase.cmd即可。
2.运行配置工具,我们创建一个日志和监测应用程序块,并建一个Database Sink,具体的配置方法在日志和监测应用程序块中讲过了,这里就不重复了,我们看一下它的配置:
 
注意设置StoredProcName为WriteLog,就是我们刚才创建的存储过程。
3.同时再创建一个Category,起名为DataException,并设置它的Sink为Database Sink。
4.设置Logging Handler的LogCategory为我们刚才创建的DataException,其他的参数暂时默认。
 
5.至此配置完成,在程序中我们不需要做任何改动(这就是企业库的配置驱动的思想精妙之处^_^)。
 1/**//// <summary>
 2        /// 日志策略
 3        /// </summary>
 4        /// <param name="sender"></param>
 5        /// <param name="e"></param>
 6        private void btn_Log_Click(object sender, System.EventArgs e)
 7        {
 8            try
 9            {
10                Exception ex = new Exception();
11                throw ex;
12            }
13            catch(Exception ex)
14            {
15                bool Flag = ExceptionPolicy.HandleException(ex,"Log Policy");
16
17                if(Flag)
18                {
19                    throw;
20                }
21            }
22        }

补充一点:在项目中要添加对Microsoft.Practices.EnterpriseLibrary.Logging.Sinks.Database.dll的引用

二.异常的传播机制

异常的传播机制有以下几种:
l        异常自动传播
l        在同一层内部,捕获或者再抛出原有异常
l        捕获,包装和抛出包装后的异常
我们不推荐直接抛出原有异常,因为恶意的用户能够从系统诊断信息中得知应用的详细情况,并从中查找应用的弱点。异常应用程序块提供了一旦配置的Handler执行后,就产生对应的post-handling动作,该动作有如下选项:
None -没有重抛异常的动作。
NotifyRethrow -告诉调用程序:Policy推荐应该重抛异常。
ThrowNewException -在所有的Handler执行后,向调用程序抛出最终异常(并不一定是原始的异常)。

三.异常的格式化
可以格式化任何System.Exception类型的异常
能够用来记录或者显示异常的详细信息
字符型格式化器——TextExceptionFormatter:创建在一个屏幕上,日志中或以其他形式表现的,可以表现异常信息的详细记录
XML格式化器——XMLExceptionFormatter:针对一个异常,创建一个用XML表现形式表现记录,每一个异常的属性,均可以被存储为XML元素。
看一下在Enterprise Library Quick Start中提供的自定义的ExceptionFormatter,实现了TextExceptionFormatter类:
 1/**//// <summary>
 2    /// Summary description for AppTextExceptionFormatter.
 3    /// </summary>    
 4    public class AppTextExceptionFormatter : TextExceptionFormatter
 5    {
 6        public AppTextExceptionFormatter(TextWriter writer, Exception exception)
 7            : base (writer, exception) 
 8            {
 9            }
10        
11        protected override void WriteDescription() 
12        {
13            // An exception of type {0} occurred and was caught.
14            string line = String.Format("An exception of type {0} occurred and was caught.", base.Exception.GetType().FullName);
15            this.Writer.WriteLine(line);
16        }
17
18        protected override void WriteExceptionType(Type exceptionType) 
19        {
20            base.Indent();
21            base.Writer.WriteLine("Type : {0}", exceptionType.FullName);
22        }
23
24        public override void Format() 
25        {
26            //this.Writer.WriteLine("Message : {0}", message);
27            this.WriteDescription();
28            //this.WriteExceptionType(base.Exception.GetType());
29            base.WriteMessage(base.Exception.Message);
30        }
31
32    }
四.创建自定义的异常处理器
异常处理应用程序块允许您包装并使用您自己的例外业务处理流程,例如在时间记录系统中填写一个事件,利用业务规范进行包装和替代,利用另外的记录系统进行记录(比较常用的有Log4net,前段时间深渊野鱼介绍的,还没用过^_^),这种灵活的可配置性,将允许您在不同的异常类型及其策略中灵活的配置。
可以通过实现ExceptionHandler抽象类,来创建定制的Handler
1public abstract class ExceptionHandler : ConfigurationProvider, IExceptionHandler
该抽象类继承ConfigurationProvider类,并实现IExceptionHandler接口。ConfigurationProvider抽象类实现了IConfigurationProvider接口,用来读取配置数据。
1public abstract class ConfigurationProvider : IConfigurationProvider
使用支持序列化的数据类型作为配置参数,还有要注意数据类型的简单,避免“Exception Handling Exceptions”
看一下在Enterprise Library Quick Start中提供了定制Handler的实现:
 1/**//// <summary>
 2  /// Summary description for GlobalPolicyExceptionHandler.
 3  /// </summary>
 4  public class AppMessageExceptionHandler : ExceptionHandler
 5  {
 6    public AppMessageExceptionHandler()
 7    {
 8    }
 9
10    public override void Initialize(ConfigurationView configurationView)
11    {
12    }
13
14    public override Exception HandleException(Exception exception, string policyName, Guid correlationID) 
15    {
16      DialogResult result = this.ShowThreadExceptionDialog(exception);
17
18      // Exits the program when the user clicks Abort.
19      if (result == DialogResult.Abort) 
20        Application.Exit();
21
22      return exception;
23    }
24
25    // Creates the error message and displays it.
26    private DialogResult ShowThreadExceptionDialog(Exception e) 
27    {
28      string errorMsg = e.Message + Environment.NewLine + Environment.NewLine;
29
30      return MessageBox.Show(errorMsg, "Application Error", MessageBoxButtons.OK, MessageBoxIcon.Stop);
31    }
32  }
结束语:异常处理应用程序块的进阶篇就写到这里了。

转载于:https://blog.51cto.com/terrylee/67614

Enterprise Library Step By Step系列(十二):异常处理应用程序块——进阶篇相关推荐

  1. 数据与广告系列十二:接上一篇,见习算法工程师教程

    作者|黄崇远(题图:ssyer.com,CCO协议)  公号,数据虫巢(ID: blogchong) " 看完了这篇,你就是个见习级算法工程师了.你觉得可能吗?" 接上一篇< ...

  2. Enterprise Library Step By Step系列(十一):异常处理应用程序块——入门篇

    Enterprise Library Step By Step系列(十一):异常处理应用程序块--入门篇 作者:Terrylee 一.概述 使开发人员和决策人员能够针对发生在企业应用程序体系结构层的异 ...

  3. Alamofire源码解读系列(十二)之请求(Request)

    本篇是Alamofire中的请求抽象层的讲解 前言 在Alamofire中,围绕着Request,设计了很多额外的特性,这也恰恰表明,Request是所有请求的基础部分和发起点.这无疑给我们一个Req ...

  4. kotlin杂谈系列十二(Kotlin和Java的互操作)

    Kotlin杂谈系列十二 这次就主要来谈谈kotlin和java互操作的问题 kotlin出来的使命就是为了解决java的模板问题和一些冗长的问题所以kotlin天生就很好的支持了java 所以我们在 ...

  5. Reflex WMS入门系列十二:Reflex里的Location

    Reflex WMS入门系列十二:Reflex里的Location 玩过SAP系统里的人都知道,在SAP系统里库存管理分为IM Level和WM Level.IM Level的仓库,在SAP里被定义为 ...

  6. Highcharts翻译系列十二:gauge测量图

    Highcharts翻译系列十二:gauge测量图 说明 测量图需要highcharts-more.js的支持 属性 参数 描述 默认值 animation 动画 true color 主要颜色或序列 ...

  7. xen是服务器虚拟化,xen虚拟化实战系列(十二)之xen虚拟机高可用之在线迁移

    xen虚拟化实战系列文章列表 xen虚拟化实战系列(十三)之xen虚拟机集中管理之convirt 1. 方案背景概述 本文是有对我们一个xen虚拟化生产环境将要改造的一个方案而来,在项目上线初期,没有 ...

  8. Web 前端开发精华文章推荐(jQuery、HTML5、CSS3)【系列十二】

    2012年12月12日,[<Web 前端开发人员和设计师必读文章>系列十二]和大家见面了.梦想天空博客关注 前端开发 技术,分享各种增强网站用户体验的 jQuery 插件,展示前沿的 HT ...

  9. C#基础知识梳理系列十:异常处理 System.Exception

    C#基础知识梳理系列十:异常处理 System.Exception 参考文章: (1)C#基础知识梳理系列十:异常处理 System.Exception (2)https://www.cnblogs. ...

最新文章

  1. [na]pc加入域认证细节
  2. java linux 面试题_java 面试题
  3. java servlet helloworld,Java如何创建HelloWorld Servlet?
  4. 【c++】28.虚析构函数、纯虚函数
  5. Cpp 对象模型探索 / 编译器为对象创建缺省构造函数的条件
  6. @EnableDiscoveryClient和@EnableEurekaClient
  7. java建议:优先使用基本类型
  8. c语言共享内存储存结构体,C语言共享内存使用思路利用结构体
  9. iphone全部机型_iPhone 上新,首次明确支持中国北斗
  10. SpringBoot学习笔记(4):自定义的过滤器
  11. ORA-01940: cannot drop a user that is currently connected
  12. linux nmon 进程io,Linux服务器用iotop命令分析服务器磁盘IO情况
  13. 服务器能用usb pe安装win7系统,另一种U盘(支持winPE,可以安装win7)安装ubuntu系统的方法...
  14. 冰点还原离线激活_冰点还原密钥,手把手教你如何激活冰点还原
  15. 黑群晖DSM7.1.0物理机安装教程
  16. Mybatis-Plus 的BaseMapper用法
  17. Android实现USB扫码枪获取扫描二维码
  18. HTML/CSS——微信公众号二维码显示效果
  19. vue项目为什么选择svg图标
  20. 达人评测华为MatePadPro2怎么样

热门文章

  1. Centos7 下 配置 rsync 以及 rsync+inotify 实时同步
  2. SSM框架之批量增加示例(同步请求jsp视图解析)
  3. Windows 活动目录(AD)服务器系统升级到2012之活动目录角色迁移(三)
  4. 2014-5-14 我的战斗效果
  5. 苹果所有常用证书,appID,Provisioning Profiles配置说明及制作图文教程(精)
  6. Javascript与正则表达式个人总结与收录--高级篇
  7. aws lambda_为什么我会自动删除所有旧的推文以及我用来执行此操作的AWS Lambda函数...
  8. <软件过程与改进>计算大题考点总结与例题
  9. linux消息通信无法接收,进程间通信:消息队列有关问题:进程1接收不到进程2的消息...
  10. Java3大框架的学习都是什么