Lgging ,展现的是应用运行而产生的事件或者程序在执行的过程中间产生的一些日志,可以详细解释系统的运行状态,但是存储和查询需要消耗大量的资源。所以往往使用过滤器减少数据量。
Metrics ,是一种聚合数值,存储空间很小,可以观察系统的状态和趋势,但对于问题定位缺乏细节展示。这个时候使用等高线指标等多维数据结构来增强对于细节的表现力。例如统计一个服务的 TBS 的正确率、成功率、流量等,这是常见的针对单个指标或者某一个数据库的。
Tracing ,面向的是请求,可以轻松分析出请求中异常点,但与 logging 有相同的问题就是资源消耗较大。通常也需要通过采样的方式减少数据量。比如一次请求的范围,也就是从浏览器或者手机端发起的任何一次调用,一个流程化的东西,我们需要轨迹去追踪。
在形式上,所有的指标(Metric)都通过如下格式标示:
<metric name>{<label name>=<label value>, ...}
指标的名称(metric name)可以反映被监控样本的含义(比如,
http_request_total
- 表示当前系统接收到的HTTP请求总量)。指标名称只能由ASCII字符、数字、下划线以及冒号组成并必须符合
正则表达式
[a-zA-Z_:][a-zA-Z0-9_:]*
。
[a-zA-Z_][a-zA-Z0-9_]*
。
http_requests_total
,
node_cpu
都是 Counter 类型的监控指标。一般在定义Counter类型指标的名称时推荐使用
_total
作为后缀。通过 counter 指标我们可以和容易的了解某个事件产生的速率变化。
例如,通过
rate()
函数获取HTTP请求量的增长率:
rate(http_requests_total[5m])
node_memory_MemFree
(主机当前空闲的内容大小)、
node_memory_MemAvailable
(可用内存大小)都是Gauge类型的监控指标。node_memory_MemFree
# HELP go_gc_duration_seconds A summary of the pause duration of garbage collection cycles.# TYPE go_gc_duration_seconds summarygo_gc_duration_seconds{quantile="0"} 3.98e-05go_gc_duration_seconds{quantile="0.25"} 5.31e-05go_gc_duration_seconds{quantile="0.5"} 6.77e-05go_gc_duration_seconds{quantile="0.75"} 0.0001428go_gc_duration_seconds{quantile="1"} 0.0008099go_gc_duration_seconds_sum 0.0114183go_gc_duration_seconds_count 85
_count
作为后缀)以及其值的总量(以
_sum
作为后缀)。不同在于 Histogram 指标直接反应了在不同区间内样本的个数,区间通过标签len进行定义。同时对于Histogram的指标,可以通过
histogram_quantile()
函数计算出其值的分位数。# HELP prometheus_http_response_size_bytes Histogram of response size for HTTP requests.# TYPE prometheus_http_response_size_bytes histogramprometheus_http_response_size_bytes_bucket{handler="/",le="100"} 1prometheus_http_response_size_bytes_bucket{handler="/",le="1000"} 1prometheus_http_response_size_bytes_bucket{handler="/",le="10000"} 1prometheus_http_response_size_bytes_bucket{handler="/",le="100000"} 1prometheus_http_response_size_bytes_bucket{handler="/",le="1e+06"} 1prometheus_http_response_size_bytes_bucket{handler="/",le="+Inf"} 1prometheus_http_response_size_bytes_sum{handler="/"} 29prometheus_http_response_size_bytes_count{handler="/"} 1
/metrics
接口暴露指标,这样 Promethues server 就能通过 http 请求抓取到我们的业务指标。server := gin.New()server.Use(middlewares.AccessLogger(), middlewares.Metric(), gin.Recovery())server.GET("/health", func(c *gin.Context) {c.JSON(http.StatusOK, gin.H{ "message": "ok",})})server.GET("/metrics", Monitor)func Monitor(c *gin.Context) {h := promhttp.Handler()h.ServeHTTP(c.Writer, c.Request)}
为了方便理解,这里选取了三种类型和两种业务场景的指标
示例
var (//HTTPReqDuration metric:http_request_duration_secondsHTTPReqDuration *prometheus.HistogramVec//HTTPReqTotal metric:http_request_totalHTTPReqTotal *prometheus.CounterVec// TaskRunning metric:task_runningTaskRunning *prometheus.GaugeVec)func init() {// 监控接口请求耗时// 指标类型是 HistogramHTTPReqDuration = prometheus.NewHistogramVec(prometheus.HistogramOpts{Name: "http_request_duration_seconds",Help: "http request latencies in seconds",Buckets: nil,}, []string{"method", "path"})// "method"、"path" 是 label// 监控接口请求次数// 指标类型是 CounterHTTPReqTotal = prometheus.NewCounterVec(prometheus.CounterOpts{Name: "http_requests_total",Help: "total number of http requests",}, []string{"method", "path", "status"}) // "method"、"path"、"status" 是 label// 监控当前在执行的 task 数量// 监控类型是 GaugeTaskRunning = prometheus.NewGaugeVec(prometheus.GaugeOpts{Name: "task_running",Help: "current count of running task",}, []string{"type", "state"})// "type"、"state" 是 labelprometheus.MustRegister(HTTPReqDuration,HTTPReqTotal,TaskRunning,)}
通过上述的代码我们就定义并且注册了我们的想要监控的指标。
示例
start := time.Now()c.Next()duration := float64(time.Since(start)) / float64(time.Second)path := c.Request.URL.Path// 请求数加1controllers.HTTPReqTotal.With(prometheus.Labels{"method": c.Request.Method,"path": path,"status": strconv.Itoa(c.Writer.Status()),}).Inc()// 记录本次请求处理时间controllers.HTTPReqDuration.With(prometheus.Labels{"method": c.Request.Method,"path": path,}).Observe(duration)// 模拟新建任务controllers.TaskRunning.With(prometheus.Labels{"type": shuffle([]string{"video", "audio"}),"state": shuffle([]string{"process", "queue"}),}).Inc()// 模拟任务完成controllers.TaskRunning.With(prometheus.Labels{"type": shuffle([]string{"video", "audio"}),"state": shuffle([]string{"process", "queue"}),}).Dec()
Promethues 抓取 target 配置
# 抓取间隔scrape_interval: 5s# 目标scrape_configs:- job_name: 'prometheus'static_configs:- targets: ['prometheus:9090']- job_name: 'local-service'metrics_path: /metricsstatic_configs:- targets: ['host.docker.internal:8000']
来自 “ ITPUB博客 ” ,链接:https://blog.itpub.net/70013542/viewspace-3020834/ ,如需转载,请注明出处,否则将追究法律责任。