参考资料
[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"]
]
}
]
发表回复