在現今微服務流行的年代相信一定有了解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上運行。