--- tags: Serilog, APM --- # Elastic APM 與 Serilog 整合 ### 前言 Serilog是一個使用於C#的結構化日誌套件,此套件可以很方便且快速的紀錄運行的相關資訊,也具有很高的擴充性可讓使用者自行定義要記錄的重要指標並且可以輕鬆的輸出到指定位置,不論是檔案或是命令列或是其他遠端伺服器。 [TOC] ### 目標 將APM運作紀錄的TrnasctionID與TraceID整合進Serilog的log中,可以很方便地讓日誌中包含APM運作的ID值,可以幫助使用者整合運作紀錄與效能紀錄的資料,不需要使用多個服務來比對跟尋找特定資料的完整效能與日誌紀錄。 ### 概觀 APM與Serilog都是協助開發與維護團隊辨識、分析、找出問題的工具,但是紀錄內容並沒有完全的重疊,兩種工具都是為了各自需要的指標進行紀錄,不過我們可以在兩種紀錄中設置重疊的資料,並且將兩份資料做整合,這樣可以在必要時快速的鎖定問題! - APM與Serilog分別記錄的訊息  - APM與Serilog關聯的資料  ### 使用工具 關於Elastic APM與ZeroC Ice相關介紹可以參考[此份文件](https://hackmd.io/LbZl8PRpS7K4O-2SVArQWA) 1. [Serilog](https://serilog.net/) - [結構化日誌紀錄](https://messagetemplates.org/),易於設置並且具有簡潔的API提供使用者操作 2. [Elastic APM](https://www.elastic.co/guide/en/apm/get-started/current/index.html)(以下簡稱APM) - Elastic APM為一款基於Elastic Stack建構的APM(Application performance management)服務,用途為收集有關傳入請求,數據庫查詢,對緩存的調用,外部HTTP請求等的響應時間的詳細性能信息。這樣可以輕鬆快速地找出並解決性能問題 3. [ZeroC Ice](https://doc.zeroc.com/)(被記錄作業,不一定用在此中間件上) - Zeroc ICE ( Internet Communications Engine ),一個物件導向式的RPC(Remote Procedure Call)框架,支持不同語言間的服務調用,使用Ice統一調用語言Slice定義服務接口並轉換成對應語言並實作其應用邏輯之後由Ice保證資料通訊的安全與可靠性 ### 實現過程 Serilog中提供了 Enrich介面可供開發者自訂在建立 ILogger對象時要附加在日誌訊息中的自訂內容(hash、ID、Location...其他需要的資訊),Elastic APM也有針對 Serilog提供了Enrich擴充套件,直接從Nuget安裝後在啟動ILogger時加入此Enrich即可在日誌中自動載入當前 TransactionID、TraceID資訊。 - 運作過程: 1. 於業務邏輯Task開始前初始化APM 2. 於業務邏輯Task開始時初始化Serilog、啟動APM Transaction、啟動APM Span 3. 於任務中需要紀錄位置加上Log紀錄,並且在此Log中加入此Task的APM TransactionID、TraceID等資料 4. 業務邏輯如果有需要呼叫其他業務邏輯,將APM Distribute tracing data傳遞過去 5. 業務邏輯結束前結束Span、Transaction、視需要寫入Log、結束Serilog ### 測試紀錄 - APM有針對Serilog製作Enrich擴充、其中使用的方式則是直接使用其API取得當前`CurrentTransactionID`與`CurrentTraceID`等值,其原始碼如下: ``` public sealed class ElasticApmEnricher : ILogEventEnricher { public void Enrich(LogEvent logEvent, ILogEventPropertyFactory propertyFactory) { if (!Agent.IsConfigured) return; if (Agent.Tracer?.CurrentTransaction == null) return; logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty( "ElasticApmTransactionId", Agent.Tracer.CurrentTransaction.Id)); logEvent.AddPropertyIfAbsent(propertyFactory.CreateProperty( "ElasticApmTraceId", Agent.Tracer.CurrentTransaction.TraceId)); } } ``` 經過測試,使用在Async的Task中不會發生資料異常 ### 問題紀錄 [動態產生 Serilog Github討論](https://github.com/serilog/serilog/issues/714) 目前沒有看到可以動態產生ILogger的方式,目前唯一能產生ILogger的方式只有靜態的`new LoggerConfiguration()`,產生後也沒辦法更改其配置,如果要彈性的針對各任務設置指定配置,只能夠在該任務開始跟結束各自設定ILogger ### 如何解決/待解決 ### Q&A
×
Sign in
Email
Password
Forgot password
or
By clicking below, you agree to our
terms of service
.
Sign in via Facebook
Sign in via Twitter
Sign in via GitHub
Sign in via Dropbox
Sign in with Wallet
Wallet (
)
Connect another wallet
New to HackMD?
Sign up