Prometheus 所有采集的监控数据均以指标(metric)的形式保存在内置的时间序列数据库当中(TSDB):属于同一指标名称,同一标签集合的、有时间戳标记的数据流。除了存储的时间序列,Prometheus 还可以根据查询请求产生临时的、衍生的时间序列作为返回结果。
样本在时间序列中的每一个点称为一个样本(sample),样本由以下三部分组成:
指标(metric):指标名称和描述当前样本特征的 labelsets;
时间戳(timestamp):一个精确到毫秒的时间戳;
样本值(value): 一个 folat64 的浮点型数据表示当前样本的值。
一种累加的 metric,典型的应用如:请求的个数,结束的任务数,出现的错误数等。随着客户端不断请求,数值越来越大。例如api_http_requests_total{method="POST", handler="/messages"}
一种常规的 metric,典型的应用如:温度,运行的 goroutines 的个数。返回的数值会上下波动。
例如go_goroutines{instance="172.17.0.2", job="Prometheus"}
可以理解为柱状图,典型的应用如:请求持续时间,响应大小。可以对观察结果采样,分组及统计。例如设置一个name为web_request_duration_seconds的Histogram 的metrics,并设置区间值为[0.1,0.5,1]
会对区间点生成一条统计数据.
# 响应时间小于0.1s的请求有5次
web_request_duration_seconds_bucket{endpoint="/query",method="GET",le="0.1"} 3
# 响应时间小于0.5s的请求有次
web_request_duration_seconds_bucket{endpoint="/query",method="GET",le="0.5"} 5
# 响应时间小于1s的请求有7次
web_request_duration_seconds_bucket{endpoint="/query",method="GET",le="1"} 7
# 总共7次请求
web_request_duration_seconds_bucket{endpoint="/query",method="GET",le="+Inf"} 7
# 7次请求duration的总和
web_request_duration_seconds_sum{endpoint="/query",method="GET"} 2.7190880529999997
类似于 Histogram, 典型的应用如:请求持续时间,响应大小。
主要做统计用,设置分位数的值,会实时返回该分位数上的值。
下载 prometheus go 客户端 go get github.com/prometheus/client_golang/prometheus/promhttp
.
golang应用中集成
func main() {
// expose prometheus metrics接口
http.Handle("/metrics", promhttp.Handler())
log.Fatal(http.ListenAndServe(":8080", nil))
}
http://localhost:8080/metrics
,会返回一些go应用中goroutine,thread、gc、堆栈的基本信息。
# HELP go_gc_duration_seconds A summary of the GC invocation durations.
# TYPE go_gc_duration_seconds summary
go_gc_duration_seconds{quantile="0"} 0
go_gc_duration_seconds{quantile="0.25"} 0
go_gc_duration_seconds{quantile="0.5"} 0
go_gc_duration_seconds{quantile="0.75"} 0
go_gc_duration_seconds{quantile="1"} 0
go_gc_duration_seconds_sum 0
go_gc_duration_seconds_count 0
# HELP go_goroutines Number of goroutines that currently exist.
# TYPE go_goroutines gauge
go_goroutines 6
# HELP go_info Information about the Go environment.
# TYPE go_info gauge
go_info{version="go1.12"} 1
完整应用代码
// 初始化 web_reqeust_total, counter类型指标, 表示接收http请求总次数
var WebRequestTotal = prometheus.NewCounterVec(
prometheus.CounterOpts{
Name: "web_reqeust_total",
Help: "Number of hello requests in total",
},
// 设置两个标签 请求方法和 路径 对请求总次数在两个
[]string{"method", "endpoint"},
)
// web_request_duration_seconds,Histogram类型指标,bucket代表duration的分布区间
var WebRequestDuration = prometheus.NewHistogramVec(
prometheus.HistogramOpts{
Name: "web_request_duration_seconds",
Help: "web request duration distribution",
Buckets: []float64{0.1, 0.3, 0.5, 0.7, 0.9, 1},
},
[]string{"method", "endpoint"},
)
func init() {
// 注册监控指标
prometheus.MustRegister(WebRequestTotal)
prometheus.MustRegister(WebRequestDuration)
// 包装 handler function,不侵入业务逻辑
func Monitor(h http.HandlerFunc) http.HandlerFunc {
return func(w http.ResponseWriter, r *http.Request) {
start := time.Now()
h(w, r)
duration := time.Since(start)
// counter类型 metric的记录方式
WebRequestTotal.With(prometheus.Labels{"method": r.Method, "endpoint": r.URL.Path}).Inc()
// Histogram类型 meric的记录方式
WebRequestDuration.With(prometheus.Labels{"method": r.Method, "endpoint": r.URL.Path}).Observe(duration.Seconds())
}
}
···
func main() {
// expose prometheus metrics接口
http.Handle("/metrics", promhttp.Handler())
http.HandleFunc("/query", monitor.Monitor(Query))
log.Fatal(http.ListenAndServe(":8080", nil))
}
// query
func Query(w http.ResponseWriter, r *http.Request) {
//模拟业务查询耗时0~1s
time.Sleep(time.Duration(rand.Intn(1000)) * time.Millisecond)
_,_ = io.WriteString(w, "some results")
}
http://localhost:8080/query
接口,并再次访问http://localhost:8080/metrics
接口,返回的指标数据中就有了刚加上的metric,如下所示
# HELP web_reqeust_total Number of hello requests in total
# TYPE web_reqeust_total counter
web_reqeust_total{endpoint="/hello",method="GET"} 1
web_reqeust_total{endpoint="/query",method="GET"} 7
# HELP web_request_duration_seconds web request duration distribution
# TYPE web_request_duration_seconds histogram
web_request_duration_seconds_bucket{endpoint="/query",method="GET",le="0.1"} 3
web_request_duration_seconds_bucket{endpoint="/query",method="GET",le="0.3"} 3
web_request_duration_seconds_bucket{endpoint="/query",method="GET",le="0.5"} 5
web_request_duration_seconds_bucket{endpoint="/query",method="GET",le="0.7"} 5
web_request_duration_seconds_bucket{endpoint="/query",method="GET",le="0.9"} 7
web_request_duration_seconds_bucket{endpoint="/query",method="GET",le="1"} 7
web_request_duration_seconds_bucket{endpoint="/query",method="GET",le="+Inf"} 7
web_request_duration_seconds_sum{endpoint="/query",method="GET"} 2.7190880529999997
web_request_duration_seconds_count{endpoint="/query",method="GET"} 7
完整应用代码地址,可以直接安装运行,详细说明可以参考官网
go install github.com/crockitwood/go-prometheus-example
go-prometheus-example
curl http://localhost:8080/query
curl http://localhost:8080/metrics