由於這個系列文筆者是以Kong
作為起點,來開始撰寫如何搭配Kong
與所有的節點來完成各式各樣的協作。終於,進入到Kong
的可觀測性實踐了。
本節有關於Kong的設定參考連結如下:
https://developer.konghq.com/plugins/opentelemetry/examples/enable-otel/
首先先注意到docker-compose.yaml
檔案,其中有一段節錄如下:
KONG_TRACING_INSTRUMENTATIONS: all
KONG_TRACING_SAMPLING_RATE: 1.0
在啟用Kong
的可觀測性實踐之前,根據原廠文件會需要將Kong.conf
做幾個調整。kong.conf
是 Kong API Gateway 的主要設定檔,負責定義 Kong
的核心行為與運作參數。一搬來說可以透過修改 kong.conf 來調整 Kong 的網路監聽埠、資料庫連線、日誌、可觀測性、認證、快取等多種功能。而筆者將Kong
實踐在Docker Compose的做法,相關Kong.conf
的設定就會docker-compose.yaml
檔案中。
當完成docker-compose.yaml
中的設定後,接下來就是要調整kong.yml
了,節錄如下:
plugins:
- name: http-log
...中略...
- name: opentelemetry
config:
traces_endpoint: http://opentelemetry-collector:4318/v1/traces
就如同之前有關於Kong
的相關Policy設定一樣,可觀測性的tracing實踐,也是要關注到到ironman2025\case_ELK_Jaeger\1.Kong_declarative\declarative\kong.yml
設定檔,當中有關opentelemetry
Plugin的設定十分簡易。筆者將traces_endpoint 指向Opentelemetry Collector
的http port。
其中 http://opentelemetry-collector:4318/v1/traces
的 URL 是 OpenTelemetry OTLP HTTP 協議的預設 endpoint 路徑。只要 OpenTelemetry Collector 有啟用 OTLP HTTP receiver(像你 otel-collector-config.yaml 裡的設定),它就會自動監聽 4318 port,並且 /v1/traces 這個路徑就是用來收 trace 的,不需要額外設定。
看完了Kong
的相關設定後,接下來關注到程式碼的部分。請關注到ironman2025\case_ELK_Jaeger\2.api_provider\case_with_elk_jaeger\Program.cs
檔案。節錄如下:
以上省略
using OpenTelemetry.Resources;
using OpenTelemetry.Trace;
...中間省略...
var builder = WebApplication.CreateBuilder(args);
// Configure OpenTelemetry Tracing
builder.Services.AddOpenTelemetry()
.ConfigureResource(resource => resource
.AddService(serviceName: builder.Environment.ApplicationName)) // 使用應用程式名稱作為服務名稱
.WithTracing(tracing => tracing
.AddAspNetCoreInstrumentation() // 自動追蹤傳入的 HTTP 請求
.AddHttpClientInstrumentation() // 自動追蹤傳出的 HTTP 請求
.AddRuntimeInstrumentation() // 補充 runtime 層級 trace
.AddOtlpExporter(otlpExporterOptions =>
{
otlpExporterOptions.Endpoint = new Uri("http://opentelemetry-collector:4317"); // 指向 OTel Collector
otlpExporterOptions.Protocol = OpenTelemetry.Exporter.OtlpExportProtocol.Grpc;
}));
上面這段程式碼讓 .NET API 服務自動產生並上報分散式追蹤資料,並且將 trace 資料送到 OpenTelemetry Collector,進而串接 Jaeger、Elasticsearch 等後端,實現完整的可觀測性。
將Kong
與後端API
都共同實踐了可觀測性的trace
概念之後,就可以來進行實驗了!
實驗開始,首先當然要把這次實驗的專案服務一併啟動,請到ironman2025\case_ELK_Jaeger
執行指令如下:
docker compose up -d
當服務都正常起來之後,還是使用Postman
來做API Request的實驗。這次直接連續發出兩個Request,分別是:
apikey
:預期應該會得到http 401
的錯誤。apikey
:預期可以得到http 200
正常取得api內容的回覆。在request
實驗完成後,同樣的還是先透過Kibana
來查錯,看看可不可以看到一些曾經發生過的蛛絲馬跡。
馬上就拿出Kibana
的結果,可以看到就如同實驗的結果,共計兩次,分別是:
讀者請開啟Kibana http://localhost:5601/
401
的錯誤: 這次的401
是因為沒有帶入apikey
,因此造成Kong
就直接回絕了API Request,這表示流量並沒有被往API Provider送過去,可以從圖12-3關注到upstream_status
這個欄位,可以看到下面那一筆(比較早的那一筆)在該欄位是(empty)
的狀態。200
的正確回復: 這次的請求由於有正確的帶入apikey
的認證資訊,因此Kong
就放行這次的請求,並協助做轉傳的工作。同樣的可以從圖12-3關注到upstream_status
這個欄位,最終上游回了200
的正常狀態。
圖12-3 從Log的角度確認請求紀錄
讀者請開啟Jaeger http://localhost:16686/
接下來就是本段落的重頭戲,讓我們進入Jeager
,並將Service
選擇Kong
,從Kong
的進入點開始進行前文兩次的請求。
可以看到圖12-4,可以明顯的看到有兩筆Trace
,筆者簡單說明:
API Key
,因此僅有Kong
的追蹤資訊。也因為處理的時間極短,因此的處理時間的圖,就非常靠近x軸。API Key
,因此這次Kong
有協助轉發到上游,因此該筆追蹤紀錄可以看到除了kong
以外,還多了case_with_elk_jaeger
的追蹤紀錄。同時處理時間由於較久,對照到上方的時間圖就較遠離x軸。
圖12-4
接著來看圖12-5,深入進去看第一次請求失敗的處理追蹤紀錄,可以注意到Kong
在整個請求的過程中,經歷過了好幾個邏輯,包含了kong.route
、plugin.key-auth
以及plugin.opentelemetry
。
圖12-5
再來則是看圖12-6,可以注意到除了Kong
相關的請求有被追蹤執行時間以外,另外由於認證有通過,因此將追蹤傳遞到了上游API,並且同時也將執行與等待的時間都被記錄下來。
圖12-6
追蹤trace
到底是用來做甚麼的呢?就如同面說到的,當執行緩慢的請求被追蹤記錄下來的,當使用者反應速度慢,技術人員不需要從一個個log中查找曾經發生緩慢的紀錄。進而可以從Jaeger
查找在一定時間內,所有執行緩慢的請求處理,進而深入去查找Log
是否有進階的蛛絲馬跡,快速地鎖定問題發生的所在地,進而進行持續的改善。
筆者花了三天的篇幅,來說明有關於透過Kong
與後端API
的trace
實作示範,提供了簡單的範例與說明是如何做到可觀測性中-trace
的實踐。接下來,筆者將在進入可觀測性的第三根支柱,metric
來進行探索。
明天見~