圖 14-1
雖說同事嫌筆者上面的架構圖太太太複雜了,但筆者還是想要放一下,因為看起來好像有一點點厲害的樣子(謎之音:圖太複雜就看不懂了)。
經過了昨天docker compose
以及相關服務的設定檔說明之後,接下來就要把要送出監控的那些mertics
實作出來,不然整個架構都完成了之後,沒有任何資料往服務送去,那也只是白搭。
這時候就會注意到一件事情,筆者在談不論是log
、trace
以及metric
,在架構人員協助將這些服務建置起來之後,都需要搭配開發人員協助才能夠完善這些可觀測性的實踐。並不是架構團隊自己將服務架設完成之後,就能夠完成任務的。
不知道讀者有沒有思考過,推行這些服務在組織中要如何進行?過去三年筆者在組織中推行 DevOps 解決方案時,遇過不少的阻力。同樣的,這些可觀測性的實踐,在組織中也會遇到一模一樣的故事。
技術的本質是正向的,目的都是為了系統與服務可以持續在組織中運行,因此才會發展出這些在系統外圍協助的各種技術與平台。
不論是這系列文的三本柱:
log
、trace
、monitor
,或是筆者曾經在組織中推動的ci
(持續整合)與cd
持續交付。其實這些都牽涉到了組織內的文化變革與衝擊,這系列文在最後會用一些篇幅來說明這些可能遇到的問題,以及給出一些建議與想法。現在先讓大家著迷於平台與技術的實踐。
在kong
裡面,要將metrics
資料提供給prometheus
非常的容易,前一天有說到可以透過plugin開啟,就可以讓prometheus
來取得監控資料。請讀者關注到示範專案的kong
設定檔,case_ELK_Jaeger_Promethus_Grafana\1.Kong_declarative\declarative\kong.yml
。其中相關設定如下:
services:
- name: example-service
...
routes:
- name: example-route
...
plugins:
- name: prometheus
config:
status_code_metrics: true
latency_metrics: true
bandwidth_metrics: true
upstream_health_metrics: true
可以注意到,這次開啟的prometheus
plugin,對齊的是services
這一層。這表示這個prometheus
的設定,是在全域生效的。監控資訊的暴露,並不限於任何一個層級。kong
的plugin 雖然可以被套用在global
、services
、routes
、consumers
各個層級,但由於監控這件事情,其實是整個kong
服務,因此這次的設定就對齊services
。
另外kong
的prometheus
plugin應該是在3版以後,提供了更細緻的量測標的。筆者之前也不清楚,在某次升級之後,發現grafana
突然某些監控指標都沒有資料了。翻找原廠文件之後才發現,需要進階的針對希望被蒐集的監控資料開啟,才能夠送去提供監控。
接下來則是要將 API Provider
的部分實踐監控,不然就沒辦法僅有看到kong
的資料,而無法觀測架構中其他服務的狀態,那架構中的監控就會有所缺漏。請讀者參考到示範專案case_ELK_Jaeger_Promethus_Grafana\2.api_provider\case_withelk_jaeger_promethus_grafana\Program.cs
using OpenTelemetry.Metrics; // 新增這行
...中間省略...
builder.Services.AddOpenTelemetry()
.ConfigureResource(resource => resource
...中間省略...
)
.WithMetrics(metrics => metrics
.AddAspNetCoreInstrumentation() // 需 NuGet: OpenTelemetry.Instrumentation.AspNetCore
.AddHttpClientInstrumentation() // 需 NuGet: OpenTelemetry.Instrumentation.Http
.AddRuntimeInstrumentation() // 需 NuGet: OpenTelemetry.Instrumentation.Runtime
.AddProcessInstrumentation()
//.AddPrometheusExporter() // 新增這行以啟用 Prometheus Exporter ,可參考http://localhost/metrics
.AddOtlpExporter(otlpExporterOptions =>
{
otlpExporterOptions.Endpoint = new Uri("http://opentelemetry-collector:4317"); // 指向 OTel Collector
otlpExporterOptions.Protocol = OpenTelemetry.Exporter.OtlpExportProtocol.Grpc;
}));
...中間省略 ...
// 請搭配38行,如果註解取消,新增這一行,註冊 /metrics endpoint
// app.MapPrometheusScrapingEndpoint();
上述這段程式碼範例在API Provider
端,實作了將metrics
資料送往OTEL Collector(http://opentelemetry-collector:4317)
,實作上其實要新增的程式碼並不多。不過可以注意到被筆者註解掉的兩段程式碼,這是在除錯的時候,筆者一直懷疑是不是哪裡寫錯了,導致metrics
的資料沒有被正確的prometheus
。
//.AddPrometheusExporter() // 新增這行以啟用 Prometheus Exporter ,可參考http://localhost/metrics
...中間省略...
// 請搭配38行,如果註解取消,新增這一行,註冊 /metrics endpoint
// app.MapPrometheusScrapingEndpoint();
如果讀者拿到範例程式時,可以把這兩行註解先解開,一樣可以正確執行。也不需特別執行在docker
中,直接執行 dotnet run
來看看效果。
請到
ironman2025\case_ELK_Jaeger_Promethus_Grafana\2.api_provider\case_withelk_jaeger_promethus_grafana\
這層目錄下執行dotnet run
。
圖 14-2 prometheus metrics endpoint
當看到圖 14-2執行成功的畫面,這時候可以透過瀏覽器,執行 http://localhost:5293/metrics
,應該可以看到圖14-3 的畫面。
圖 14-3 metrics的畫面
好吧,筆者認為不是給人類看的畫面。但這個參數的開啟,可以透過/metrics/
的endpoint 確保dotnet
相關的metrics
的程式碼撰寫正確。不然其實在docker compose各個節點中找尋log
也是一門苦工,還是要先從源頭資訊確認是不是程式碼正確地被執行。
目前筆者將需要透過metrics
的兩個服務,都透過程式碼的撰寫或是參數的設定完成。明天筆者將在prometheus
與grafana
來觀看監控否有被正確的執行。
我們明天見~