参考资料
[1] prometheus 包的应用
[2] Prometheus 监控装置及应用
[3] Prometheus Client 教程
[4] 应用 Prometheus 对 Go 应用程序进行监测
[5] 带你读《Prometheus 监控实战》
[6] Prometheus
https://eddycjy.com/posts/pro…
https://yunlzheng.gitbook.io/…
1. 简介
prometheus 包提供了用于实现监控代码的 metric 原型和用于注册 metric 的 registry。子包(promhttp)容许通过 HTTP 来裸露注册的 metric 或将注册的 metric 推送到 Pushgateway。
Metrics
prometheus 一共有 5 种 metric 类型,前四种为:Counter,Gauge,Summary 和 Histogram,每种类型都有对应的 vector 版本:GaugeVec, CounterVec, SummaryVec, HistogramVec,vector 版本细化了 prometheus 数据模型,减少了 label 维度。第 5 种 metric 为 Untyped,它的运作形式相似 Gauge,区别在于它只向 prometheus 服务器发送类型信号。
只有根底 metric 类型实现了 Metric 接口,metric 和它们的 vector 版本都实现了 collector 接口。collector 负责一系列 metrics 的采集,然而为了不便,metric 也能够“收集本人”。留神:Gauge, Counter, Summary, Histogram, 和 Untyped 本身就是接口,而 GaugeVec, CounterVec, SummaryVec, HistogramVec, 和 UntypedVec 则不是接口。
为了创立 metric 和它们的 vector 版本,须要抉择适合的 opts 构造体,如 GaugeOpts, CounterOpts, SummaryOpts, HistogramOpts, 或 UntypedOpts.
Custom Collectors and constant Metrics
实现本人的 metric,个别只须要实现本人的 collector 即可。如果曾经有了现成的 metric(prometheus 上下文之外创立的),则无需应用 Metric 类型接口,只须要在采集期间将现有的 metric 映射到 prometheus metric 即可,此时能够应用 NewConstMetric, NewConstHistogram, and NewConstSummary (以及对应的 Must… 版本) 来创立 metric 实例,以上操作在 collect 办法中实现。describe 办法用于返回独立的 Desc 实例,NewDesc 用于创立这些 metric 实例。(NewDesc 用于创立 prometheus 辨认的 metric)
如果只须要调用一个函数来收集一个 float 值作为 metric,那么举荐应用 GaugeFunc, CounterFunc, 或 UntypedFunc。
Advanced Uses of the Registry
MustRegister 是注册 collector 最通用的形式。如果须要捕捉注册时产生的谬误,能够应用 Register 函数,该函数会返回谬误。
如果注册的 collector 与曾经注册的 metric 不兼容或不统一时就会返回谬误。registry 用于使收集的 metric 与 prometheus 数据模型保持一致。不统一的谬误会在注册时而非采集时检测到。前者会在零碎的启动时检测到,而后者只会在采集时产生(可能不会在首次采集时产生),这也是为什么 collector 和 metric 必须向 Registry describe 它们的起因。
以上提到的 registry 都被称为默认 registry,能够在全局变量 DefaultRegisterer 中找到。应用 NewRegistry 能够创立 custom registry,或者能够本人实现 Registerer 或 Gatherer 接口。custom registry 的 Register 和 Unregister 运作形式相似,默认 registry 则应用全局函数 Register 和 Unregister。
custom registry 的应用形式还有很多:能够应用 NewPedanticRegistry 来注册非凡的属性;能够防止由 DefaultRegisterer 限度的全局状态属性;也能够同时应用多个 registry 来裸露不同的 metrics。
DefaultRegisterer 注册了 Go runtime metrics(通过 NewGoCollector)和用于 process metrics 的 collector(通过 NewProcessCollector)。通过 custom registry 能够本人决定注册的 collector。
HTTP Exposition
Registry 实现了 Gather 接口。调用 Gather 接口能够通过某种形式裸露采集的 metric。通常 metric endpoint 应用 http 来裸露 metric。通过 http 裸露 metric 的工具为 promhttp 子包。
函数和类型阐明:
func Register(c Collector) error:应用 DefaultRegisterer 来注册传入的 Collector
func Unregister(c Collector) bool:应用 DefaultRegisterer 来移除传入的 Collector 的注册信息
type AlreadyRegisteredError:该类型实现了 error 接口,由 Register 返回,用于判断用于注册的 collector 是否曾经被注册过
type Collector:用于采集 prometheus metric,如果运行多个雷同的实例,则须要应用 ConstLabels 来注册这些实例。实现 collector 接口须要实现 Describe 和 Collect 办法,并注册 collector。type Registerer:负责 collector 的注册和去注册,实现 custom registrer 时应该实现该接口
// MustRegister implements Registerer.
func (r *Registry) MustRegister(cs ...Collector) {
for _, c := range cs {if err := r.Register(c); err != nil {panic(err)
}
}
}
2. 示例
https://blog.csdn.net/runner6…
https://www.cnblogs.com/FG123…
[1] 下载案例
git clone https://github.com/crockitwoo…
[2] 建设 go.mod
$ cd go-prometheus-example
$ touch go.mod
键入以下内容:
module go-prometheus-example
go 1.12
$ go mod tidy
[3] 批改 main.go
将 "github.com/crockitwood/go-prometheus-example/monitor" 改为 "go-prometheus-example/monitor"
[4] 编译运行
$ go build
$ ./go-prometheus-example
[5] 拜访网址
http://localhost:8080/hello
http://localhost:8080/query
http://localhost:8080/metrics
3. Prometheus 四大度量指标
- Counter (计数器) 类型代表一个累积的指标数据,其枯燥递增,只增不减。在利用场景中,像是申请次数、谬误数量等等,就非常适合用 Counter 来做指标类型,另外 Counter 类型,只有在被采集端重新启动时才会归零。
- Gauge (仪表盘) 类型代表一个能够任意变动的指标数据,其可增可减。在利用场景中,像是 Go 利用程序运行时的 Goroutine 的数量就能够用该类型来示意,因为其是浮动的数值,并非固定的,侧重于反馈以后的状况。
Histogram(累计直方图) 类型将会在一段时间范畴内对数据进行采样(通常是申请持续时间或响应大小等等),并将其计入可配置的存储桶(bucket)中,后续可通过指定区间筛选样本,也能够统计样本总数。 - Summary(摘要) 类型将会在一段时间范畴内对数据进行采样,然而与 Histogram 类型不同的是 Summary 类型将会存储分位数(在客户端进行计算),而不像 Histogram 类型,依据所设置的区间状况统计存储。
Prometheus 通过指标名称(metrics name)以及对应的一组标签(labelset)惟一定义一条工夫序列。指标名称反映了监控样本的根本标识,而 label 则在这个基本特征上为采集到的数据提供了多种特色维度。用户能够基于这些特色维度过滤,聚合,统计从而产生新的计算后的一条工夫序列。
4. 查问
func HandleGetQueryResp(c *gin.Context){
//queryString:="promhttp_metric_handler_requests_total"
//queryString:="cpu_total_info"
queryString:="cpu_total_info{}[5m]"
fmt.Println("queryString=",queryString)
// create prom client
newClient, err := api.NewClient(api.Config{Address: "http://localhost:9090"})
//newClient, err := api.NewClient(api.Config{Address: "http://localhost:10086/metrics"})
if nil != err {fmt.Println("NewClient err=",err)
return
}
// create prom client http api
promAPI := v1.NewAPI(newClient)
// instant value, type is vector
resp, _, err := promAPI.Query(context.TODO(), queryString, time.Time{})
//resp, _,err := promAPI.LabelValues(context.TODO(), queryString,time.Time{},time.Time{})
if nil != err {fmt.Println("Query err=",err)
return
}
cpuValue := resp.(model.Matrix)
fmt.Println("cpuValue=",cpuValue)
fmt.Println("len=",cpuValue.Len())
fmt.Println("cpuValue[0].Metric.String()=",cpuValue[0].Metric.String())
byts,err:=cpuValue[0].Values[0].Value.MarshalJSON()
fmt.Println("byts=",string(byts))
fmt.Println("cpuValue[0].Metric.Values=",cpuValue[0].Values)
zer:=cpuValue[0].Metric["cpu"]
fmt.Println("cpuValue[0].Metric[cpu]=",zer)
for a,b:= range cpuValue[0].Metric{fmt.Println("a=",a)
fmt.Println("b=",b)
}
c.JSON(http.StatusOK, resp)
return
}
resp 后果:
[{"metric":{
"__name__":"cpu_total_info",
"instance":"localhost:10086",
"job":"cpu",
"nice":"nice",
"user":"user"
},
"values":
[[1610368090.67,"1"], # 工夫,值
[1610368300.67,"16"]]
}]
[
{
"metric":{
"__name__":"disk_info",
"disk_file_system":"general",
"disk_label":"free",
"disk_mount_point":"total",
"instance":"localhost:10086",
"job":"cpu","node_ip":"1.1.1.1"
},
"values":[[1610419795.669,"22778143113216"],
[1610419900.669,"40493879795712"]
]
},
{
"metric":{
"__name__":"disk_info",
"disk_file_system":"general",
"disk_label":"total",
"disk_mount_point":"total",
"instance":"localhost:10086",
"job":"cpu","node_ip":"1.1.1.1"
},
"values":[[1610419795.669,"63494033448960"],
[1610419900.669,"112878281687040"]
]
},
{
"metric":{
"__name__":"disk_info",
"disk_file_system":"general",
"disk_label":"used",
"disk_mount_point":"total",
"instance":"localhost:10086",
"job":"cpu","node_ip":"1.1.1.1"
},
"values":[[1610419795.669,"40715890335744"],
[1610419900.669,"72384401891328"]
]
},
{
"metric":{
"__name__":"disk_info",
"disk_file_system":"general",
"disk_label":"used_rate",
"disk_mount_point":"total",
"instance":"localhost:10086",
"job":"cpu","node_ip":"1.1.1.1"
},
"values":[[1610419795.669,"64.12553766721038"],
[1610419900.669,"64.12606642260637"]
]
}
]