Enterprise Library 2.0 -- Logging Application Block

   Enterprise Library 2.0 中的 Logging Application Block 在1.0版本中是Logging and Instrumentation Application Block,因为把重点放在了日志记录上,所以改名为Logging Application Block。Logging Application Block提供了统一的日志记录功能,它支持将日志写入到多种目的地中,比如:
1、数据库;
2、文本文件;
3、Email;
4、消息队列;
5、WMI event;
6、事件日志;
7、自定义区域(For Example:XML File)

  等等。
   Logging Application Block 提供了统一的接口用于将日志写入到任何指定的目的地,我们不需要在代码中指定日志信息该写到什么地方,而是在配置文件中设定我们什么情况下写日志以及将日志信息写到什么地方,这也就意味着操作员可以和我们开发人员一样不通过修改代码来改变日志记录行为。它对于我们程序开发有以下几点好处:
1、可以使我们的应用程序中的日志记录方法保持一致;
2、正是因为它提供一致的结构模型,很大程度上方便了我们开发人员对其的学习;
3、很好的解决了应用程序中的日志问题;
4、可扩展,我们可以自定义日志信息的过滤程序以及格式化日志信息的程序
... ...

   相对于上一个版本,Logging Application Block 2.0作出了下列改变:
1、LogEntry对象现在可以属于一个或多个类别(category);
2、2.0版本中我们可以自定义过滤器,在Logging Application Block 将日志信息发送给监听器(trace listeners)之前就将该信息过滤掉,过滤器支持我们根据事件的类别和(或)优先级来过滤事件,我们可以定制符合自己需要的标准的过滤器来过滤事件;
3、你可以在代码中通过查询过滤器来判断当前事件是否需要被记录日志,这样就大大减少了我们日志记录量,可以有效的提高应用程序的性能。

   下面我们就来说一下Logging Application Block的使用方法,首先需要添加对下面三个程序集的引用:

None.gif using  Microsoft.Practices.EnterpriseLibrary.Logging;
None.gif
using  Microsoft.Practices.EnterpriseLibrary.Logging.ExtraInformation;
None.gif
using  Microsoft.Practices.EnterpriseLibrary.Logging.Filters;

      和前面几个Block一样,在使用之前还是先说一下配置方法,首先用配置工具代开我们程序的App.Config/Web.Config,然后选中Application右键,New-->Logging Application Block,如下图:


这时你会发现,在新建的Logging Application Block节点下自动出现了Filters,Category Source,Special Source,Trace Listeners,Formatters这样的几个节点,如下:


      我下面按照我配置的顺序来说一下每个节点的作用,首先是Formatters,它用于指定日志信息的格式,如下图,我们在Formatters节点下创建一个Text Formatter,如下:


然后我们可以编辑它的模板,编辑我们要显示的信息,如下:



我们还可以配置Binary Formatter和自定义的Formatter ,这里不在多说了。

       Formatter配置好了以后,我们就可以来配置Trace Listeners了,Enterprise Library 2.0 提供了七种Trace Listeners,分别用于将日志信息记录到特定的目的地中,下面我们就来配置一个Flat File Trace Listener ,如下:



        使用Flat File Trace Listener后,记录的日志信息就输出到指定的文本文件中,所以我们要指定输出的文本文件的路径,默认在Bin/Debug目录下;同时我们需指定该Listener的Formatter,Name等属性。如果我们配置的是一个DataBase Listener,我们则要在数据库中建立相应的表,并创建一个用于插入日志信息的存储过程。


Trace Listeners 配置好之后就可以开始配置Category Source,我们新建一个Category Source,命名为General,指定其SourceLevel为All,如下:



之后,我们可以对刚添加的Category Source添加一个或多个Trace Listener,本文中,我们将上面配置的SHY52O Formatter加进来,


         如上图,在RefrenceTraceListener中选择SHY520 Listeners就可以了。
         最后我们来看一下如何配置过滤器(Filters),Enterprise Library 2.0 中提供了三种默认的Filters,分别是:Category Filter ,Log Enable Filter和Priority Filter,我们以Category Filter为例来配置:


然后可以修改过滤器名称和过滤规则:



这里面我们可以选择过滤的模式,过滤模式有两种:
1、Allow All Categories Except those explicitly denied below
2、Deny All Categories Except those explicitly allowed below

根据我们需要选择好过滤模式,然后添加需要过滤的类别,点击OK按钮即可完成Category Filter的配置。

    前面我们介绍了如何去配置Logging Application Block,接下来将主要介绍Logging Application Block 的基本操作以及Formatter和Trace Listeners 的自定义方法,首先我们来看如何将一个事件日志写入到一个文本文件中。
    假设我们按照上一篇的操作配置了Logging Application Block,那么配置文件中的信息如下:

None.gif    < loggingConfiguration  name ="Logging Application Block"  tracingEnabled ="true"
None.gif    defaultCategory
="General"  logWarningsWhenNoCategoriesMatch ="true" >
None.gif    
< listeners >
None.gif      
< add  fileName ="trace.log"  header ="****************************************"
None.gif        footer
="****************************************"  formatter ="ryb Formatter"
None.gif        listenerDataType
="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.FlatFileTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null"
None.gif        traceOutputOptions
="None"  type ="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.FlatFileTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null"
None.gif        name
="FlatFile TraceListener"   />
None.gif      
< add  source ="Enterprise Library Logging"  formatter ="ryb Formatter"
None.gif        log
="Application"  machineName =""  listenerDataType ="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.FormattedEventLogTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null"
None.gif        traceOutputOptions
="None"  type ="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.FormattedEventLogTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null"
None.gif        name
="Formatted EventLog TraceListener"   />
None.gif      
< add  source ="Enterprise Library Logging"  formatter ="ryb Formatter"
None.gif        log
="Application"  machineName =""  listenerDataType ="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.FormattedEventLogTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null"
None.gif        traceOutputOptions
="None"  type ="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.FormattedEventLogTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null"
None.gif        name
="Formatted EventLog TraceListener1"   />
None.gif    
</ listeners >
None.gif    
< formatters >
None.gif      
< add  template ="Timestamp: {timestamp} Message: {message} Category: {category} Priority: {priority} EventId: {eventid} Severity: {severity} Title:{title} Machine: {machine} Application Domain: {appDomain} Process Id: {processId} Process Name: {processName} Win32 Thread Id: {win32ThreadId} Thread Name: {threadName} Extended Properties: {dictionary({key} - {value} )}"
None.gif        type
="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null"
None.gif        name
="Text Formatter"   />
None.gif      
< add  template ="Timestamp: {timestamp} Message: {message} Category: {category} Priority: {priority} EventId: {eventid} Severity: {severity} Title:{title} Machine: {machine} Application Domain: {appDomain} Process Id: {processId} Process Name: {processName} Win32 Thread Id: {win32ThreadId} Thread Name: {threadName} Extended Properties: {dictionary({key} - {value} )}"
None.gif        type
="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null"
None.gif        name
="ryb Formatter"   />
None.gif    
</ formatters >
None.gif    
< categorySources >
None.gif      
< add  switchValue ="All"  name ="General" >
None.gif        
< listeners >
None.gif          
< add  name ="Formatted EventLog TraceListener1"   />
None.gif        
</ listeners >
None.gif      
</ add >
None.gif    
</ categorySources >
None.gif    
< specialSources >
None.gif      
< allEvents  switchValue ="All"  name ="All Events"   />
None.gif      
< notProcessed  switchValue ="All"  name ="Unprocessed Category"   />
None.gif      
< errors  switchValue ="All"  name ="Logging Errors &amp; Warnings" >
None.gif        
< listeners >
None.gif          
< add  name ="Formatted EventLog TraceListener"   />
None.gif        
</ listeners >
None.gif      
</ errors >
None.gif    
</ specialSources >
None.gif  
</ loggingConfiguration >
None.gif

