本文主主要是对上文的补充,关于 Prometheus及grafana 的安装配置就参考上文 go-prometheus业务监控指标实战 。本文主要讲解的是 Histogram和Summary的案例。并且结合案例配置自动告警机制。
案例 Histogram 统计班级人数的考试分数(value),每个人有subject(学科)和age(年龄)两个属性(label)
代码
main.go
package main
import (
"net/http"
qzPro "gitee.com/qzcsu/go-web-study/service/prometheus"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
)
func main() {
prometheus.MustRegister(qzPro.CommonCounter, qzPro.FuncCounter, qzPro.VecCounter, qzPro.CommonGauge, qzPro.FuncGauge, qzPro.VecGauge,
qzPro.CommonHistogram, qzPro.VecHistogram, qzPro.CommonSummary, qzPro.VecSummary)
http.HandleFunc("/common_counter", qzPro.DealCommCounter)
http.HandleFunc("/vec_counter", qzPro.DealVecCounter)
http.HandleFunc("/common_gauge", qzPro.DealCommGauge)
http.HandleFunc("/vec_gauge", qzPro.DealVecGauge)
http.HandleFunc("/common_histogram", qzPro.DealCommHistogram)
http.HandleFunc("/vec_histogram", qzPro.DealVecHistogram)
http.Handle("/metrics", promhttp.Handler()) // 暴露 metrics 指标
http.ListenAndServe(":8090", nil)
}
service/prometheus/constants.go
package prometheus
import (
"fmt"
"net/http"
"strconv"
"gitee.com/qzcsu/go-web-study/utils/randomutil"
)
const (
namePrefix = "the_number_of_student"
subSys = "client_golang"
nameSpace = "prometheus_demo"
)
var names = []string{
"小明", "小红", "小花"}
var ages = []int64{
20, 21, 22, 23, 24, 25}
var subjects = []string{
"语文", "数学", "体育"}
func GetParamNum(req *http.Request) int64 {
err := req.ParseForm()
if err != nil {
fmt.Println("parse form err")
return 0
}
numStr := req.Form.Get("num")
fmt.Printf("numStr:[%v]\n", numStr)
num, err := strconv.ParseInt(numStr, 10, 64)
if err != nil {
fmt.Printf("parse int err :%v\n", err)
return 0
}
return num
}
// randData随机获取一个元素,并且将本次请求的随机元素统计到countStrMap
func getCurRandomStrMap(countStrMap map[string]int64, randData []string) string {
index := randomutil.RandomNum(0, int64(len(randData)))
randVal := randData[index]
countStrMap[randVal] = countStrMap[randVal] + 1
return randVal
}
// randData随机获取一个元素,并且将本次请求的随机元素统计到countIntMap
func getCurRandomIntMap(countIntMap map[int64]int64, randData []int64) string {
index := randomutil.RandomNum(0, int64(len(randData)))
randVal := randData[index]
countIntMap[randVal] = countIntMap[randVal] + 1
return fmt.Sprintf("%d", randVal)
}
service/prometheus/histogram.go
package prometheus
import (
"fmt"
"net/http"
"sort"
"sync/atomic"
"time"
"github.com/prometheus/client_golang/prometheus"
"gitee.com/qzcsu/go-web-study/utils/randomutil"
)
const HistogramNamePrefix = namePrefix + "_histogram"
// CommonHistogram 普通的直方图
var commonHistogramTotalCount int64
var totalHistogramCommonPoint []float64
var CommonHistogram = prometheus.NewHistogram(
prometheus.HistogramOpts{
Subsystem: subSys,
Namespace: nameSpace,
Help: "desc the metric",
Name: fmt.Sprintf("%s:%s", HistogramNamePrefix, "common"),
// DefBuckets = []float64{.005, .01, .025, .05, .1, .25, .5, 1, 2.5, 5, 10} //默认的分桶
// 定义桶 (开始值-步长-桶个数) 定义的bucket 小于等于某个桶的count数 prometheus.LinearBuckets(20, 3, 5) 指的是 [20,23],(23,26],(26,29],(29,+q)
Buckets: prometheus.LinearBuckets(60, 10, 5),
},
)
// 创建一个常量的直方图
var ConstHistogram, _ = prometheus.NewConstHistogram(
prometheus.NewDesc(
fmt.Sprintf("%s:%s", HistogramNamePrefix, "const"),
"A histogram of the HTTP request durations.",
[]string{
"code", "method"},
prometheus.Labels{
"owner": "example", "头衔": "将军"},
),
4711,