1.Logging Application Block(日志应用程序块)
1.1涉及对象及处理过程
1.1.1主要有如下五种类别的对象
日志记录器(Log Writer):日志记录器是创建日志项(Log Entry)及写它们到你的日志目标(Logging Target)的主要入口点(Entry Point)。它创建一个包含要记录的信息的日志项的实例(Instance),并与其它过滤日志项的对象交互,赋一个或多个类别(Category)给这个日志项,最后格式化并指派这个日志项给合适的目标(Target)。
日志过滤器(Log Filters):日志过滤器能基于许多特征阻止(Block)或允许一个日志项。每个日志项被赋予一个或多个类别(默认是General类别),类别日志过滤器(Category Log Filter)能使用这些类别来允许或阻止一个日志项。另外,两个特殊的日志过滤器能阻止所有日志,或阻止优先级不在指定范围内(Maximum Priority指定最大值,Minimum Priority指定最小值,一个例外是当待写入的日志项优先级小于0时,此日志项将不受优先级过滤器的限制)的日志项。你能在配置文件中为这个程序块定义类别,优先级并设置这些过滤器。
跟踪源(Trace Sources):跟踪源是连接日志项(Log Entry)与日志目标(Log Target)的桥梁,也可以把它看作
一组桶,这个应用块放置所有未被日志过滤器阻止的日志项到这组桶。你使用这些桶来确定日志项的目的地----你可以认为这些桶是日志项的源(Source),而这些日志项将被指派到目的地(Target Destination)。有两类基本的跟踪源:
- 你在配置文件中定义的用于每个类别(Category)的跟踪源,称为类别源(Category Source);
- 有三个内置的跟踪源:一个(All Events)接收所有日志项,一个(Logging Errors & Warnings)是在日志处理或指派过程中出错时接收日志项,一个(Unprocessed Category)是在日志项不匹配任何配置的类别时接收日志项;称为特别源(Special Source);
跟踪侦听器(Trace Listeners):跟踪侦听器代表你的日志项的目标(Target),你为每类目标(如Windows事件
日志,磁盘文件与e-mail消息)配置一个跟踪侦听器,这些目标就是你发送的日志的目的地。跟踪侦听器侦
听将要到达跟踪源桶的日志项,然后按要求格式化每个日志项,最后将它指派给为跟踪源配置的目标
(Target),你的配置映射每个跟踪源(你定义的每个类别源及三个特别源)到一个或多个跟踪侦听器。值得注
意的是这允许你将每个日志项指派(dispatch)给零个,一个或多个目标(如同时以e-mail发送及将它写到
Windows 事件日志)。
日志格式化器(Log Formatters):你添加到配置的每个跟踪侦听器使用一个日志格式化器来转换日志项(一
系列属性)中的数据成某种适合发送到日志目标的格式。这个应用块包括一个文本格式化器(你能用跟踪侦
听器来配置)和一个二进制格式化器(序列化日志项数据成某种适合传输到诸如MSMQ等目标的格式)。这种
文本格式化器是可配置的,这样你就能修改文本消息的格式与内容,包括使用占位符(代表日志项的属性
值)。
1.1.2日志处理顺序
- 你的应用程序提交日志应用程序块应该记录的信息,有两种方式来创建这个信息:一种是使用LogWriter类来自动创建一个日志项,另一种是直接创建一个LogEntry类的实例,然后用要记录的信息来填充它。日志项能指定一组类别,这些类别映射到配置文件中定义的类别。这种映射控制了应用块处理日志项(过滤器及它使用的源)的方式。
- 日志记录器通过你在配置文件中定义的过滤器来传输日志项。这些过滤器能基于日志项的优先级,类别名来阻止日志项,如果日志未启用,日志项也将被阻止。
- 如果日志过滤器没有阻止日志项,日志记录器将检索合适的跟踪源。你能使用的跟踪源由一组你创建并配置的类别源及你能用来确保记录所有日志项(例如,如果在日志系统中有一个错误或日志项不匹配任何配置的类别)的三个特别源组成。
- 你能为每个跟踪源配置一个或多个跟踪侦听器。换言之,你能为消息包括的每个类别和可能处理消息的三个特别源中的每个配置一组特定的跟踪侦听器。日志记录器将传递日志项到匹配的跟踪源。
- 跟踪侦听器使用日志格式器转换日志项中信息成一种合适的格式,如格式化的文本或二进制,然后写结果到对应于跟踪侦听器类别的输出。取决于跟踪侦听器类别,输出可能是一个文件,一个数据库,WMI,Message Queuing(也称为MSMQ),或者是一个e-mail消息。
1.2Logging Target Listeners(日志目标侦听器)
内置了九个日志目标侦听器
- Database Trace Listener(数据库跟踪侦听器)---使用在数据访问应用程序中配置的数据库实例向指定的数据库发送日志消息;
- Email Trace Listener(Email跟踪侦听器)---向指定的Email服务器发送日志消息;
- Event Log Trace Listener(事件日志跟踪侦听器)---向指定的Windows事件日志如应用程序或系统日志发送日志消息;
- Flat File Trace Listener(平面文件跟踪侦听器)---向指定的文本文件发送日志消息,可以指定文本的头与脚,消息的格式可通过模板来指定;
- Message Queuing Trace Listener(消息队列跟踪侦听器)---向指定的Windows Message Queuing发送日志消息,对于队列有很多选项,如优先级,事务,加密;
- Rolling Flat File Trace Listener(滚动平面文件跟踪侦听器)---向一组文本文件发送日志消息,侦听器在指定的时间间隔启动一个新文件(使用指定的文件命名模式),也可以选择重写现有文件,可以指定文本的头与脚,消息的格式可通过模板来指定;
- System Diagnostics Trace Listener(系统诊断跟踪侦听器)---监视跟踪与调试输出的跟踪侦听器的抽象基类;
- WMI Trace Listener(WMI跟踪侦听器)---为每个日志消息引发一个WMI(Windows Management Instrumentation)事件;
- XML Trace Listener(XML跟踪侦听器)---以XML的格式向指定的文本文件写入日志消息;
- Custom Trace Listener(自定义跟踪侦听器)---添加到日志应用程序块的一个类,它向自定义日志目标写入日志消息;
1.3Logging Message Formatters(日志消息格式器)
内置了两个日志消息格式器:
- Binary Log Message Formatter(二进制日志消息格式器)---为日志消息生成一个二进制格式输出,适合与Message Queuing Trace Listener(消息队列跟踪侦听器)一起使用;
- ext Formatter(文本格式器)---为日志消息生成一个文本格式输出,适合与诸如平面文件, 滚动平面文件,Email,事件日志跟踪侦听器一起使用;
- Custom Log Message Formatter(自定义日志消息格式器)---添加到日志应用程序块的一个类,它为日志消息实现了一个自定义格式;
1.4日志配置工具中相关字段
1.4.1Categories(类别)
- Auto Flush(自动刷新)
Specifies if the Logging Target Listeners will automatically flush messages to the target as soon as they are receivd. When set to False,the listener buffers the messages and send them to them target in batches or when significant events occur such as the machine shutting down.
指定当日志目标侦听器收到消息时,是否立即发送它给目标。如果设置为False,侦听器缓存消息,然后批量发送给目标,或者,当关机时,才发送消息。 - Minimum Severity(最低严重程度)
The severity level for messages that will be logged.Messages sent to the block for this category,and with a lower severity than that specified,will not be logged for this category.
低于最低严重程度的消息将不被允许写入日志目标;
配置工具中的All Off Critical Error Warning Information Verbose ActivityTracing严重程度依次递减;
1.4.2Logging Filters(日志过滤器)
- Priority Filter(优先级过滤器)
Maximum Priority(最大优先级值)
The maximum priority value for messages to be passed to the logging targets listener(s). Messages with a priority above this value are not sent to the logging target.
Minimum Priority(最小优先级值)
The minimum priority value for messages to be passed to the logging targets listener(s).Messages with a priority below this value are not sent to the logging target. - Category Filter(类别过滤器)
DenyAllExceptAllowed
The filter will allow only messages that match one of the configured categories to pass to the logging target;
过滤器将只允许与类别过滤器中配置的类别匹配的消息传递到日志目标;
AllowAllExceptDenied
The filter will allow all messages except those that match one of the configured categories to pass to the logging target.
过滤器将允许除与类别过滤器中配置的类别匹配的消息之外的消息传递到日志目标; - Logging Enabled Filter(启用日志过滤器)
All Logging Enabled 设为true时允许日志写入日志目标,设为false时将阻止所有日志写入。
1.4.3Global Settings(全局设置)
- Activity Tracing Enabled(启用活动跟踪)
Specifies whether activity tracing is enabled.When enabled,code can use Tracer instances to trace individual activities and associate the resulting log messages through an Activity ID.
指定是否启用活动跟踪。如果启用,代码可以使用跟踪器实例来跟踪单个活动,并且用活动ID关联最终的日志消息。 - Default Logging Category(默认日志类别)
The default logging category to use for messages set to the block that do not specify a Category.Categories allow log messages to be handled and processed in different ways,and sent to different logging targets.Log messages can be assigned to one or more categories.如果日志块没有指定类别,日志消息将默认属于这个类别。类别使处理日志消息的方式多样化,日志消息可以发送到不同的目标,也可以被赋予多个类别。 - Revert Impersonation(恢复模拟)
By default,log messages are written using impersonation.This provides some performance advantage for logging.This setting allows impersonation to revert to the caller.
默认情况下,使用模拟来写日志,这样提高了写日志的性能。这个设置可以将模拟转给调用方(Caller)。 - Warn If No Category Match(如果没有匹配类别发出警告)
Specifies whether the block will write a Warning message to the logging target(s) specified in the Logging Errors and Warnings special category when a log message is received that does not match any of the defined Logging Categories.
如果日志消息不属于任何指定的类别,这个应用块是否写消息给Logging Errors and Warnings中指定的日志目标。
2.Exception Handling Application Block(异常处理应用程序块)
异常处理块的目的不是让你在捕获异常的任何地方都使用,主要是用来简化应用程序(Application)或层边界(Layer Boundary)中的异常处理与管理;
2.1异常处理配置工具中相关字段
2.1.1Post handling action(异常处理后的行为)
指定异常处理块执行完为异常类型设定的所有处理程序(Handler)后做什么。实际上是告诉调用代码是否要继续执行。有三个值:
- NotifyRethrow(the default)---返回true,告诉调用代码应该重新抛出原始异常;
- ThrowNewException---抛出执行所有处理程序(Handler)后的异常;
- None---返回false,告诉调用代码继续执行;
2.1.2Handlers(处理程序)
内置四个异常处理程序:
- Wrap Handler(包装异常处理程序)---将发送给这个异常处理块的异常包装在新的异常类型中,作为新异常类型的内部异常(Inner Exception),可以为新异常类型指定异常消息;
- Replace Handler(替换异常处理程序)---用指定的新异常类型替换发送给这个异常处理块的异常,可以为新异常类型指定异常消息;
- Logging Exception Handler(记录异常处理程序)---通过日志应用程序块记录发送给这个异常处理块的异常的详细信息;
- Fault Contract Exception Handler(错误契约异常处理程序)---通过让WCF服务执行一个策略(policy)并返回一个合适的错误消息(Fault Message)来为WCF服务提供异常屏蔽(Exception Shielding);
- Custome Exception Handler(自定义异常处理程序)---添加到企业库的自定义异常处理类;
2.2选择一个异常处理策略(Strategy)
2.2.1用一个不同的异常类型替换原始异常,然后抛出新的异常。
这是异常屏蔽模式的一种实现,在你的异常处理代码中,你能清理资源或执行任何有关的其它处理。通过替换异常处理程序,你用新的异常类型替换原始异常,而新的异常类型不包括与错误源,应用程序或操作系统有关的敏感信息。如果你想记录异常,可以添加记录异常处理程序到异常策略。如果你想记录原始异常,将记录异常处理程序置于替换异常处理程序之前,反之,置于其后,值得注意的是,如果你记录敏感信息,要确保日志文件足够安全。设置Post-handling action为ThrowNewException,这样异常处理块将抛出新异常类型。
2.2.2包装原始异常以保存其内容,然后抛出新异常。
这是异常转换模式的一种实现,在你的异常处理代码中,你能清理资源或执行任何有关的其它处理。通过包装异常处理程序,你将原始异常包装在新的异常类型(与调用方代码关联较大)中,然后抛出新的异常,以便代码栈中更高层代码能处理它。如果你想保存完整的原始异常及其信息或者向处理异常的代码提供额外的信息,这种方法很有用。如果你想记录异常,可以添加记录异常处理程序到异常策略。如果你想记录原始异常,将记录异常处理程序置于包装异常处理程序之前,反之,置于其后。设置Post-handling action为ThrowNewException,这样异常处理块将抛出新异常类型。
2.2.3记录并重抛原始异常。
在你的异常处理代码中,你能清理资源或执行任何有关的其它处理。你使用记录异常处理程序将详细的异常信息写入配置的日志存储处,如Windows事件日志或一个文件。如果异常不需要在程序的其它地方作进一步处理(如,一个重试操作),则设置Post-handling action为None.否则,设置Post-handling action为NotifyRethrow。然后,你的事件处理程序可以决定是否抛出这个异常。如果你总是想异常处理块抛出异常,那么设置为NotifyRethrow。
2.3Process or HandleException?
异常处理块为管理异常提供了两种方式。你能使用Process方法来执行程序中的任何方法,让这个应用
块自动执行管理与异常的抛出。如果你想对处理作更细的控制,你可以使用HandleException方法。
- Process方法是最常使用的,在大多数情况下是很有用的。指定一个你想执行的委托(方法的地址),或Lambda表达式。异常处理块执行这个方法或表达式,并自动管理任何发生的异常。你可能通常设置Post-handling action为ThrowNewException来自动抛出执行所有处理程序(Handler)后的异常。如果你想代码继续执行(而不是抛出异常),你可以设置Post-handling action为None。
- HandleException也很有用,如果你想检测执行异常处理策略后的结果。例如,如果你设置Post-handling action为NotifyRethrow,你可以使用HandleException方法的返回值来决定是否抛出异常。你也能使用HandleException方法传一个异常给应用块,让它返回源自执行策略的异常(可能是原始异常,或者替换后的异常,也可能是包含在一个新异常中的原始异常)。