Enterprise Library 2.0 技巧(4):如何用编程的方法来配置Logging Application Block

简介:
在本系列的技巧(1技巧(2中分别介绍了使用外部配置文件,使用数据库记录配置信息两种方法,不知道大家有没有想过不使用任何配置文件,也不使用数据库而直接用编程的方法来实现呢?本文将会展示如何使用编程的方法来配置Logging Application Block。首先我们需要了解一下Logging Application Block中比较重要的几个对象:

1LogFormatter

格式化对象,LogFormatterTextFormatterBinaryFormatter两种,多数情况下我们会使用TextFormatter,它通过一个Template来创建,一个完整的Template格式如下:

None.gif Timestamp: {timestamp}{newline}
None.gif
None.gifMessage: {message}{newline}
None.gif
None.gifCategory: {category}{newline}
None.gif
None.gifPriority: {priority}{newline}
None.gif
None.gifEventId: {eventid}{newline}
None.gif
None.gifSeverity: {severity}{newline}
None.gif
None.gifTitle:{title}{newline}
None.gif
None.gifMachine: {machine}{newline}
None.gif
None.gifApplication Domain: {appDomain}{newline}
None.gif
None.gifProcess Id: {processId}{newline}
None.gif
None.gifProcess Name: {processName}{newline}
None.gif
None.gifWin32 Thread Id: {win32ThreadId}{newline}
None.gif
None.gifThread Name: {threadName}{newline}
None.gif
None.gifExtended Properties: {dictionary({key} - {value})}{newline}

这里就不具体解释每一项的含义,大家可以参考有关文档,示例代码:

None.gif const   string  Template  =   " Timestamp: {timestamp}{newline} "   +
None.gif
None.gif                            
" Message: {message}{newline} "   +
None.gif
None.gif                            
" Category: {category}{newline} "   +
None.gif
None.gif                            
" Machine: {machine}{newline} " ;
None.gif
None.gifTextFormatter formatter 
=   new  TextFormatter(Template);
2 TraceListener
TraceListener 提供了日志记录服务,它指定的是日志将被记录到何处,数据库中或者是文本文件,Enterprise Library提供了7
TraceListener Database TraceListener、 Email TraceListener、 Flat File TraceListener、 Formatter Event Log TraceListener、 Msmq TraceListener、 System Diagnostics TraceListener、 WMI Trace Listener。每一种 TraceListener都需要一个 LogFormatter来对记录的信息进行格式化,例如创建一个 FlatFileTraceListener实例:
None.gif const   string  LogFilePath  =   @" d:\\share\\messages.log " ;
None.gif
None.gifFlatFileTraceListener logFileListener 
=
None.gif
None.gif            
new  FlatFileTraceListener(LogFilePath,
None.gif
None.gif                                       
" ---------- " ,
None.gif
None.gif                                       
" ---------- " ,
None.gif
None.gif                                       formatter);
这里的 formatter就是在上面创建的 TextFormatter对象。

3LogSource

LogSource 其实就是TraceListener的集合,Enterprise Library允许针对不同的日志信息记录到不同地方,因此可以在LogSource中加入多个TraceListener
None.gif LogSource mainLogSource  =
None.gif
None.gif            
new  LogSource( " MainLogSource " , SourceLevels.All);
None.gif
None.gif        mainLogSource.Listeners.Add(logFileListener);
4 LogFilter

过滤器,对日志信息进行过滤,Enterprise Library默认提供了三种过滤器,用户也可以定义自己的过滤器,示例代码:
None.gif //  创建一个类别过滤器
None.gif

None.gifICollection
< string >  categoryfilters  =   new  List < string > ();
None.gif
None.gifcategoryfilters.Add(DebugCategory);
None.gif
None.gifCategoryFilter categoryFilter 
=   new  CategoryFilter( " CategoryFilter " , categoryfilters, CategoryFilterMode.AllowAllExceptDenied);
None.gif
None.gif 
None.gif
None.gif
//  加入类别过滤器到集合中
None.gif

None.gifICollection
< ILogFilter >  filters  =   new  List < ILogFilter > ();
了解了这四个对象,其实我们就已经知道了该如何去用编程的方法配置 Logging Application Block,下面给出一个简单的例子,先写一个 MyLogger静态类:
None.gif using  System;
None.gif
None.gif
using  System.Collections.Generic;
None.gif
None.gif
using  System.Diagnostics;
None.gif
None.gif
using  Microsoft.Practices.EnterpriseLibrary.Logging;
None.gif
None.gif
using  Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
None.gif
None.gif
using  Microsoft.Practices.EnterpriseLibrary.Logging.Filters;
None.gif
None.gif
using  Microsoft.Practices.EnterpriseLibrary.Logging.Formatters;
None.gif
None.gif
using  Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners;
None.gif
None.gif
public   static   class  MyLogger
None.gif
ExpandedBlockStart.gif
{
InBlock.gif
InBlock.gif    
static readonly LogWriter _writer;
InBlock.gif
InBlock.gif
InBlock.gif    
// 日至记录的类别
InBlock.gif

InBlock.gif    
const string ErrorCategory = "Error";
InBlock.gif
InBlock.gif    
const string DebugCategory = "Debug";
InBlock.gif
InBlock.gif
InBlock.gif    
// 文本文件的路径
InBlock.gif

InBlock.gif    
const string LogFilePath = @"d:\\share\\messages.log";
InBlock.gif
InBlock.gif
InBlock.gif    
// 模版
InBlock.gif

InBlock.gif    
const string Template = "Timestamp: {timestamp}{newline}" +
InBlock.gif
InBlock.gif                            
"Message: {message}{newline}" +
InBlock.gif
InBlock.gif                            
"Category: {category}{newline}" +
InBlock.gif
InBlock.gif                            
"Machine: {machine}{newline}";
InBlock.gif
InBlock.gif    
static MyLogger()
InBlock.gif
ExpandedSubBlockStart.gif    
{
InBlock.gif
InBlock.gif        
// 实例化一个TextFormatter,使用前面定义的模版
InBlock.gif

InBlock.gif        TextFormatter formatter 
= new TextFormatter
InBlock.gif
InBlock.gif            (Template);
InBlock.gif
InBlock.gif
InBlock.gif        
// 实例化TraceListener,记录到文本文件用FlatFileTraceListener
InBlock.gif

InBlock.gif        FlatFileTraceListener logFileListener 
=
InBlock.gif
InBlock.gif            
new FlatFileTraceListener(LogFilePath,
InBlock.gif
InBlock.gif                                       
"----------",
InBlock.gif
InBlock.gif                                       
"----------",
InBlock.gif
InBlock.gif                                       formatter);
InBlock.gif
InBlock.gif
InBlock.gif        
// 这里是TraceListener的集合,可以增加多个
InBlock.gif

InBlock.gif        LogSource mainLogSource 
=
InBlock.gif
InBlock.gif            
new LogSource("MainLogSource", SourceLevels.All);
InBlock.gif
InBlock.gif        mainLogSource.Listeners.Add(logFileListener);
InBlock.gif
InBlock.gif        IDictionary
<string, LogSource> traceSources = new Dictionary<string, LogSource>();
InBlock.gif
InBlock.gif        traceSources.Add(ErrorCategory, mainLogSource);
InBlock.gif
InBlock.gif        traceSources.Add(DebugCategory, mainLogSource);
InBlock.gif
InBlock.gif        
// 用来表示不记录日志,这点需要注意一下
InBlock.gif

InBlock.gif        LogSource nonExistantLogSource 
= new LogSource("Empty");
InBlock.gif
InBlock.gif
InBlock.gif        
// 创建一个类别过滤器
InBlock.gif

InBlock.gif        ICollection
<string> categoryfilters = new List<string>();
InBlock.gif
InBlock.gif        categoryfilters.Add(DebugCategory);
InBlock.gif
InBlock.gif        CategoryFilter categoryFilter 
= new CategoryFilter("CategoryFilter", categoryfilters, CategoryFilterMode.AllowAllExceptDenied);
InBlock.gif
InBlock.gif
InBlock.gif        
// 加入类别过滤器到集合中
InBlock.gif

InBlock.gif        ICollection
<ILogFilter> filters = new List<ILogFilter>();
InBlock.gif
InBlock.gif        filters.Add(categoryFilter);
InBlock.gif
InBlock.gif
InBlock.gif        _writer 
= new LogWriter(filters,
InBlock.gif
InBlock.gif                        traceSources,
InBlock.gif
InBlock.gif                        nonExistantLogSource,
InBlock.gif
InBlock.gif                        nonExistantLogSource,
InBlock.gif
InBlock.gif                        mainLogSource,
InBlock.gif
InBlock.gif                        ErrorCategory,
InBlock.gif
InBlock.gif                        
false,
InBlock.gif
InBlock.gif                        
true);
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedSubBlockStart.gif    
/// <summary>
InBlock.gif
InBlock.gif    
/// 记录日志信息到Error,默认类别
InBlock.gif
InBlock.gif    
/// </summary>
InBlock.gif
ExpandedSubBlockEnd.gif    
/// <param name="message">日志信息</param>

InBlock.gif
InBlock.gif    
public static void Write(string message)
InBlock.gif
ExpandedSubBlockStart.gif    
{
InBlock.gif
InBlock.gif        Write(message, ErrorCategory);
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedSubBlockStart.gif    
/// <summary>
InBlock.gif
InBlock.gif    
/// 记录日志信息到特定类别
InBlock.gif
InBlock.gif    
/// </summary>
InBlock.gif
InBlock.gif    
/// <param name="message">日志信息</param>
InBlock.gif
ExpandedSubBlockEnd.gif    
/// <param name="category">类别</param>

InBlock.gif
InBlock.gif    
public static void Write(string message, string category)
InBlock.gif
ExpandedSubBlockStart.gif    
{
InBlock.gif
InBlock.gif        LogEntry entry 
= new LogEntry();
InBlock.gif
InBlock.gif 
InBlock.gif
InBlock.gif        entry.Categories.Add(category);
InBlock.gif
InBlock.gif        entry.Message 
= message;
InBlock.gif
InBlock.gif 
InBlock.gif
InBlock.gif        _writer.Write(entry);
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedBlockEnd.gif}
我们再来写一个简单的测试,注意上面的代码中我们过滤掉了 Debug类别的日志信息,这样记录到文本文件中的日志信息应该只有 My Error一条:
None.gif public  partial  class  _Default : System.Web.UI.Page 
None.gif
ExpandedBlockStart.gif
{
InBlock.gif
InBlock.gif    
protected void Page_Load(object sender, EventArgs e)
InBlock.gif
ExpandedSubBlockStart.gif    
{
InBlock.gif
InBlock.gif        MyLogger.Write(
"My Error");
InBlock.gif
InBlock.gif        MyLogger.Write(
"My Debug""Debug");
InBlock.gif
ExpandedSubBlockEnd.gif    }

InBlock.gif
ExpandedBlockEnd.gif}
文本文件中输出的结果为:

----------

Timestamp: 2006-7-8 3:45:05

Message: My Error

Category: Error

Machine: RJ-097

----------

输出的结果与我们设想的一致,使用编程的方法配置Logging Application Block简单的就介绍到这里,你也可以使用这种方法来配置其他的应用程序块。不过使用编程的方法来配置,失去了EL的灵活性,要知道EL的根本思想就是配置驱动,但是如果掌握了这些,也许你能够更好的使用EL,在CodeProject上有人写了一篇《Plug-in Manager for Logging - Configure MSEL2 On the fly》,有兴趣的朋友不妨参考一下。









本文转自lihuijun51CTO博客,原文链接:  http://blog.51cto.com/terrylee/67628 ,如需转载请自行联系原作者


相关实践学习
日志服务之使用Nginx模式采集日志
本文介绍如何通过日志服务控制台创建Nginx模式的Logtail配置快速采集Nginx日志并进行多维度分析。
相关文章