寫在前面:最近一段時間項目比較緊,所以這篇隨筆出來的晚一些。今天寫的是在日志裡面包含名-值對的字典,跟蹤活動並記錄上下文信息,過濾事件,定制日志消息的格式,自定義Sink,自定義Formatter等。
一.在日志裡面包含名-值對的字典:
在日志消息裡面,我們可以包含名-值對這樣的字典。這時首先需要創建一個Hashtable,通過Key-Value的方式把要記錄的內容傳入。示例代碼如下:
1/**////創建一個日志項
2 LogEntry log = new LogEntry();
3
4 /**////創建名-值對
5 Hashtable logtable = new Hashtable();
6 logtable["key1"] = "value1";
7 logtable["key2"] = "value2";
8 logtable["key3"] = "value3";
9
10 log.Message = this.txt_LogMessage.Text;
11 log.Category = Category.General;
12 log.Priority = Priority.Normal;
13
14 /**////寫入日志
15 Logger.Write(log,logtable);
輸出後的文本:在這裡我們用了Text Formatter
二.跟蹤活動並記錄上下文信息:
跟蹤應用系統的活動是一項常見的功能,我們需要把活動的起始時間和結束時間以及活動的其他的信息記錄下來。日志和監測應用程序塊支持通過活動ID來跟蹤一項活動,活動ID可以在代碼中指定,也可以通過程序塊來自動生成,程序塊自動記錄活動的起始時間和結束時間。活動跟蹤由Tracer類來提供。示例代碼如下:
1using(new Tracer("UI Events"))
2 {
3 Logger.Write("Troubleshooting message");
4 }
輸出後的文本:同樣我們用了Text Formatter
三.過濾事件:
在日志和監測應用程序塊裡面,支持兩種方式的過濾事件:基於優先級過濾事件和基於類別過濾事件。過濾的過程發生在日志項傳遞給分發策略之前。在入門篇裡我們知道,每個日志消息都會有一個優先級,我們可以在代碼中指定或默認值為-1。我們可以通過配置 Client Setting使低於某個優先級的消息被過濾掉,只記錄某個類別的消息或者過濾掉具有某個類別的日志項。
在下面的圖中,日志項為0和1的消息將不被記錄。
Client Setting的CategoryFilterSettings屬性決定某個類別的日志是被記錄還是被過濾掉。我們可以自行進行設置:
在下圖中,”UI Events”類別的日志將不被記錄。
四.定制日志消息的格式:
Formatter接受一個日志項的並返回一個格式化的字符串,應用程序塊格式化將字符串傳給Sink,Text Formatter 使用模版生成格式化字符串,在應用配置中可以有多個 Text Formatters,每個有自己的模版同時我們也可以定制自己的 Formatter。
日志項根據其類別導向到目的地目的地規定了 Formatter 和接收格式化日志項的 Sink。
Text Formatter 有一個模版配置屬性。
模版編輯器定制日志項的格式, {參數}由日志項的值填充。
五.創建和使用自定義Sink:
在日志和監測應用應用程序塊裡面,允許我們自定義一個Sink,而且使用方法要比其它的應用程序塊中的自定義簡單的多。下面我們具體看一下:
1.添加對應用程序塊的引用:
Microsoft.Practices.EnterpriseLibrary.Configuration.dll
Microsoft.Practices.EnterpriseLibrary.Logging.dll
2.添加命名空間:
1using Microsoft.Practices.EnterpriseLibrary.Configuration;
2using Microsoft.Practices.EnterpriseLibrary.Logging;
3using Microsoft.Practices.EnterpriseLibrary.Logging.Sinks;
4using Microsoft.Practices.EnterpriseLibrary.Logging.Distributor.Configuration;
3.編寫代碼:
我們的自定義Sink要繼承LogSink這個基類,同時要重載Initialize()和SendMessageCore()這兩個抽象方法。
1using System;
2using Microsoft.Practices.EnterpriseLibrary.Configuration;
3using Microsoft.Practices.EnterpriseLibrary.Logging;
4using Microsoft.Practices.EnterpriseLibrary.Logging.Sinks;
5using Microsoft.Practices.EnterpriseLibrary.Logging.Distributor.Configuration;
6
7namespace EnterpriseLogging
8{
9 /**//// <summary>
10 /// 功能說明:自定義Sink
11 /// </summary>
12 public class ConsoleSink: LogSink
13 {
14 private LoggingConfigurationView configView;
15
16 public override void Initialize(ConfigurationView configurationView)
17 {
18 this.configView = configurationView as LoggingConfigurationView;
19 }
20
21 protected override void SendMessageCore(LogEntry logEntry)
22 {
23 CustomSinkData sinkData;
24 sinkData = (CustomSinkData) this.configView.GetSinkData(this.ConfigurationName);
25
26 /**//// Delimit each log entry
27 Console.WriteLine((string) sinkData.Attributes["delimiter"]);
28
29 /**//// Write the formatted log entry to the Console
30 Console.WriteLine(FormatEntry(logEntry));
31 }
32 }
33}
34
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.添加如下的命名空間:
1using System.Globalization;
2using System.IO;
3using System.Xml;
4using Microsoft.Practices.EnterpriseLibrary.Configuration;
5using Microsoft.Practices.EnterpriseLibrary.Logging;
6using Microsoft.Practices.EnterpriseLibrary.Logging.Distributor.Configuration;
7using Microsoft.Practices.EnterpriseLibrary.Logging.Formatters;
2.以Hands On Lab裡面的XmlFormatter為例,在自定義Formatter時我們需要繼承ConfigurationProvider類和實現 IlogFormatter接口,並且需要重載Initialize()這個抽象方法。
1using System;
2using System.Globalization;
3using System.IO;
4using System.Xml;
5using Microsoft.Practices.EnterpriseLibrary.Configuration;
6using Microsoft.Practices.EnterpriseLibrary.Logging;
7using Microsoft.Practices.EnterpriseLibrary.Logging.Distributor.Configuration;
8using Microsoft.Practices.EnterpriseLibrary.Logging.Formatters;
9
10namespace LoggingSink
11{
12 /**//// <summary>
13 /// 功能說明:自定義Formatter
14 /// </summary>
15 public class XmlFormatter : ConfigurationProvider, ILogFormatter
16 {
17 private LoggingConfigurationView configView = null;
18
19 public override void Initialize(ConfigurationView configurationView)
20 {
21 this.configView = (LoggingConfigurationView) configurationView;
22 }
23
24 public string Format(LogEntry log)
25 {
26 using (StringWriter sw = new StringWriter(CultureInfo.InvariantCulture))
27 {
28 XmlTextWriter w = new XmlTextWriter(sw);
29 w.Formatting = Formatting.Indented;
30 w.Indentation = 2;
31 w.WriteStartDocument(true);
32 w.WriteStartElement("logEntry");
33 w.WriteAttributeString("Category", log.Category);
34 w.WriteAttributeString("Priority", log.Priority.ToString(CultureInfo.InvariantCulture));
35 w.WriteElementString("Timestamp", log.TimeStampString);
36 w.WriteElementString("Message", log.Message);
37 w.WriteElementString("EventId", log.EventId.ToString(CultureInfo.InvariantCulture));
38 w.WriteElementString("Severity", log.Severity.ToString(CultureInfo.InvariantCulture));
39 w.WriteElementString("Title", log.Title);
40 w.WriteElementString("Machine", log.MachineName);
41 w.WriteElementString("AppDomain", log.AppDomainName);
42 w.WriteElementString("ProcessId", log.ProcessId);
43 w.WriteElementString("ProcessName", log.ProcessName);
44 w.WriteElementString("Win32ThreadId", log.Win32ThreadId);
45 w.WriteElementString("ThreadName", log.ManagedThreadName);
46 w.WriteEndElement();
47 w.WriteEndDocument();
48 return sw.ToString();
49 }
50 }
51 }
52}
53
對於自定義的Formatter我們就介紹到這兒了,它的使用和一般的Formatter沒有大的區別,只不過在創建Formatter時我們需要創建一個Custom Formatter,在這裡我就不多寫了。
結束語:這篇日志和監測應用程序塊的進階篇文章就到這裡了,希望能給初學的朋友一些幫助。後面我會寫緩存應用程序塊的使用。