日志和监测应用程序块——进阶篇(很好,转来收藏)

一.在日志里面包含名-值对的字典:
在日志消息里面,我们可以包含名-值对这样的字典。这时首先需要创建一个Hashtable,通过Key-Value的方式把要记录的内容传入。示例代码如下:



CODE:

///创建一个日志项
            LogEntry log = new LogEntry();
           

            /**////创建名-值对
            Hashtable logtable = new
Hashtable();
            logtable["key1"] = "value1";
           
logtable["key2"] = "value2";
            logtable["key3"] = "value3";
   
       
            log.Message = this.txt_LogMessage.Text;
           
log.Category = Category.General;
            log.Priority =
Priority.Normal;
           
            /**////写入日志
           
Logger.Write(log,logtable);



输出后的文本:在这里我们用了Text Formatter


微软企业库Enterprise Library Step By Step(8) - goodshow - 甲甲
二.跟踪活动并记录上下文信息:
跟踪应用系统的活动是一项常见的功能,我们需要把活动的起始时间和结束时间以及活动的其他的信息记录下来。日志和监测应用程序块支持通过活动ID来跟踪一项活动,活动ID可以在代码中指定,也可以通过程序块来自动生成,程序块自动记录活动的起始时间和结束时间。活动跟踪由Tracer类来提供。示例代码如下:




1微软企业库Enterprise Library Step By Step(8) - goodshow - 甲甲using(new
Tracer(
"UI
Events
"))
2微软企业库Enterprise Library Step By Step(8) - goodshow - 甲甲微软企业库Enterprise Library Step By Step(8) - goodshow - 甲甲            微软企业库Enterprise Library Step By Step(8) - goodshow - 甲甲{
3微软企业库Enterprise Library Step By Step(8) - goodshow - 甲甲                Logger.Write("Troubleshooting message");
4微软企业库Enterprise Library Step By Step(8) - goodshow - 甲甲           
}

输出后的文本:同样我们用了Text Formatter
微软企业库Enterprise Library Step By Step(8) - goodshow - 甲甲
三.过滤事件:
在日志和监测应用程序块里面,支持两种方式的过滤事件:基于优先级过滤事件和基于类别过滤事件。过滤的过程发生在日志项传递给分发策略之前。在入门篇里我们知道,每个日志消息都会有一个优先级,我们可以在代码中指定或默认值为-1。我们可以通过配置
Client
Setting使低于某个优先级的消息被过滤掉,只记录某个类别的消息或者过滤掉具有某个类别的日志项。
在下面的图中,日志项为0和1的消息将不被记录。


微软企业库Enterprise Library Step By Step(8) - goodshow - 甲甲
Client
Setting的CategoryFilterSettings属性决定某个类别的日志是被记录还是被过滤掉。我们可以自行进行设置:


微软企业库Enterprise Library Step By Step(8) - goodshow - 甲甲
在下图中,”UI
Events”类别的日志将不被记录。


微软企业库Enterprise Library Step By Step(8) - goodshow - 甲甲
四.定制日志消息的格式:
Formatter接受一个日志项的并返回一个格式化的字符串,应用程序块格式化将字符串传给Sink,Text
Formatter 使用模版生成格式化字符串,在应用配置中可以有多个 Text Formatters,每个有自己的模版同时我们也可以定制自己的
Formatter。
日志项根据其类别导向到目的地目的地规定了 Formatter 和接收格式化日志项的 Sink。


微软企业库Enterprise Library Step By Step(8) - goodshow - 甲甲
Text Formatter
有一个模版配置属性。


微软企业库Enterprise Library Step By Step(8) - goodshow - 甲甲
模版编辑器定制日志项的格式,
{参数}由日志项的值填充。


微软企业库Enterprise Library Step By Step(8) - goodshow - 甲甲
五.创建和使用自定义Sink:
在日志和监测应用应用程序块里面,允许我们自定义一个Sink,而且使用方法要比其它的应用程序块中的自定义简单的多。下面我们具体看一下:
1.添加对应用程序块的引用:
Microsoft.Practices.EnterpriseLibrary.Configuration.dll
Microsoft.Practices.EnterpriseLibrary.Logging.dll
2.添加命名空间:




1微软企业库Enterprise Library Step By Step(8) - goodshow - 甲甲using
Microsoft.Practices.EnterpriseLibrary.Configuration;
2微软企业库Enterprise Library Step By Step(8) - goodshow - 甲甲using Microsoft.Practices.EnterpriseLibrary.Logging;
3微软企业库Enterprise Library Step By Step(8) - goodshow - 甲甲using
Microsoft.Practices.EnterpriseLibrary.Logging.Sinks;
4微软企业库Enterprise Library Step By Step(8) - goodshow - 甲甲using
Microsoft.Practices.EnterpriseLibrary.Logging.Distributor.Configuration;

3.编写代码:
我们的自定义Sink要继承LogSink这个基类,同时要重载Initialize()和SendMessageCore()这两个抽象方法



CODE:

using System;
using
Microsoft.Practices.EnterpriseLibrary.Configuration;
using
Microsoft.Practices.EnterpriseLibrary.Logging;
using
Microsoft.Practices.EnterpriseLibrary.Logging.Sinks;
using
Microsoft.Practices.EnterpriseLibrary.Logging.Distributor.Configuration;

namespace
EnterpriseLogging
{
    /**//// <summary>
    ///
功能说明:自定义Sink
    /// </summary>
    public class ConsoleSink: 
LogSink
    {
        private LoggingConfigurationView
configView;

        public override void Initialize(ConfigurationView
configurationView)
        {
            this.configView =
configurationView as LoggingConfigurationView;
        }

       
protected override void SendMessageCore(LogEntry logEntry)
        {
     
      CustomSinkData sinkData;
            sinkData = (CustomSinkData)
this.configView.GetSinkData(this.ConfigurationName);

            /**////
Delimit each log entry
            Console.WriteLine((string)
sinkData.Attributes["delimiter"]);

            /**//// Write the
formatted log entry to the Console
           
Console.WriteLine(FormatEntry(logEntry));
        }
   
}
}
[code]

4.打开配置工具,并打开配置文件。在Sink节点上,我们选择Custom Sink。同时起名为Console
Sink:


5.单击TypeName右边的省略号,打开Type Selector对话框。单击Load an Assembly
…,并浏览选择我们工程文件的DLL。最后选择Console Sink类。


6.
单击Attributes
打开NameValueItem
Collection
Editor。单击Add创建一个新的NameValueItem,起名为delimiter,并设置它的Value值(这个值可以随意设置,比如我们设
置************************)。


7.选择General,创建一个Destination,并设置下列属性:
· 
Formatter = Text Formatter,
·  Name = Console Destination
·  Sink =
Console
Sink
8.把程序输出的方式设为控制台的方式,运行程序。
六.创建和使用自定义Formatter:
1.添加如下的命名空间:
[code]using
System.Globalization;
using System.IO;
using System.Xml;
using
Microsoft.Practices.EnterpriseLibrary.Configuration;
using
Microsoft.Practices.EnterpriseLibrary.Logging;
using
Microsoft.Practices.EnterpriseLibrary.Logging.Distributor.Configuration;
using
Microsoft.Practices.EnterpriseLibrary.Logging.Formatters;


2.以Hands
On Lab里面的XmlFormatter为例,在自定义Formatter时我们需要继承ConfigurationProvider类和实现
IlogFormatter接口,并且需要重载Initialize()这个抽象方法。



CODE:

using System;
using System.Globalization;
using System.IO;
using
System.Xml;
using
Microsoft.Practices.EnterpriseLibrary.Configuration;
using
Microsoft.Practices.EnterpriseLibrary.Logging;
using
Microsoft.Practices.EnterpriseLibrary.Logging.Distributor.Configuration;
using
Microsoft.Practices.EnterpriseLibrary.Logging.Formatters;

namespace
LoggingSink
{
    /**////
    /// 功能说明:自定义Formatter
    ///
   
public class XmlFormatter : ConfigurationProvider, ILogFormatter
    {
   
    private LoggingConfigurationView configView = null;

        public
override void Initialize(ConfigurationView configurationView)
        {
 
          this.configView = (LoggingConfigurationView) configurationView;
   
    }

        public string Format(LogEntry log)
        {
       
    using (StringWriter sw = new
StringWriter(CultureInfo.InvariantCulture))
            {
               
XmlTextWriter w = new XmlTextWriter(sw);
                w.Formatting =
Formatting.Indented;
                w.Indentation = 2;
               
w.WriteStartDocument(true);
               
w.WriteStartElement("logEntry");
               
w.WriteAttributeString("Category", log.Category);
               
w.WriteAttributeString("Priority",
log.Priority.ToString(CultureInfo.InvariantCulture));
               
w.WriteElementString("Timestamp", log.TimeStampString);
               
w.WriteElementString("Message", log.Message);
               
w.WriteElementString("EventId",
log.EventId.ToString(CultureInfo.InvariantCulture));
               
w.WriteElementString("Severity",
log.Severity.ToString(CultureInfo.InvariantCulture));
               
w.WriteElementString("Title", log.Title);
               
w.WriteElementString("Machine", log.MachineName);
               
w.WriteElementString("AppDomain", log.AppDomainName);
               
w.WriteElementString("ProcessId", log.ProcessId);
               
w.WriteElementString("ProcessName", log.ProcessName);
               
w.WriteElementString("Win32ThreadId", log.Win32ThreadId);
               
w.WriteElementString("ThreadName", log.ManagedThreadName);
               
w.WriteEndElement();
                w.WriteEndDocument();
             
  return sw.ToString();
            }
        }
   
}
}


对于自定义的Formatter我们就介绍到这儿了,它的使用和一般的Formatter没有大的区别,只不过在创建Formatter时我们需要创建一个Custom
Formatter,在这里我就不多写了。
微软企业库Enterprise Library Step By Step(8) - goodshow - 甲甲
结束语:这篇日志和监测应用程序块的进阶篇文章就到这里了,希望能给初学的朋友一些帮助。后面我会写缓存应用程序块的使用。
posted on 2012-12-03 10:57  罗里罗嗦夫斯基  阅读(305)  评论(0编辑  收藏  举报