下面我们来看如何将日志写入到文本文件:
None.gif         [TestMethod]
None.gif        
public   void  DoLog()
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif {
InBlock.gif            
//创建一个日志条目
InBlock.gif
            LogEntry log = new LogEntry();
InBlock.gif            
//指定该日志所属类别
InBlock.gif
            log.Categories.Add("General");
InBlock.gif            
//日志标题
InBlock.gif
            log.Title = "SHY520's Tests";
InBlock.gif            log.Message 
= "there is log information";
InBlock.gif            
//优先级
InBlock.gif
            log.Priority = 0;
InBlock.gif
InBlock.gif            Logger.Write(log);
ExpandedBlockEnd.gif        }
     上面的代码中,我们为该日志指定所属类别为General,在配置文件中我们可以看到General这个类别使用的Trace Listener是SHY520 Listeners,SHY520 Listeners是一个Flat File Trace Listener,它指定了我们的日志信息输出的地方(trace.log),我用的测试项目,运行测试后,该文件在TestResult/out目录中,如果是一般的Web项目或Consle项目,该文件则在Bin/Debug目录下,下面我们来看一下输出的日志信息:


上图中,我们可以看到我们在程序中记录的一些日志信息,我们还可以记录一些额外的信息,这些信息是键值对应的,在1.0版本中我们用Hashtable,这里我们用的是一个泛型的Dictionary类型,代码如下:

None.gif         [TestMethod]
None.gif        
public   void  LoggEntry()
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif {
InBlock.gif            LogEntry log 
= new LogEntry();
InBlock.gif            
//事件ID
InBlock.gif
            log.EventId = 2000;
InBlock.gif            
//日志优先级
InBlock.gif
            log.Priority = 2;
InBlock.gif            log.Message 
= "Test LogEntry 2";
InBlock.gif
InBlock.gif            
//日志类别
InBlock.gif
            ICollection<string> coll = new List<string>();
InBlock.gif            coll.Add(
"General");
InBlock.gif            log.Categories 
= coll;
InBlock.gif
InBlock.gif            
//添加额外信息
InBlock.gif
            Dictionary<stringobject> dic = new Dictionary<stringobject>();
InBlock.gif            dic.Add(
"name""SHY520");
InBlock.gif            dic.Add(
"sex","");
InBlock.gif            dic.Add(
"age""22");
InBlock.gif
InBlock.gif            log.ExtendedProperties 
= dic;
InBlock.gif            
//写入日志
InBlock.gif
            Logger.Write(log);
ExpandedBlockEnd.gif        }
然后运行测试,在TestResult/Out目录下的trace.log文件中就能看到我们在程序中添加的额外信息了。



下面我们来介绍一下过滤器的用法:
实现方法很简单,这里我们假设我们已经按照上一篇文章中的方法配置好了一个Category Filter,在Category Filter中我们可以设置要过滤掉哪种类别的事件日志,具体实现方式有两种,如下:
方法一:
None.gif         [TestMethod]
None.gif        
public   void  TestFilter1()
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif {
InBlock.gif            LogEntry logEntry 
= new LogEntry();
InBlock.gif            logEntry.Priority 
= 2;
InBlock.gif            logEntry.Categories.Add(
"General");
InBlock.gif
InBlock.gif            
//ShouldLog()方法根据Filter配置返回是否需要记录日志
InBlock.gif
            if (Logger.GetFilter<CategoryFilter>().ShouldLog(logEntry.Categories))
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
//TODO:记录日志
InBlock.gif
                Logger.Write(logEntry);
ExpandedSubBlockEnd.gif            }

ExpandedBlockEnd.gif        }
方法二:
None.gif         [TestMethod]
None.gif        
public   void  TestFilter2()
ExpandedBlockStart.gifContractedBlock.gif        
dot.gif {
InBlock.gif            LogEntry logEntry 
= new LogEntry();
InBlock.gif            logEntry.Priority 
= 2;
InBlock.gif            logEntry.Categories.Add(
"General");
InBlock.gif
InBlock.gif            
if (Logger.ShouldLog(logEntry))
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                Logger.Write(logEntry);
ExpandedSubBlockEnd.gif            }

