學(xué)習(xí),也是一個(gè)總結(jié)的過(guò)程,對(duì)此,我們也許可以總結(jié)出來(lái)一個(gè)比較重要的信息就是:通過(guò) Diagnostics 的命名空間變化,由 Microsoft 變?yōu)榱?System, 我們可以看到 Diagnostics 對(duì)于我們的應(yīng)用程序來(lái)說(shuō)變得更加重要了。
由于 EventSource 只支持 Windows,所以在全新的 .NET Core 中,它已經(jīng)被悄悄的取代了,下面我們來(lái)看一下全新的 DiagnosticSource。
在 .NET Core 中 .NET 團(tuán)隊(duì)設(shè)計(jì)了一個(gè)全新的?DiagnosticSource,新的?DiagnosticSource?非常的簡(jiǎn)單,它允許你在生產(chǎn)環(huán)境記錄豐富的 payload 數(shù)據(jù),然后你可以在另外一個(gè)消費(fèi)者可以消費(fèi)感興趣的記錄,是不是聽(tīng)著有點(diǎn)懵逼?沒(méi)關(guān)系,等會(huì)我再詳細(xì)說(shuō)。
我們先來(lái)說(shuō)說(shuō)?DiagnosticSource?和上面的?EventSource?的區(qū)別,他們的架構(gòu)設(shè)計(jì)有點(diǎn)類(lèi)似,主要區(qū)別是?EventSource?它記錄的數(shù)據(jù)是可序列化的數(shù)據(jù),會(huì)被在進(jìn)程外消費(fèi),所以要求記錄的對(duì)象必須是可以被序列化的。而?DiagnosticSource?被設(shè)計(jì)為在進(jìn)程內(nèi)處理數(shù)據(jù),所以通過(guò)它可以拿到更加豐富的一些數(shù)據(jù)信息,它支持非序列化的對(duì)象,比如?HttpContext?,?HttpResponseMessage?等。如果你想在?EventSource?中獲取?DiagnosticSource?中的事件數(shù)據(jù),你可以通過(guò)?DiagnosticSourceEventSource?這個(gè)對(duì)象來(lái)進(jìn)行數(shù)據(jù)橋接。
下面我們來(lái)看一下在代碼中如何使用?DiagnosticSource對(duì)象。
在這之前我們需要了解另外一個(gè)對(duì)象?DiagnosticListener,DiagnosticListener?從命名上來(lái)看它是一個(gè)監(jiān)聽(tīng)診斷信息的對(duì)象,它確實(shí)是一個(gè)用來(lái)接收事件的類(lèi),在 .NET Core 中?DiagnosticSource?它其實(shí)是一個(gè)抽象類(lèi),定義了記錄事件日志所需要的方法,那么我們?cè)谑褂玫臅r(shí)候就需要使用具體的對(duì)象,DiagnosticListener?就是?DiagnosticSource?的默認(rèn)實(shí)現(xiàn),明白了吧。
好了,現(xiàn)在我們來(lái)看一下如何使用吧。
生成 Diagnostic 日志記錄
如何生成 Diagnostic 日志記錄呢?首先,我們需要?jiǎng)?chuàng)建一個(gè)?DiagnosticListener?對(duì)象,比如:
privatestaticDiagnosticSource httpLogger =newDiagnosticListener("System.Net.Http");
DiagnosticListener?參數(shù)中的名稱即為需要監(jiān)聽(tīng)的事件(組件)名稱,這個(gè)名稱在以后會(huì)被用來(lái)被它的消費(fèi)者所訂閱使用。
DiagnosticSource?其核心只包含了兩個(gè)方法,分別是 :
boolIsEnabled(stringname)voidWrite(stringname,objectvalue);
那么然后我們可以這樣來(lái)調(diào)用:
if(httpLogger.IsEnabled("RequestStart")){? ? httpLogger.Write("RequestStart",new{ Url="http://clr", Request=aRequest });}
IsEnabled(string param1)?這個(gè)方法用來(lái)判斷是否有消費(fèi)者注冊(cè)了當(dāng)前的事件(組件)名稱監(jiān)聽(tīng),通常有消費(fèi)者關(guān)心了相關(guān)數(shù)據(jù),我們才會(huì)進(jìn)行事件記錄。
Write(string param1,object param2)?這個(gè)方法用來(lái)向 DiagnosticSource 中寫(xiě)入日志記錄,param1?和上面一樣用來(lái)指定名稱的,也就是所向指定名稱中寫(xiě)入數(shù)據(jù),param2?即為寫(xiě)入的 payloads 數(shù)據(jù),你可以使用 匿名類(lèi)型來(lái)向?param2?中寫(xiě)入數(shù)據(jù),這樣會(huì)方便很多。
這樣,我們就已經(jīng)把 Diagnostic 事件日志寫(xiě)入到 DiagnosticSource中了,是不是很簡(jiǎn)單? 我們?cè)倏匆幌氯绾芜M(jìn)行消費(fèi)(監(jiān)聽(tīng))這些事件信息。
監(jiān)聽(tīng) Diagnostic 日志記錄
在監(jiān)聽(tīng) Diagnostic 日志記錄之前你需要知道你要關(guān)心的事件數(shù)據(jù)名稱,那么如果僅僅是在代碼中把?DiagnosticListeners?都寫(xiě)死到監(jiān)聽(tīng)的消費(fèi)者代碼中的話,這樣就太不靈活了,所以這里設(shè)計(jì)了一個(gè)機(jī)制用來(lái)發(fā)現(xiàn)中那些在運(yùn)行時(shí)被激活的DiagnosticListeners。
你可以使用?DiagnosticListener.AllListeners?來(lái)獲取一個(gè)?IObservable對(duì)象,IObservable接口大家應(yīng)該都不陌生了吧,然后通過(guò)其Subscribe方法進(jìn)行OnNext“回調(diào)”關(guān)心的事件數(shù)據(jù)。
