美文网首页
grafana 和 Prometheus 采集数据并展示

grafana 和 Prometheus 采集数据并展示

作者: 天空蓝雨 | 来源:发表于2023-10-15 18:21 被阅读0次

参考: 使用 Prometheus 监控服务器性能

进程监控:Prometheus+Process exporter+Grafana进程监控
容器监控 cadvisor + Prometheus+Grafana监控Docker容器

(cadvisor 指标比较多,我们在Grafana自己编辑采集的指标, 比如容器内存用这个container_memory_working_set_bytes{job="cadvisor", name="apc_boolean"}
默认的内存可能不是我们想要的,看到这个 https://blog.csdn.net/u010918487/article/details/106190764才知道的
)

主机监控 node_exporter Prometheus+Grafana 监控主机
prometheus client_golang 简单使用

Go进阶31:python 的 Prometheus Client教程
apc_boolean
gitbook 介绍普罗米的:
https://yunlzheng.gitbook.io/prometheus-book/introduction

接下来就详细介绍一下 普罗米的使用,并在最后的一个项目中使它结合 grafna 展示一些数据

总体特征

  • 收集的数据是时间戳 和 可选的标签 值 以及指标 共同存储
  • PromQL 自己的查询数据的 语言 类似 sql 这些
  • 采集数据通过http pull
  • 可以配置中间网关 push 数据,但最后 普罗米从网关 pull 数据
  • 支持服务发现获取 pull 地址(当然也可以直接配置 目标机器)
  • 支持 grafana 等仪表盘获取数据展示

可以看出来, 普罗米就是通过 http 采集数据, 并存储,数据展示可以被其他开源组件。

使用

  • 安装
    下载对应的版本
tar xvfz prometheus-*.tar.gz
cd prometheus-*
// 启动
./prometheus --config.file=prometheus.yml
// 可以编辑 prometheus.yml ,在里面配置一些数据采集的地址

配置文件有 global、rule_files和scrape_configs 三个字段

// 全局配置
global:
  scrape_interval:     15s   // 采集周期
  evaluation_interval: 15s  // 判断规则时间, 生成警报

rule_files:  // 加载其他规则文件
  # - "first.rules"
  # - "second.rules"

scrape_configs:   // 监控数据来源
  - job_name: prometheus
    static_configs:
      - targets: ['localhost:9090']

指标类型

  • Counter
    单调递增的计数器, 记录比如 请求总数,任务总数这些只会增加的指标, 对于波动的数据使用 Gauge
    python 实例:
pip install prometheus_client
进程重新启动时重置
from prometheus_client import Counter
c = Counter('my_failures', 'Description of counter')
c.inc()     # Increment by 1
c.inc(1.6)  # Increment by given value
表示服务启动后的数据增长, 可以用 rate (irate 波动更大)计算 增长速率 (模拟qps)
  • Gauge
    记录波动的数值, 比如请求的 qps(直接客户端上报,记得天一就是在入口处计算的qps, 直接是原子累加,不用在前端计算了), 温度变化等
    python:
from prometheus_client import Gauge
g = Gauge('my_inprogress_requests', 'Description of gauge')
g.inc()      # 增加
g.dec(10)    # 减少
g.set(4.2)   # 设置到某个值 

天一统计 qps:
就是一个在接口入口原子计数累积,每秒清零,其实可以把这个 qps 上报到 Gauge, 但是采集速度不是每秒的,所以还是有误差的

go func(t *time.Ticker) {
        defer ticker.Stop()
        for {
            // 一秒打印一次统计数量
            <- t.C
            common.GetLogger().Error("module current qps is:",  atomic.LoadInt64(&Model_rate))
                    httpRequestGauge.WithLabelValues("qps").Set(float64(atomic.LoadInt64(&Model_rate)))
            // 清空
            atomic.StoreInt64(&Model_rate, 0)
        }
    }(ticker)

效果:
为了便于观察, 把 label 的path 参数都改成 qps


