一、先容
- 源码步调基于dameng_exporter源码解说,看完本篇文章可以直接举行二次开发。
- dameng exporter的开源地址:点击跳转(可直接对接prometheus+grafana 提供表盘)
- 开发一个exporter 实在就是写一个 Metric格式的接口页面,等待prometheus访问就可以了。
- Metric(指标)是用于描述和记录系统、应用程序或服务状态的量化数据。Metric提供了对系统运行状态和性能的可量化度量,资助监控系统的健康状态、性能表现和行为模式。
1. Metric 的主要特征包罗
- 名称(Name): 指标的唯一标识符,用于在监控系统中识别和区分不同的指标。
- 标签(Labels): 用于附加到指标的键值对元数据,可以提供更详细的上下文信息。标签使得指标能够根据不同维度举行分组和过滤。
- 值(Value): 指标的详细数值或测量结果,反映了被度量对象的某种状态、计数或度量。
- 时间戳(Timestamp): 记录指标值的时间点或时间范围,用于分析指标变革的趋势和时间干系性。
2. Metric 的分类
Metrics 可以按照不同的维度举行分类,主要包罗以下几类:
- 计数器(Counter): 计数器用于累计某个变乱发生的次数或增量。它通常只能递增,不能减少。比方,HTTP哀求数、任务完成数等。
- 计量器(Gauge): 计量器表现一个可变的数值,它可以增加或减少。通常用于表现系统状态或资源利用率,如内存利用量、CPU利用率等。
- 直方图(Histogram): 直方图用于统计和分析观察值的分布环境。它将观察值按照预定义的桶(Bucket)范围举行分组统计,并记录每个桶中的观察值数目。
- 摘要(Summary): 摘要雷同于直方图,但是它除了统计桶中的观察值数目外,还会记录观察值的总和、计数和其他分位数(如中位数、95th百分位数等)。
二、简化版的Metric
- 最浅易版的Counter范例指标方式,只有这么几行代码。
- 主要是三个函数也就是三步调
1) prometheus.NewCounter()声明一个自己的指标
2) prometheus.MustRegister() 将自定义的指标注册到prometheus
3) http.Handle(“/metrics”, promhttp.Handler()) 把prometheus的handler交给接口即可
- var (
- requestsTotal = prometheus.NewCounter(
- prometheus.CounterOpts{
- Name: "http_requests_total",
- Help: "Total number of HTTP requests processed",
- },
- )
- )
- func main() {
- // 注册指标
- prometheus.MustRegister(requestsTotal)
- // 模拟请求处理
- http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
- requestsTotal.Inc() // 每次请求增加计数器
- fmt.Fprintf(w, "Hello, World!")
- })
- // 启动 HTTP 服务,暴露指标
- http.Handle("/metrics", promhttp.Handler())
- log.Fatal(http.ListenAndServe(":8080", nil))
- }
复制代码 三、标准版的Metric
1. 目录结构
- collector
- //注册类
- collector.go
- db_sessions_collector.go
- //启动类
- dameng_exporter.go
复制代码 2. main函数(dameng_exporter.go)
注:这里利用的是自己的Registry,特殊重要。并且注册指标方式不同
- func main() {
- // 创建一个新的注册器,如果使用系统自带的Registry,会多余出很多默认的go指标
- reg := prometheus.NewRegistry()
- //注册指标,这里的collector是我的项目目录
- collector.RegisterCollectors(reg)
- //设置metric路径
- http.Handle("/metrics", promhttp.HandlerFor(reg, promhttp.HandlerOpts{}))
- }
复制代码 3. 注册指标(collector.go)
- 这里为什么声明MetricCollector接口,附录章节写缘故起因
- // MetricCollector 接口
- type MetricCollector interface {
- Describe(ch chan<- *prometheus.Desc)
- Collect(ch chan<- prometheus.Metric)
- }
- var (
- collectors []prometheus.Collector
- registerMux sync.Mutex
- )
- //注册指标
- func RegisterCollectors(reg *prometheus.Registry) {
- //加锁
- registerMux.Lock()
- defer registerMux.Unlock()
-
- //连接DM数据库
- db, err := sql.Open("dm", "dm://SYSDBA:SYSDBA@localhost:5236?autoCommit=true")
-
- //将指标存放到collectors数组中
- collectors = append(collectors, NewDBSessionsCollector(db))
-
- //把collectors数组中指标注册
- for _, collector := range collectors {
- reg.MustRegister(collector)
- }
-
- }
复制代码 4.指标采集器(db_sessions_collector.go)
- 实现MetricCollector的两个接口 Describe 和 Collect, Describe传的channel,Collect是采集逻辑
- Collect函数我是直接连接DM数据库执行SQL采集指标
- NewDBSessionsCollector中的返回值 就是我们的metric指标的格式。四个参数已经在代码中标明白,这里只是声明lable的标签并不赋值
- Collect函数的prometheus.MustNewConstMetric()函数,这步是给事先定义的标签赋值,必要一一对应才行。
- Collect函数的prometheus.MustNewConstMetric()函数的prometheus.GaugeValue这个参数指定就是Metric的分类
- package collector
- import (
- "context"
- "dameng_exporter/config"
- "dameng_exporter/logger"
- "database/sql"
- "github.com/prometheus/client_golang/prometheus"
- )
- type DBSessionsCollector struct {
- db *sql.DB
- metricDesc *prometheus.Desc
- }
- func NewDBSessionsCollector(db *sql.DB) MetricCollector {
- return &DBSessionsCollector{
- db: db,
- metricDesc: prometheus.NewDesc(
- "db_sessions", //key便签值
- "Number of database sessions",//辅助信息
- []string{"host_name"}, // 添加标签
- nil,
- ),
- }
- }
- func (c *DBSessionsCollector) Describe(ch chan<- *prometheus.Desc) {
- ch <- c.metricDesc
- }
- func (c *DBSessionsCollector) Collect(ch chan<- prometheus.Metric) {
- // ping 一下判断连接是否有问题
- if err := checkDBConnection(c.db); err != nil {
- return
- }
- //设置超时时间的ctx对象
- ctx, cancel := context.WithTimeout(context.Background(), timeout)
- defer cancel()
- var value float64
- err := c.db.QueryRowContext(ctx, "SELECT COUNT(*) FROM v$sessions").Scan(&value)
- if err != nil {
- handleDbQueryError(err)
- return
- }
- logger.Logger.Debugf("DBSessionsCollector: %v", value)
- ch <- prometheus.MustNewConstMetric(c.metricDesc, prometheus.GaugeValue, value, config.GetHostName())
- }
复制代码 四、附录
为什么声明MetricCollector接口?
- prometheus注册必要reg.MustRegister函数必要传Collector范例
- Collector有两个接口Describe(chan<- *Desc)以及Collect(chan<- Metric)
- 因为要传这个以是先定义同接口的MetricCollector范例
- 写的每一个指标都必要实现这两个接口
如何连接DM数据库
大概如下,详细的参考DM官网:https://eco.dameng.com/document/dm/zh-cn/app-dev/go_dm.html
- // 引用Go标准库sql和dm驱动包,后面的示例不再赘述
- import (
- "database/sql"
- _ "dm"
- )
- db, err := sql.Open("dm", "dm://SYSDBA:SYSDBA@localhost:5236?autoCommit=true")
复制代码 免责声明:如果侵犯了您的权益,请联系站长,我们会及时删除侵权内容,谢谢合作!更多信息从访问主页:qidao123.com:ToB企服之家,中国第一个企服评测及商务社交产业平台。 |