• Enterprise Library 2.0 Logging Application Block (下)


            阅读本文之前,请先阅读:Enterprise Library 2.0 -- Logging Application Block (上) 
           上一篇中我们介绍了如何去配置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 &amp; 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<stringobject> dic = new Dictionary<stringobject>();
                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 : pwei013@163.com

  • 相关阅读:
    比特币的加密算法
    区块链项目-Lisk
    以太坊(二)
    以太坊的货币发行模式
    以太坊(一)
    前端er们如何最快开发h5移动端页面?
    jQuery Ajax常用总结
    js中变量作用域
    网页引入特殊字体的几种方案
    几个有趣的WEB设备API(二)
  • 原文地址:https://www.cnblogs.com/pw/p/419991.html
Copyright © 2020-2023  润新知