上报的 qps 更为精确, rate 计算的斜率,由于是一段时间(时间改小点,更精确)的平均值,所以变化缓和一点
  • Histogram
    直方图, 对观察结果进行采样, 通常是 请求响应时间或响应大小,就是你只管 Observe, 其他的由普罗米抽样显示。并不是全部显示,因为全部展示数据量太大。
    我们也可以使用函数,查看 tp99 这些数据, 结果和 summary 计算的基本一致
histogram_quantile(0.99, http_request_histogram_bucket)
Histogram 根据设置的采集数据的区间进行分类计数
  • Summary
    同直方图
from prometheus_client import Summary
s = Summary('request_latency_seconds', 'Description of summary')
s.observe(4.7)    # Observe 4.7 (seconds in this case)
采集的数据,从小到大排列,显示设置的 % 名次的数值

服务接入普罗米

  • 查看服务监听正不正常
    http://localhost:9090/targets
    看到如果监听服务没有启动, 服务状态就是 down
    go 客户端代码, 模拟某个服务,并定时请 /test 接口
    我们定义了一个总请求量和每次请求的耗时 这两个指标
package main

import (
    "fmt"
    "github.com/prometheus/client_golang/prometheus"
    "github.com/prometheus/client_golang/prometheus/promhttp"
    "log"
    "math/rand"
    "net/http"
    "strconv"
    "time"
)

// prometheus.NewCounterVec  带 Vec的可以多添加 label 参数


// 创建计数器
var httpRequestCount = prometheus.NewCounterVec(
    prometheus.CounterOpts{
        Name: "http_request_count",
        Help: "http request count",
    },
    []string{"endpoint"},
)


// 创建Gauge
var httpRequestGauge = prometheus.NewGaugeVec(
    prometheus.GaugeOpts{
        Name: "http_request_Gauge",
        Help: "http request Gauge",
    },
    []string{"endpoint"},
)



// 创建 summary 指标
var httpRequestSummary= prometheus.NewSummaryVec(
    prometheus.SummaryOpts{  // 指标名称
        Name: "http_request_summary",
        Help: "http request Summary",
        // 客户端计算 百分比分类, 不加这个配置就没数据
        // 后面的 0.05 0.01 代表 百分比误差, 0.5 对应的是 0.05 表示 45% - 55% 的区间都可以作为目标值
        // 假设某个0.5-quantile的值为120,由于设置的误差为0.05,所以120代表的真实quantile是(0.45, 0.55)范围内的某个值。
        // 参考: https://cloud.tencent.com/developer/news/319419
        Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001}, // 返回五分数, 九分数, 九九分数
    },
    []string{"endpoint"},  // label 列表
)


// 创建 Histogram 指标  (也可以使用  histogram_quantile(0.99, http_request_histogram_bucket) 来计算 tp99)
var httpRequestHistogram = prometheus.NewHistogramVec(
    prometheus.HistogramOpts{  // 指标名称
        Name: "http_request_histogram",
        Help: "http request Histogram",
        Buckets: prometheus.LinearBuckets(20, 20, 5), //第一个桶20起,每个桶间隔20,共5个桶。 所以20, 40, 60, 80, 100
    },
    []string{"endpoint"},  // label 列表
)





// 初始化, 注册两个指标
func init() {
    // 请求总数,可计算 用rate 函数计算 qps, 或者计算 label 为枚举类型的百分比, 直接算就好了
    prometheus.MustRegister(httpRequestCount)
    // cpu 使用率这些,直接上传 qps
    prometheus.MustRegister(httpRequestGauge)
    // Summary 可以分析平均耗时 (客户端计算,不确定的状态分布,可以写几个范围)
    prometheus.MustRegister(httpRequestSummary)
    // 直方图, 也可以分析平均耗时 (服务端计算)
    prometheus.MustRegister(httpRequestHistogram)

}


