阅读本文之前,请先阅读:
上一篇中我们介绍了如何去配置Logging Application Block,本文将主要介绍Logging Application Block 的基本操作以及Formatter和Trace Listeners 的自定义方法,首先我们来看如何将一个事件日志写入到一个文本文件中。 假设我们按照上一篇的操作配置了Logging Application Block,那么配置文件中的信息如下: < loggingConfiguration name ="Logging Application Block" tracingEnabled ="true" defaultCategory ="General" logWarningsWhenNoCategoriesMatch ="true" > < listeners > < add fileName ="trace.log" header ="----------------------------------------" footer ="----------------------------------------" formatter ="SHY520 Formatter" listenerDataType ="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.FlatFileTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null" traceOutputOptions ="None" type ="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.FlatFileTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null" name ="SHY520 Listeners" /> < add source ="Enterprise Library Logging" formatter ="Text Formatter" log ="Application" machineName ="" listenerDataType ="Microsoft.Practices.EnterpriseLibrary.Logging.Configuration.FormattedEventLogTraceListenerData, Microsoft.Practices.EnterpriseLibrary.Logging, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null" traceOutputOptions ="None" type ="Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners.FormattedEventLogTraceListener, Microsoft.Practices.EnterpriseLibrary.Logging, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null" name ="Formatted EventLog TraceListener" /> </ listeners > < formatters > < 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} )}" type ="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null" name ="Text Formatter" /> < 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} )}" type ="Microsoft.Practices.EnterpriseLibrary.Logging.Formatters.TextFormatter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null" name ="SHY520 Formatter" /> </ formatters > < logFilters > < add categoryFilterMode ="AllowAllExceptDenied" type ="Microsoft.Practices.EnterpriseLibrary.Logging.Filters.CategoryFilter, Microsoft.Practices.EnterpriseLibrary.Logging, Version=2.0.0.0, Culture=neutral, PublicKeyToken=null" name ="Category Filter" /> </ logFilters > < categorySources > < add switchValue ="All" name ="General" > < listeners > < add name ="SHY520 Listeners" /> </ listeners > </ add > </ categorySources > < specialSources > < allEvents switchValue ="All" name ="All Events" /> < notProcessed switchValue ="All" name ="Unprocessed Category" /> < errors switchValue ="All" name ="Logging Errors & Warnings" > < listeners > < add name ="Formatted EventLog TraceListener" /> </ listeners > </ errors > </ specialSources > </ loggingConfiguration >
下面我们来看如何将日志写入到文本文件: [TestMethod] public void DoLog() { //创建一个日志条目 LogEntry log = new LogEntry(); //指定该日志所属类别 log.Categories.Add("General"); //日志标题 log.Title = "SHY520's Tests"; log.Message = "there is log information"; //优先级 log.Priority = 0; Logger.Write(log); }
上面的代码中,我们为该日志指定所属类别为General,在配置文件中我们可以看到General这个类别使用的Trace Listener是SHY520 Listeners,SHY520 Listeners是一个Flat File Trace Listener,它指定了我们的日志信息输出的地方(trace.log),我用的测试项目,运行测试后,该文件在TestResult/out目录中,如果是一般的Web项目或Consle项目,该文件则在Bin/Debug目录下,下面我们来看一下输出的日志信息:上图中,我们可以看到我们在程序中记录的一些日志信息,我们还可以记录一些额外的信息,这些信息是键值对应的,在1.0版本中我们用Hashtable,这里我们用的是一个泛型的Dictionary类型,代码如下: [TestMethod] public void LoggEntry() { LogEntry log = new LogEntry(); //事件ID log.EventId = 2000; //日志优先级 log.Priority = 2; log.Message = "Test LogEntry 2"; //日志类别 ICollection<string> coll = new List<string>(); coll.Add("General"); log.Categories = coll; //添加额外信息 Dictionary<string, object> dic = new Dictionary<string, object>(); dic.Add("name", "SHY520"); dic.Add("sex","男"); dic.Add("age", "22"); log.ExtendedProperties = dic; //写入日志 Logger.Write(log); }
然后运行测试,在TestResult/Out目录下的trace.log文件中就能看到我们在程序中添加的额外信息了。下面我们来介绍一下过滤器的用法:实现方法很简单,这里我们假设我们已经按照上一篇文章中的方法配置好了一个Category Filter,在Category Filter中我们可以设置要过滤掉哪种类别的事件日志,具体实现方式有两种,如下:方法一: [TestMethod] public void TestFilter1() { LogEntry logEntry = new LogEntry(); logEntry.Priority = 2; logEntry.Categories.Add("General"); //ShouldLog()方法根据Filter配置返回是否需要记录日志 if (Logger.GetFilter<CategoryFilter>().ShouldLog(logEntry.Categories)) { //TODO:记录日志 Logger.Write(logEntry); } }
方法二: [TestMethod] public void TestFilter2() { LogEntry logEntry = new LogEntry(); logEntry.Priority = 2; logEntry.Categories.Add("General"); if (Logger.ShouldLog(logEntry)) { Logger.Write(logEntry); } }
关于事件日志的过滤就说到这里,下面我们来看看如何创建一个自定义的Trace Listener,首先我们新建一个类(MyListener),并且继承与CustomTraceListener,同时不要忘了在为这个新建的类加上[ConfigurationElementType(typeof(CustomTraceListenerData))]的Attribute,最后重写基类的三个方法,在每个方法中加入自己需要的逻辑既可。完整的类的代码如下: using System; using System.Collections.Generic; using System.Text; using Microsoft.Practices.EnterpriseLibrary.Common.Configuration; using Microsoft.Practices.EnterpriseLibrary.Logging.Configuration; using Microsoft.Practices.EnterpriseLibrary.Logging; using Microsoft.Practices.EnterpriseLibrary.Logging.TraceListeners; namespace Enterprise_Library_2 { [ConfigurationElementType(typeof(CustomTraceListenerData))] public class MyListener : CustomTraceListener { public override void TraceData(System.Diagnostics.TraceEventCache eventCache, string source, System.Diagnostics.TraceEventType eventType, int id, object data) { if (data is LogEntry && this.Formatter != null) { this.WriteLine(this.Formatter.Format(data as LogEntry)); } else { this.WriteLine(data.ToString()); } } public override void Write(string message) { //TODO:添加自己所需的逻辑 } public override void WriteLine(string message) { //TODO:添加自己所需的逻辑 } }}
然后我们在配置Trace Listener的时候选择Custom Trace Listener就可以了。 接下来我们来看看如何自定义Formatter,实现的方法和上面类似,首先新建一个类MyFormatter,继承ILogFormatter接口,同时加上[ConfigurationElementType(typeof(CustomFormatterData))]的Attribute,完整的代码如下:
using System; using System.Collections.Generic; using System.Text; using System.Collections.Specialized; using Microsoft.Practices.EnterpriseLibrary.Common.Configuration; using Microsoft.Practices.EnterpriseLibrary.Logging.Configuration; using Microsoft.Practices.EnterpriseLibrary.Logging; using Microsoft.Practices.EnterpriseLibrary.Logging.Formatters; namespace Enterprise_Library_2 { [ConfigurationElementType(typeof(CustomFormatterData))] public class MyFormatter : ILogFormatter { public MyFormatter(NameValueCollection nv) { //注意:构造函数的参数必须是NameValueCollection类型的 } public string Format(LogEntry log) { string result = string.Empty; //TODO:此处添加我们个性化的Formatter逻辑 return result; } }}
到这里,关于Logging Application Block的有关问题已经都简单的介绍了一下,有遗漏错误的地方,请指正,谢谢! 希望对初学者有所帮助,同时也欢迎Enterprise Library学习者一起共同交流经验。
Email :