设置支持指标记录
// see internal/router/router.go
...
mux, err := core.New(logger,
...
core.WithRecordMetrics(metrics.RecordHandler(logger)),
...
)
// core.WithRecordMetrics() 表示已设置指标记录
// metrics.RecordHandler 表示具体指标记录的实现,目前是 prometheus 指标记录
指标记录逻辑
// see internal/metrics/metrics.go
// RecordHandler 指标处理
func RecordHandler(logger *zap.Logger) func(msg *proposal.MetricsMessage) {
if logger == nil {
panic("logger required")
}
return func(msg *proposal.MetricsMessage) {
RecordMetrics(
msg.Method,
msg.Path,
msg.IsSuccess,
msg.HTTPCode,
msg.BusinessCode,
msg.CostSeconds,
msg.TraceID,
)
}
}
记录 prometheus 指标
// see internal/metrics/prometheus.go
// metricsRequestsTotal metrics for request total 计数器(Counter)
var metricsRequestsTotal = prometheus.NewCounterVec(
prometheus.CounterOpts{
Namespace: namespace,
Subsystem: subsystem,
Name: "requests_total",
Help: "request(ms) total",
},
[]string{"method", "path"},
)
// metricsRequestsCost metrics for requests cost 累积直方图(Histogram)
var metricsRequestsCost = prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Namespace: namespace,
Subsystem: subsystem,
Name: "requests_cost",
Help: "request(ms) cost milliseconds",
},
[]string{"method", "path", "success", "http_code", "business_code", "cost_milliseconds", "trace_id"},
)
func init() {
prometheus.MustRegister(metricsRequestsTotal, metricsRequestsCost)
}
// RecordMetrics 记录指标
func RecordMetrics(method, path string, success bool, httpCode, businessCode int, costSeconds float64, traceId string) {
metricsRequestsTotal.With(prometheus.Labels{
"method": method,
"path": path,
}).Inc()
metricsRequestsCost.With(prometheus.Labels{
"method": method,
"path": path,
"success": cast.ToString(success),
"http_code": cast.ToString(httpCode),
"business_code": cast.ToString(businessCode),
"cost_milliseconds": cast.ToString(costSeconds * 1000),
"trace_id": traceId,
}).Observe(costSeconds)
}
prometheus 指标数据的收集地址
当时笔记
本地启动服务
启用 promethus
$ prometheus --config.file=./deploy/prometheus/prometheus.yml
启动 grafana
$ brew services start grafana
访问地址:http://127.0.0.1:3000
账号密码:admin/123456
PromQL 示例
Counter
指标数据可以让用户方便的了解事件产生的速率的变化,在 PromQL 内置的相关操作函数可以提供相应的分析,比如以 HTTP 应用请求量来进行说明:
//通过 rate() 函数,获取 5 分钟内 HTTP 请求量的增长率
rate(xinliangnote_go_gin_api_requests_total[5m])
//通过 topk() 函数,获取访问量前 10 的 HTTP 地址
topk(10, xinliangnote_go_gin_api_requests_total)
Histogram
指标,可以通过 histogram_quantile() 函数计算出其值的分位数,举例:
histogram_quantile(0.95, sum(rate(xinliangnote_go_gin_api_requests_cost_bucket[5m])) by (le))
文档
Prometheus 中文文档:https://yunlzheng.gitbook.io/prometheus-book/
Prometheus 英文文档:https://prometheus.io/docs/introduction/overview/