func main() {
    // metrics 接口,用于收集指标
    http.Handle("/metrics", promhttp.Handler())
    // 自测接口, 用于修改指标
    http.HandleFunc("/test0", handler)
    http.HandleFunc("/test1", handler)
    go func() {
        fmt.Println("服务启动")
        err := http.ListenAndServe(":8888", nil)
        if err != nil{
            fmt.Println(err)
        }
    }()
    startClient()
    doneChan := make(chan struct{})
    <-doneChan
}



// 自定义接口
func handler(w http.ResponseWriter, r *http.Request) {
    start := time.Now()
    path := r.URL.Path
    // 请求计数器, 请求路径为标签
    httpRequestCount.WithLabelValues(path).Inc()
    // 模拟处理不同的耗时
    n := rand.Intn(100)
    if n >= 95 {  // 5% 耗时 100
        time.Sleep(100 * time.Millisecond)
    } else { // %95 耗时 50
        time.Sleep(50 * time.Millisecond)
    }
    // 请求耗时 xx ms
    elapsed := (float64)(time.Since(start) / time.Millisecond)
    // 记录当前请求的耗时 Summary
    httpRequestSummary.WithLabelValues(path).Observe(elapsed)
    // 记录平均耗时 直方图
    httpRequestHistogram.WithLabelValues(path).Observe(elapsed)
    httpRequestGauge.WithLabelValues(path).Set(float64(rand.Intn(100)))
}

// 测试脚本
func startClient() {
    sleepTime := 1000
    // 模拟请求频率,每三十秒请求间隔设置 1s, 每两分钟设置为 0.2, 就是 0.2 高频会持续不超过 30秒
    go func() {
        ticker := time.NewTicker(2 * time.Minute)
        for {
            <-ticker.C
            sleepTime = 200
            <-time.After(30 * time.Second)
            sleepTime = 1000
        }
    }()

    for i := 0; i < 100; i++ {
        go func() {
            for {
                sendRequest()
                time.Sleep((time.Duration)(sleepTime) * time.Millisecond)
            }
        }()
    }
}

func sendRequest() {
    api_verson := strconv.Itoa(rand.Intn(2))
    resp, err := http.Get("http://localhost:8888/test" + api_verson)
    if err != nil {
        log.Println(err)
        return
    }
    resp.Body.Close()
}

搜索我们的指标名称, 可以加 label 作为过滤条件 点击 graph 可以看到 请求总数的变化曲线

查看qps 可以使用 自带函数 rate


30s 为计算qps的单个区间, 同样支持 标签过滤

参考: https://cjting.me/2017/03/12/use-prometheus-to-monitor-server/
怎么计算 qps, 和请求耗时, 并对接 grafana

普罗米修斯对接 grafana 前端

  • 新建数据源为 普罗米,然后配置请求数据 url


    安装grafana 后登陆,配置data source 为 普罗米修斯
  • 新建一个 dashborad, 用来展示数据


    我们直接输入 普罗米的查询语句,然后点执行就可以了
  • 展示的数据是根据label 分类展示的


    可以看到展示数据是按照label 展示的,如果不过率的话,就展示所有 label

    当然也可以在一个 dashbroad 展示几个 查询语句,但是建议只展示同一个 指标类型,不然坐标轴不统一

  • 保存dashboad


    编辑之后,需要点保存,不然刷新修改的东西就没了
  • 四种数据类型效果
    可以拖动 panel, 摆放合适的位置, 想要看具体的某个 label 数据,直接点击 tag 就好了。


    我们建立了 几个panel, 用来展示不同的数据

普罗米修斯告警

可以把告警发给 alertmanage 做进一步处理
告警内容:
  • 告警名称:用户需要为告警规则命名,当然对于命名而言,需要能够直接表达出该告警的主要内容
  • 告警规则:告警规则实际上主要由 PromQL 进行定义,其实际意义是当表达式(PromQL)查询结果持续多长时间(During)后出发告警
  • 模板变量
    通过labels.<labelname>变量可以访问当前告警实例中指定标签(就是告警里面 label 那些健值对)的值。value则可以获取当前PromQL表达式计算的样本值(就是判断是不是告警的值)
    比如:
