Prometheus开发中间件Exporter过程详解


Posted in Python onNovember 30, 2020

Prometheus 为开发这提供了客户端工具,用于为自己的中间件开发Exporter,对接Prometheus 。

目前支持的客户端

  • Go
  • Java
  • Python
  • Ruby

以go为例开发自己的Exporter

依赖包的引入

工程结构

[root@node1 data]# tree exporter/
exporter/
├── collector
│ └── node.go
├── go.mod
└── main.go

引入依赖包

require (
  github.com/modern-go/concurrent v0.0.0-20180306012644-bacd9c7ef1dd // indirect
  github.com/modern-go/reflect2 v1.0.1 // indirect
  github.com/prometheus/client_golang v1.1.0
    //借助gopsutil 采集主机指标
  github.com/shirou/gopsutil v0.0.0-20190731134726-d80c43f9c984
)

main.go

package main

import (
  "cloud.io/exporter/collector"
  "fmt"
  "github.com/prometheus/client_golang/prometheus"
  "github.com/prometheus/client_golang/prometheus/promhttp"
  "net/http"
)

func init() {
   //注册自身采集器
  prometheus.MustRegister(collector.NewNodeCollector())
}
func main() {
  http.Handle("/metrics", promhttp.Handler())
  if err := http.ListenAndServe(":8080", nil); err != nil {
    fmt.Printf("Error occur when start server %v", err)
  }
}

为了能看清结果我将默认采集器注释,位置registry.go

func init() {
  //MustRegister(NewProcessCollector(ProcessCollectorOpts{}))
  //MustRegister(NewGoCollector())
}

/collector/node.go

代码中涵盖了Counter、Gauge、Histogram、Summary四种情况,一起混合使用的情况,具体的说明见一下代码中。

package collector

import (
  "github.com/prometheus/client_golang/prometheus"
  "github.com/shirou/gopsutil/host"
  "github.com/shirou/gopsutil/mem"
  "runtime"
  "sync"
)

var reqCount int32
var hostname string
type NodeCollector struct {
  requestDesc  *prometheus.Desc  //Counter
  nodeMetrics   nodeStatsMetrics //混合方式 
  goroutinesDesc *prometheus.Desc  //Gauge
  threadsDesc  *prometheus.Desc //Gauge
  summaryDesc  *prometheus.Desc //summary
  histogramDesc *prometheus.Desc  //histogram
  mutex     sync.Mutex
}
//混合方式数据结构
type nodeStatsMetrics []struct {
  desc  *prometheus.Desc
  eval  func(*mem.VirtualMemoryStat) float64
  valType prometheus.ValueType
}

//初始化采集器
func NewNodeCollector() prometheus.Collector {
  host,_:= host.Info()
  hostname = host.Hostname
  return &NodeCollector{
    requestDesc: prometheus.NewDesc(
      "total_request_count",
      "请求数",
      []string{"DYNAMIC_HOST_NAME"}, //动态标签名称
      prometheus.Labels{"STATIC_LABEL1":"静态值可以放在这里","HOST_NAME":hostname}),
    nodeMetrics: nodeStatsMetrics{
      {
        desc: prometheus.NewDesc(
          "total_mem",
          "内存总量",
          nil, nil),
        valType: prometheus.GaugeValue,
        eval: func(ms *mem.VirtualMemoryStat) float64 { return float64(ms.Total) / 1e9 },
      },
      {
        desc: prometheus.NewDesc(
          "free_mem",
          "内存空闲",
          nil, nil),
        valType: prometheus.GaugeValue,
        eval: func(ms *mem.VirtualMemoryStat) float64 { return float64(ms.Free) / 1e9 },
      },

    },
    goroutinesDesc:prometheus.NewDesc(
      "goroutines_num",
      "协程数.",
      nil, nil),
    threadsDesc: prometheus.NewDesc(
      "threads_num",
      "线程数",
      nil, nil),
    summaryDesc: prometheus.NewDesc(
      "summary_http_request_duration_seconds",
      "summary类型",
      []string{"code", "method"},
      prometheus.Labels{"owner": "example"},
    ),
    histogramDesc: prometheus.NewDesc(
      "histogram_http_request_duration_seconds",
      "histogram类型",
      []string{"code", "method"},
      prometheus.Labels{"owner": "example"},
    ),
  }
}