ExpandedBlockEnd.gif        }

        关于事件日志的过滤就说到这里,下面我们来看看如何创建一个自定义的Trace Listener,首先我们新建一个类(MyListener),并且继承与CustomTraceListener,同时不要忘了在为这个新建的类加上[ConfigurationElementType(typeof(CustomTraceListenerData))]的Attribute,最后重写基类的三个方法,在每个方法中加入自己需要的逻辑既可。完整的类的代码如下:
None.gif using  System;
None.gif
using  System.Collections.Generic;
None.gif
using  System.Text;
None.gif
using  Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
None.gif
using  Microsoft.Practices.EnterpriseLibrary.Logging.Configuration;
None.gif
using  Microsoft.Practices.EnterpriseLibrary.Logging;
None.gif
using  Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners;
None.gif
None.gif
namespace  Enterprise_Library_2
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    [ConfigurationElementType(
typeof(CustomTraceListenerData))]
InBlock.gif    
public class MyListener : CustomTraceListener
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
public override void  TraceData(System.Diagnostics.TraceEventCache eventCache, string source, System.Diagnostics.TraceEventType eventType, int id, 
InBlock.gif
InBlock.gif
object data)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
if (data is LogEntry && this.Formatter != null)
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
this.WriteLine(this.Formatter.Format(data as LogEntry));
ExpandedSubBlockEnd.gif            }

InBlock.gif            
else
ExpandedSubBlockStart.gifContractedSubBlock.gif            
dot.gif{
InBlock.gif                
this.WriteLine(data.ToString());
ExpandedSubBlockEnd.gif            }

ExpandedSubBlockEnd.gif        }

InBlock.gif
InBlock.gif
InBlock.gif        
public override void Write(string message)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
//TODO:添加自己所需的逻辑
ExpandedSubBlockEnd.gif
        }

InBlock.gif
InBlock.gif        
public override void WriteLine(string message)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
//TODO:添加自己所需的逻辑
ExpandedSubBlockEnd.gif
        }

ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}
然后我们在配置Trace Listener的时候选择Custom Trace Listener就可以了。

接下来我们来看看如何自定义Formatter,实现的方法和上面类似,首先新建一个类MyFormatter,继承ILogFormatter接口,同时加上[ConfigurationElementType(typeof(CustomFormatterData))]的Attribute,完整的代码如下:

None.gif using  System;
None.gif
using  System.Collections.Generic;
None.gif
using  System.Text;
None.gif
using  System.Collections.Specialized;
None.gif
using  Microsoft.Practices.EnterpriseLibrary.Common.Configuration;
None.gif
using  Microsoft.Practices.EnterpriseLibrary.Logging.Configuration;
None.gif
using  Microsoft.Practices.EnterpriseLibrary.Logging;
None.gif
using  Microsoft.Practices.EnterpriseLibrary.Logging.Formatters;
None.gif
None.gif
namespace  Enterprise_Library_2
ExpandedBlockStart.gifContractedBlock.gif
dot.gif {
InBlock.gif    [ConfigurationElementType(
typeof(CustomFormatterData))]
InBlock.gif    
public class MyFormatter : ILogFormatter    
ExpandedSubBlockStart.gifContractedSubBlock.gif    
dot.gif{
InBlock.gif        
public MyFormatter(NameValueCollection nv)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
//注意:构造函数的参数必须是NameValueCollection类型的
ExpandedSubBlockEnd.gif
        }

InBlock.gif
InBlock.gif        
public string Format(LogEntry log)
ExpandedSubBlockStart.gifContractedSubBlock.gif        
dot.gif{
InBlock.gif            
string result = string.Empty;
InBlock.gif
InBlock.gif            
//TODO:此处添加我们个性化的Formatter逻辑
InBlock.gif

InBlock.gif            
return result;
ExpandedSubBlockEnd.gif        }

ExpandedSubBlockEnd.gif    }

ExpandedBlockEnd.gif}

转载于:https://www.cnblogs.com/ryb/archive/2006/11/14/560015.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值