annotations:
      summary: "Instance {{ $labels.instance }} down"
      description: "{{ $labels.instance }} of job {{ $labels.job }} has been down for more than 5 minutes."
  • 设置告警规则
rule_files:
  - /etc/prometheus/rules/*.rules

我们可以设置多个告警文件, 普罗米会默认一分钟(通过 evaluation_interval 设置)跑所以的告警语句

  • 告警状态

样本值为1表示当前告警处于活动状态(pending 就是触发了,但是可能设置持续一分钟才告警,所以为等待状态 或者firing 已经发出告警了),当告警从活动状态转换为非活动状态时,样本值则为0。

  • Alertmanager 接受普罗米的告警
    从普罗米官网 下载 alertmanage 或 docker 安装。
// alertmanager.yml  也有这个配置文件
./alertmanager  启动
  • 关联Prometheus与Alertmanager
alerting:
  alertmanagers:
    - static_configs:
        - targets: ['localhost:9093']
  • Alertmanager配置概述
    略 就是配置一些邮件这些。实际操作的时候在写

一些问题

  • 如何将日志输入?
    简短的回答:不要!改用ELK 堆栈 之类的东西
    更长的答案:Prometheus 是一个收集和处理指标的系统,而不是事件记录系统

  • 如何选择使用哪种数据格式呢
    先说几个简单的:
    qps 可以用 counter 结合rate/irate进行计算
    在线人数,或者服务状态, 温度变化用 Gauge

  • 关于 Summary 里面参数 Objectives 的设置
    参考 https://cloud.tencent.com/developer/news/319419

Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001}, // 返回五分数, 九分数, 九九分数

主要是 0.5: 0.05 说明是 50% 的数据, 其实是 45% - 50% 中的一个数据, 并不能精确到 50% 整,因为数据太多,计算精确到话,太耗性能。关心的 0.99 可以计算准确一点。

https://www.mianshigee.com/tutorial/prometheus-book/grafana-templating.md
怎么导出自己编辑好的模板:

dashboard 导出 模板导入, 如果没有数据,要先手动配置数据源才行 添加变量
编辑变量

可以使用 label_values({job="$job"}, instance) 进行快速筛选某个属性

查询语句引用当前选择的变量值即可

比如上查询了 dfir_service_time_cost_count 这个指标, 所有job的可选值, 简单的正则分组匹配即可

dfir_service_time_cost_count{instance="91yxlv2.tianyi.iflytekauto.cn:80", job="ugc-0-gray", path="/ugc/run", service="UGC"}
或者使用指标里面的属性 自定义图例
如果把字符串拼接到字符串,请用 ${xx} 而不能直接 $xx

为啥用 “=~” 来指定变量呢,这是因为菜单 select 可以是多选,值会是 xx|xx|xx 的格式, ~ 是正则匹配,不加会匹配不到的

变量的值可以支持单选或者多选,当对接Prometheus时,Grafana会自动将$node的值格式化为如“host1|host2|host3”的形式。配合使用PromQL的标签正则匹配“=~”,通过动态改变PromQL从而实现基于标签快速对时间序列进行过滤。

效果展示
  • 关于如何监控主机 cpu 内存等
    node_exporter 用普罗米开源采集工具, 启动就好了
    https://cloud.tencent.com/developer/article/1808172

  • grafana 如何新建不同的用户以及设置他们对dashboard 的权限
    https://www.modb.pro/db/499351
    左下角从组织开始,新建组织,新建用户等,以及设置他们的角色 (每个组织默认会有当前的 admin 用户,并且就算 admin自己也删不掉是新建 组织的超级管理员)
    admin 用户可以管理所有的组织和所有的dashboard 以及 用户
    每个组织下可以有单独的管理员和可编辑权限和只读权限

    可以对每个dashboard 进行编辑,添加已经创建的用户或者组,以及对应的权限
各种监控都有对应的开源的 exporter

相关文章

网友评论

      本文标题:grafana 和 Prometheus 采集数据并展示

      本文链接:https://www.haomeiwen.com/subject/ssthjrtx.html