在現今微服務流行的年代相信一定有了解APM,對於APM核心來說是資料來源,一般各自的APM都有對應的元件幫助完成這些工作。如果需要製作自己的APM系統 ,那需要考慮服務程式呼叫埋點問題;在這裡介紹使用BeetleX.Tracks元件進行程式碼埋點,元件基於Activity機制實現,它可以輕鬆方便地對程式碼處理邏輯進行埋點,並可實現跨執行緒跨組呼叫鏈跟蹤記錄,最終過訂閱的方式提交到相應的服務中。
基礎實現
元件通過.NetCore內建Activity物件實現程式碼呼叫鏈記錄,並通過DiagnosticSource物件進行呼叫記錄釋出。這樣做的好處是不管其他元件是不是使用BeetleX.Tracks元件記錄,只要其內部使用Activity即可保持各元件呼叫的關係鏈資訊串連起來達到不同元件都能構建完整跟蹤資訊。
由於Activity和DiagnosticSource是框架內部整合,因此只需要按規則實現即可共享之間程式碼呼叫的關係鏈資料。
使用
在使用元件埋點的時候需要先引用它,可能通過以下地址安裝下載:https://www.nuget.org/packages/BeetleX.Tracks/
安裝元件後你只需要通過以下方式對程式碼進行跟蹤
public async Task Hello() { using (CodeTrackFactory.Track("/Hello", CodeTrackLevel.Bussiness, null)) { var host = new Http.Clients.HttpHost("https://www.baidu.com"); var request = host.Get("/"); var txt = await request.Execute(); await DefaultRedis.Instance.Flushall(); await DefaultRedis.Get<Employee>("nonexisting"); await DefaultRedis.Set("emp3", Northwind.Data.DataHelper.Defalut.Employees[3]); await DefaultRedis.Get<Employee>("emp3"); var wss = new TextClient("wss://echo.websocket.org"); await wss.ReceiveFrom("henry"); } }
通過CodeTrackFactory.Track方法建立一個跟蹤物件,以上示例是建立一個/Hello的跟蹤標籤,等級是Bussiness。沒指定父ID通過元件內部自動獲取上一層的Activity的ID資訊作為父資訊,這個父ID一般用於不同服務程式間互動指定,用於指定當前執行程式碼是由那個服務路由過來;還有一種情況就是跨佇列任務處理難以確定關係的時候也可以顯式指定ID,一般同一程式碼塊下來的都無須指定(即使不同元件間呼叫)。以下是針對上面程式碼的執行效果:
跟蹤標籤
元件提供兩種跟蹤標籤,上面示例用到的Track是一種,它的資訊最終通過訂單來獲取;實際應用中可能在執行完成就需要一個詳細資訊,這個時候就需要TrackReport方法來建立。
using (var track = CodeTrackFactory.TrackReport(actionUrl, CodeTrackLevel.Module, parentID, "HTTP", "Action")) { //.... } Console.Write($"{CodeTrackFactory.Activity.GetReport()}")
以上是建立TrackReport的示例,並在後面把結果列印出來。在上面的使用程式碼中定義TrackReport標籤,在處理完成後即可把完整結果列印出來。由於TrackReport是元件單獨擴充套件的,所以只能把BeetleX.Tracks自己的跟蹤鏈串起來;如果想和其他方式的關係串起來只能自己通過DiagnosticSource訂閱後再自行處理。
跟蹤等級
元件跟蹤分為以下幾個等級
All = 0, Code = 1, Function = 2, Class = 4, Module = 8, Bussiness = 16, Off = 512,
通過等級配置來實現當前的跟蹤資訊是否需要釋出,因此在寫完所有埋點資訊後還可以通過配置來設定那些埋點資訊需要啟用;特別在不同的執行狀態下有些埋點資訊是不需要的。可以通過以下方式配置輸出的埋點資訊級別
public static CodeTrackLevel Level { get; set; } = CodeTrackLevel.Off;
設定級別越低輸出資訊越多,當設定為Off後則所有跟蹤資訊都無效;為了效能上的考慮元件針對不輸出的資訊是不會建立對應的Activity物件也不會發布訂閱資訊,只是一個沒有任何邏輯的Track結構處理。
訂閱
單一程式的跟蹤資料只是一個資料孤島,它存在的作用非常有限;通過訂閱的方式來獲取跟蹤資料並提交到服務上做整合才能發揮其主要作用。
CodeTrackFactory.SubscribeTrack((name, data) =>{ //...});
元件可以通過CodeTrackFactory.SubscribeTrack方法來訂閱相關跟蹤資料,然後加工後傳送到相應的服務上。
多服務關係鏈
一個完整的業務往往需要關聯到多個服務應用,對這個關係的維護只需要在服務之前傳遞個Activity的ParentID即可,每個服務在接管資料處理後只需要把ParentID傳遞給每個建立跟蹤的Activity上即可以實現不同服務的關係鏈引用。
總結
BeetleX.Tracks只針對本地程式埋點,APM整合需要自行訂閱跟蹤資訊併發布到相關伺服器上,在多服務關係鏈處理上需要自動傳遞事件的ParentID用於保證各服務之前的執行關係。由於實現是基於Activity和DiagnosticSource所以無法在.NETFramework上執行。