用 Go 編寫的 HTTP 伺服器儀表化
在本教程中,我們將建立一個簡單的 Go HTTP 伺服器,並透過新增一個計數器指標來對其進行儀表化,以統計伺服器處理的總請求數。
這裡我們有一個簡單的 HTTP 伺服器,其中包含一個 `/ping` 端點,該端點返回 `pong` 作為響應。
package main
import (
"fmt"
"net/http"
)
func ping(w http.ResponseWriter, req *http.Request) {
fmt.Fprintf(w,"pong")
}
func main() {
http.HandleFunc("/ping", ping)
http.ListenAndServe(":8090", nil)
}
編譯並執行伺服器
go build server.go
./server
現在在瀏覽器中開啟 `https://:8090/ping`,您應該會看到 `pong`。
現在,讓我們向伺服器新增一個指標,該指標將用於統計對 ping 端點的請求數量。計數器指標型別非常適合此目的,因為我們知道請求計數只會增加而不會減少。
建立一個 Prometheus 計數器
type metrics struct {
pingCounter prometheus.Counter
}
func newMetrics(reg prometheus.Registerer) *metrics {
m := &metrics{
pingCounter: promauto.With(reg).NewCounter(
prometheus.CounterOpts {
Name: "ping_request_count",
Help: "No of requests handled by Ping handler",
}),
}
return m
}
接下來,讓我們更新 ping 處理程式,使用 `metrics.pingCounter.Inc()` 來增加計數器的計數。
func ping(m *metrics) func(w http.ResponseWriter, req *http.Request) {
return func(w http.ResponseWriter, req *http.Request) {
m.pingCounter.Inc()
fmt.Fprintf(w, "pong")
}
}
然後將指標(在本例中,只有一個計數器)註冊到 Prometheus 登錄檔並暴露這些指標。
func main() {
reg := prometheus.NewRegistry()
m := newMetrics(reg)
http.HandleFunc("/ping", ping(m))
http.Handle("/metrics", promhttp.HandlerFor(reg, promhttp.HandlerOpts{}))
http.ListenAndServe(":8090", nil)
}
`prometheus.MustRegister` 函式將 pingCounter 註冊到預設登錄檔。為了暴露指標,Go Prometheus 客戶端庫提供了 promhttp 包。`promhttp.Handler()` 提供了一個 `http.Handler`,用於暴露在預設登錄檔中註冊的指標。
示例程式碼現在是
package main
import (
"fmt"
"net/http"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
type metrics struct {
pingCounter prometheus.Counter
}
func newMetrics(reg prometheus.Registerer) *metrics {
m := &metrics{
pingCounter: promauto.With(reg).NewCounter(
prometheus.CounterOpts{
Name: "ping_request_count",
Help: "No of request handled by Ping handler",
}),
}
return m
}
func ping(m *metrics) func(w http.ResponseWriter, req *http.Request) {
return func(w http.ResponseWriter, req *http.Request) {
m.pingCounter.Inc()
fmt.Fprintf(w, "pong")
}
}
func main() {
reg := prometheus.NewRegistry()
m := newMetrics(reg)
http.HandleFunc("/ping", ping(m))
http.Handle("/metrics", promhttp.HandlerFor(reg, promhttp.HandlerOpts{}))
http.ListenAndServe(":8090", nil)
}
執行示例
go mod init prom_example
go mod tidy
go run server.go
現在訪問 localhost:8090/ping 端點幾次,然後向 localhost:8090/metrics 傳送請求以檢視指標。
在這裡,`ping_request_count` 顯示 `/ping` 端點被呼叫了 3 次。
預設登錄檔包含 Go 執行時指標的收集器,這就是我們看到 `go_threads`、`go_goroutines` 等其他指標的原因。
我們已經構建了我們的第一個指標匯出器。現在,讓我們更新 Prometheus 配置以從我們的伺服器抓取指標。
global:
scrape_interval: 15s
scrape_configs:
- job_name: prometheus
static_configs:
- targets: ["localhost:9090"]
- job_name: simple_server
static_configs:
- targets: ["localhost:8090"]
prometheus --config.file=prometheus.yml

