Prometheus 实现 openGauss 的指标监控(一)第一个监控指标

举报
boyce 发表于 2021/08/28 00:24:41 2021/08/28
【摘要】 Prometheus 是一个开源系统监控和警报工具包。Prometheus 将其指标收集并存储为时间序列数据,即指标信息与记录的时间戳一起存储,以及称为标签的可选键值对。

什么是 Prometheus

Prometheus 是一个开源系统监控和警报工具包。Prometheus 将其指标收集并存储为时间序列数据,即指标信息与记录的时间戳一起存储,以及称为标签的可选键值对。

Prometheus 主要特点是:

  • 一个多维数据模型,具有由指标名称和键/值对标识的时间序列数据
  • PromQL,一种 利用这种维度的灵活查询语言
  • 不依赖分布式存储;单个服务器节点是自治的
  • 时间序列收集通过 HTTP 上的拉模型发生
  • 通过中间网关支持推送时间序列
  • 通过服务发现或静态配置发现目标
  • 多种图形和仪表板支持模式

前面已经介绍如何使用 Docker 方式运行 openGauss,这次我们看下如何使用时下最流行的监控工具 Prometheus 来监控 openGauss,下面开一个非常简单的 openGauss 的 Prometheus Exporter。

Collector

Colletor 是在每次接受请求的时候才会主动收集数据,Collector 是一个接口如下面代码所示,所有收集 metrics 数据的对象都需要实现这个接口,包括Counter, Gauge, Histogram 和 Summary,他们都实现了该接口。很多时候现有的监控指标不能满足我们的监控需求,这时候就需要我们自行实现 Collector 接口,接下来介绍一个简单的实现 Collector 接口的自定义监控指标。

type Collector interface {
    Describe(chan<- *Desc)
    Collect(chan<- Metric)
}

监控 openGauss 版本

定义对象

type OpenGaussManager struct {
	DBVersionUsageDesc *prometheus.Desc
	OpenGaussServer    OpenGaussServer
}

实现 Collector 接口

func (o *OpenGaussManager) Describe(ch chan<- *prometheus.Desc) {
	ch <- o.DBVersionUsageDesc
}

func (o *OpenGaussManager) Collect(ch chan<- prometheus.Metric) {
	host, version := o.FetchDBVersion()
	versions := strings.Split(version, " ")
	pgVer := fmt.Sprintf("%s %s", versions[0], versions[1])
	openGaussVer := fmt.Sprintf("%s %s %s %s", strings.Trim(versions[2], "("), versions[3], versions[4], strings.Trim(versions[5], ")"))
	dbVersionUsage := prometheus.MustNewConstMetric(
		o.DBVersionUsageDesc,
		prometheus.GaugeValue,
		1,
		host,
		pgVer,
		openGaussVer,
	)
	ch <- dbVersionUsage
}

注册监控指标

	reg := prometheus.NewPedanticRegistry()
	openGaussServer := OpenGaussServer{Host: "127.0.0.1", Port: "5432", User: "gaussdb", Password: "Password@123", DBname: "postgres"}
	openGaussManager := NewOpenGaussManager(openGaussServer)
	reg.MustRegister(openGaussManager)

经过以上步骤,基本完成了从自动监控指标到将自定监控指标暴漏给接口的过程。

运行效果

完整代码

代码已经托管到 opengauss_exporter 中,后续有任何更新也将会提交到代码仓库中,待 2021可信“大比武” ·鲲鹏基础软件开发赛道 比赛结束,会把最终版提交到仓库中。

package main

import (
	"fmt"
	"log"
	"net/http"
	"strings"

	"database/sql"

	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/client_golang/prometheus/promhttp"

	_ "gitee.com/opengauss/openGauss-connector-go-pq"
)

var (
	metricPath = "/metrics"
)

func main() {
	reg := prometheus.NewPedanticRegistry()
	openGaussServer := OpenGaussServer{Host: "127.0.0.1", Port: "5432", User: "gaussdb", Password: "Password@123", DBname: "postgres"}
	openGaussManager := NewOpenGaussManager(openGaussServer)
	reg.MustRegister(openGaussManager)

	var landingPage = []byte(`<html>
	<head><title>openGauss exporter</title></head>
	<body>
	<h1>openGauss exporter</h1>
	<p><a href='` + metricPath + `'>Metrics</a></p>
	</body>
	</html>
	`)
	http.Handle(metricPath, promhttp.HandlerFor(reg, promhttp.HandlerOpts{}))
	http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
		w.Header().Set("Content-Type", "text/html; charset=UTF-8") // nolint: errcheck
		w.Write(landingPage)                                       // nolint: errcheck
	})
	http.ListenAndServe(":9101", nil)
}

type OpenGaussServer struct {
	Host     string
	Port     string
	User     string
	Password string
	DBname   string
}

func (o OpenGaussServer) OpenGaussDNS() string {
	return fmt.Sprintf("host=%s port=%s user=%s password=%s dbname=%s sslmode=disable", o.Host, o.Port, o.User, o.Password, o.DBname)
}

type OpenGaussManager struct {
	DBVersionUsageDesc *prometheus.Desc
	OpenGaussServer    OpenGaussServer
}

func NewOpenGaussManager(openGaussServer OpenGaussServer) *OpenGaussManager {
	dbVersionUsageDesc := prometheus.NewDesc(
		"opengauss_db_current_version",
		"The current version of openGauss",
		[]string{"host", "pg_ver", "version"},
		make(map[string]string),
	)
	return &OpenGaussManager{
		DBVersionUsageDesc: dbVersionUsageDesc,
		OpenGaussServer:    openGaussServer,
	}
}

func (o *OpenGaussManager) Describe(ch chan<- *prometheus.Desc) {
	ch <- o.DBVersionUsageDesc
}

func (o *OpenGaussManager) Collect(ch chan<- prometheus.Metric) {
	host, version := o.FetchDBVersion()
	versions := strings.Split(version, " ")
	pgVer := fmt.Sprintf("%s %s", versions[0], versions[1])
	openGaussVer := fmt.Sprintf("%s %s %s %s", strings.Trim(versions[2], "("), versions[3], versions[4], strings.Trim(versions[5], ")"))
	dbVersionUsage := prometheus.MustNewConstMetric(
		o.DBVersionUsageDesc,
		prometheus.GaugeValue,
		1,
		host,
		pgVer,
		openGaussVer,
	)
	ch <- dbVersionUsage
}

func (o *OpenGaussManager) FetchDBVersion() (host string, version string) {
	connStr := o.OpenGaussServer.OpenGaussDNS()
	db, err := sql.Open("opengauss", connStr)
	if err != nil {
		log.Fatal(err)
	}
	err = db.QueryRow("select version();").Scan(&version)
	if err != nil {
		log.Fatal(err)
	}
	return
}
【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。