Prometheus 提供了 官方版 Golang 库 用于采集并暴露监控数据,本文为您介绍如何使用官方版 Golang 库来暴露 Golang runtime 相关的数据,以及其它一些基本简单的示例,并使用托管 Prometheus 服务来采集和展示指标数据。
说明
Golang Client API 相关的文档详见 GoDoc。
您可以通过 go get
命令来安装相关依赖,示例如下:
go get github.com/prometheus/client_golang/prometheus go get github.com/prometheus/client_golang/prometheus/collectors go get github.com/prometheus/client_golang/prometheus/promhttp
创建一个 HTTP 服务,路径使用 /metrics
。可以直接使用 prometheus/promhttp
里提供的 Handler
函数。
如下是一个简单的示例,通过 http://localhost:2023/metrics
暴露 Golang 应用的一些默认指标数据,包括:运行时指标、进程相关指标以及构建相关的指标。
package main import ( "math" "math/rand" "net/http" "time" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/collectors" "github.com/prometheus/client_golang/prometheus/promhttp" ) func main() { // Create a new registry. reg := prometheus.NewRegistry() // Add Go module build info. reg.MustRegister(collectors.NewBuildInfoCollector()) // Add go runtime metrics and process collectors. reg.MustRegister( collectors.NewGoCollector(), collectors.NewProcessCollector(collectors.ProcessCollectorOpts{}), ) http.Handle("/metrics", promhttp.HandlerFor( reg, promhttp.HandlerOpts{}, )) http.ListenAndServe(":2023", nil) }
go run main.go
curl http://localhost:2023/metrics
package main import ( "math" "math/rand" "net/http" "time" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/collectors" "github.com/prometheus/client_golang/prometheus/promhttp" ) var rpcDurations = prometheus.NewSummaryVec( prometheus.SummaryOpts{ Name: "rpc_durations_seconds", Help: "RPC latency distributions.", Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001}, }, []string{"service"}, ) func main() { // Create a new registry. reg := prometheus.NewRegistry() // Add Go module build info. reg.MustRegister(collectors.NewBuildInfoCollector()) // Add go runtime metrics and process collectors. reg.MustRegister( collectors.NewGoCollector(), collectors.NewProcessCollector(collectors.ProcessCollectorOpts{}), ) reg.MustRegister(rpcDurations) start := time.Now() oscillationFactor := func() float64 { return 2 + math.Sin(math.Sin(2*math.Pi*float64(time.Since(start))/float64(10*time.Minute))) } // Periodically record some sample latencies for the three services. go func() { for { v := rand.Float64() * 0.0002 rpcDurations.WithLabelValues("uniform").Observe(v) time.Sleep(time.Duration(100*oscillationFactor()) * time.Millisecond) } }() go func() { for { v := (rand.NormFloat64() * 0.0002) + 0.00001 rpcDurations.WithLabelValues("normal").Observe(v) time.Sleep(time.Duration(75*oscillationFactor()) * time.Millisecond) } }() go func() { for { v := rand.ExpFloat64() / 1e6 rpcDurations.WithLabelValues("exponential").Observe(v) time.Sleep(time.Duration(50*oscillationFactor()) * time.Millisecond) } }() http.Handle("/metrics", promhttp.HandlerFor( reg, promhttp.HandlerOpts{}, )) http.ListenAndServe(":2023", nil) }
go run main.go
curl http://localhost:2023/metrics
从输出结果我们可以看到 rpc_durations_seconds
计数器相关的信息,包括帮助文档、类型信息、指标名和当前值。
# HELP rpc_durations_seconds RPC latency distributions. # TYPE rpc_durations_seconds summary rpc_durations_seconds{service="exponential",quantile="0.5"} 7.427294276581254e-07 rpc_durations_seconds{service="exponential",quantile="0.9"} 2.3157390817424027e-06
上面的示例仅展示了如何使用 Prometheus Golang 库来暴露应用的指标数据,但暴露的监控指标数据还需要通过托管 Prometheus 服务进行统一的采集的存储,进一步才能实现数据的监控和告警。
说明
该 Dockerfile 仅为示例,您需要按需修改里面的参数。
FROM golang:1.19 as builder COPY . /go/src/demo WORKDIR /go/src/demo RUN go env -w GOPROXY=https://goproxy.cn,direct && \ go mod init && \ go mod tidy && \ go mod vendor && \ go build -v -o /golang-demo FROM buildpack-deps:bullseye-curl RUN mkdir -p /app COPY --from=builder /golang-demo /app WORKDIR /app ENV TZ Asia/Shanghai EXPOSE 2023 ENTRYPOINT ["/app/golang-demo"]
说明
火山引擎镜像仓库的镜像推送方式,请参见 推送和拉取镜像。
您可以使用镜像仓库中的镜像,在容器服务 VKE 集群中部署应用。步骤如下:
apiVersion: apps/v1 kind: Deployment metadata: name: golang-demo # 配置应用的名称 namespace: volcano-metrics # 配置应用所在的命名空间 labels: app: golang-demo # 配置应用的标签 spec: replicas: 2 # 配置应用副本数 selector: matchLabels: app: golang-demo template: metadata: labels: app: golang-demo spec: containers: - name: golang-demo # 配置容器名称 image: doc-cn-beijing.cr.volces.com/vmp/golang-demo:1.0 # 配置应用镜像的地址和版本 ports: - containerPort: 2023 # 配置容器端口
apiVersion: v1 kind: Service metadata: name: golang-service-demo namespace: volcano-metrics # 配置服务所在的命名空间 labels: app: golang-service-demo # 配置服务的标签 spec: selector: app: golang-demo ports: - protocol: TCP port: 2023 targetPort: 2023 name: metrics # 配置服务端口名称 type: ClusterIP
当应用部署并正常运行后,可以使用 ServiceMonitor 配置服务发现,允许 Agent 采集该应用的指标。具体的操作步骤如下:
apiVersion: monitoring.coreos.com/v1 kind: ServiceMonitor metadata: name: golang-demo # 填写一个唯一名称 namespace: default # 配置 ServiceMonitor 命名空间 labels: volcengine.vmp: "true" # 配置 ServiceMonitor 的标签,允许被 Prometheus-agent 发现 spec: endpoints: - interval: 30s port: metrics # 配置服务端口号 path: /metrics # 填写指标暴露的 URI 路径,不填默认为 /metrics relabelings: - action: replace sourceLabels: [__meta_kubernetes_pod_label_app] targetLabel: application namespaceSelector: matchNames: - volcano-metrics # 配置为服务所在的命名空间 selector: matchLabels: app: golang-service-demo # 配置服务的 Label 值,以定位目标服务
您可以使用托管 Prometheus 服务的 Explore 功能来查看监控指标数据。详情请参见 指标查询。
也可以使用 Grafana 读取托管 Prometheus 服务中存储的数据,并创建指标大盘。