// Describe returns all descriptions of the collector.
//实现采集器Describe接口
func (n *NodeCollector) Describe(ch chan<- *prometheus.Desc) {
  ch <- n.requestDesc
  for _, metric := range n.nodeMetrics {
    ch <- metric.desc
  }
  ch <- n.goroutinesDesc
  ch <- n.threadsDesc
  ch <- n.summaryDesc
  ch <- n.histogramDesc
}
// Collect returns the current state of all metrics of the collector.
//实现采集器Collect接口,真正采集动作
func (n *NodeCollector) Collect(ch chan<- prometheus.Metric) {
  n.mutex.Lock()
  ch <- prometheus.MustNewConstMetric(n.requestDesc,prometheus.CounterValue,0,hostname)
  vm, _ := mem.VirtualMemory()
  for _, metric := range n.nodeMetrics {
    ch <- prometheus.MustNewConstMetric(metric.desc, metric.valType, metric.eval(vm))
  }

  ch <- prometheus.MustNewConstMetric(n.goroutinesDesc, prometheus.GaugeValue, float64(runtime.NumGoroutine()))

  num, _ := runtime.ThreadCreateProfile(nil)
  ch <- prometheus.MustNewConstMetric(n.threadsDesc, prometheus.GaugeValue, float64(num))

  //模拟数据
  ch <- prometheus.MustNewConstSummary(
    n.summaryDesc,
    4711, 403.34,
    map[float64]float64{0.5: 42.3, 0.9: 323.3},
    "200", "get",
  )

  //模拟数据
  ch <- prometheus.MustNewConstHistogram(
      n.histogramDesc,
      4711, 403.34,
      map[float64]uint64{25: 121, 50: 2403, 100: 3221, 200: 4233},
      "200", "get",
    )
  n.mutex.Unlock()
}

执行的结果http://127.0.0.1:8080/metrics

Prometheus开发中间件Exporter过程详解

以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持三水点靠木。

Python 相关文章推荐
Python转换HTML到Text纯文本的方法
Jan 15 Python
python常用知识梳理(必看篇)
Mar 23 Python
python 垃圾收集机制的实例详解
Aug 20 Python
利用python为运维人员写一个监控脚本
Mar 25 Python
Python基于TCP实现会聊天的小机器人功能示例
Apr 09 Python
Python读取txt文件数据的方法(用于接口自动化参数化数据)
Jun 27 Python
Python Excel处理库openpyxl使用详解
May 09 Python
PyCharm搭建Spark开发环境实现第一个pyspark程序
Jun 13 Python
Python 限定函数参数的类型及默认值方式
Dec 24 Python
Python程序控制语句用法实例分析
Jan 14 Python
使用Python实现牛顿法求极值
Feb 10 Python
python mock测试的示例
Oct 19 Python
python实现猜拳游戏项目
Nov 30 #Python
Python解析微信dat文件的方法
Nov 30 #Python
Python应用自动化部署工具Fabric原理及使用解析
Nov 30 #Python
使用python将微信image下.dat文件解密为.png的方法
Nov 30 #Python
Python 微信公众号文章爬取的示例代码
Nov 30 #Python
python爬虫工具例举说明
Nov 30 #Python
编译 pycaffe时报错:fatal error: numpy/arrayobject.h没有那个文件或目录
Nov 29 #Python
You might like
PHP.MVC的模板标签系统(一)
2006/09/05 PHP
php基础知识:类与对象(3) 构造函数和析构函数
2006/12/13 PHP
php error_log 函数的使用
2009/04/13 PHP
php代码审计比较有意思的例子
2014/05/07 PHP
php与flash as3 socket通信传送文件实现代码
2014/08/16 PHP
php实现快速对二维数组某一列进行组装的方法小结
2019/12/04 PHP
jQuery实现单行文字间歇向上滚动源代码
2013/06/02 Javascript
jquery制作搜狐快站页面效果示例分享
2014/02/21 Javascript
JS数组的遍历方式for循环与for...in
2014/07/31 Javascript
js怎么判断flash swf文件是否加载完毕
2014/08/14 Javascript
一个JavaScript用逗号分割字符串实例
2014/09/22 Javascript
本人自用的global.js库源码分享
2015/02/28 Javascript
javascript最基本的函数汇总
2015/06/25 Javascript
使用jquery插件qrcode生成二维码
2015/10/22 Javascript
Boostrap入门准备之border box
2016/05/09 Javascript
angularjs 源码解析之scope
2016/08/22 Javascript
一步步教你利用webpack如何搭一个vue脚手架(超详细讲解和注释)
2018/01/08 Javascript
如何以Angular的姿势打开Font-Awesome详解
2018/04/22 Javascript
js实现京东秒杀倒计时功能
2019/01/21 Javascript
解决vue单页面应用进入页面加载所有 js 的问题
2020/08/12 Javascript
[56:35]DOTA2上海特级锦标赛C组小组赛#1 OG VS Archon第二局
2016/02/27 DOTA
python学习教程之使用py2exe打包
2017/09/24 Python
TensorFlow实现模型评估
2018/09/07 Python
对numpy中的where方法嵌套使用详解
2018/10/31 Python
Python 实现打印单词的菱形字符图案
2020/04/12 Python
删除pycharm鼠标右键快捷键打开项目的操作
2021/01/16 Python
Nike加拿大官网:Nike.com (CA)
2019/04/09 全球购物
莫斯科购买书籍网站:Book24
2020/01/12 全球购物
求职信写作要突出重点
2014/01/01 职场文书
2014领导班子“四风问题”对照检查材料思想汇报(执法局)
2014/09/21 职场文书
民主生活会对照检查材料
2014/09/22 职场文书
2014年度培训工作总结
2014/11/27 职场文书
公司员工宿舍管理制度
2015/08/07 职场文书
2016十一国庆节慰问信
2015/12/01 职场文书
2019年市场部个人述职报告(三篇)
2019/10/23 职场文书
Nginx 安装SSL证书完成HTTPS部署
2022/04/28 Servers