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学习之第三方包安装方法(两种方法)
Jul 30 Python
python利用urllib实现爬取京东网站商品图片的爬虫实例
Aug 24 Python
Python 12306抢火车票脚本
Feb 07 Python
python pandas中对Series数据进行轴向连接的实例
Jun 08 Python
Python3调用百度AI识别图片中的文字功能示例【测试可用】
Mar 13 Python
快速排序的四种python实现(推荐)
Apr 03 Python
Python识别快递条形码及Tesseract-OCR使用详解
Jul 15 Python
Python中最好用的命令行参数解析工具(argparse)
Aug 23 Python
python 爬取古诗文存入mysql数据库的方法
Jan 08 Python
详解python itertools功能
Feb 07 Python
通过python连接Linux命令行代码实例
Feb 18 Python
Python+Selenium实现读取网易邮箱验证码
Mar 13 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连接SQLServer2005 的问题解决方法
2010/07/19 PHP
php页面缓存ob系列函数介绍
2012/10/18 PHP
PHP使用DirectoryIterator显示下拉文件列表的方法
2015/03/13 PHP
完美解决php 导出excle的.csv格式的数据时乱码问题
2017/02/18 PHP
php 处理png图片白色背景色改为透明色的实例代码
2018/12/10 PHP
如何在Laravel之外使用illuminate组件详解
2020/09/20 PHP
获取css样式表内样式的js函数currentStyle(IE),defaultView(FF)
2011/02/14 Javascript
原生javascript和jquery判断浏览器版本等信息
2013/07/04 Javascript
js判断60秒以及倒计时示例代码
2014/01/24 Javascript
js通过location.search来获取页面传来的参数
2014/09/11 Javascript
7个有用的jQuery代码片段分享
2015/05/19 Javascript
JavaScrip常见的一些算法总结
2015/12/28 Javascript
学习AngularJs:Directive指令用法(完整版)
2016/04/26 Javascript
Bootstrap教程JS插件弹出框学习笔记分享
2016/05/17 Javascript
JavaScript对象数组排序实例方法浅析
2016/06/15 Javascript
jquery的父、子、兄弟节点查找,节点的子节点循环方法
2016/12/07 Javascript
JavaScript中利用for循环遍历数组
2017/01/15 Javascript
bootstrap table实现x-editable的行单元格编辑及解决数据Empty和支持多样式问题
2017/08/10 Javascript
JQuery 获取多个select标签option的text内容(实例)
2017/09/07 jQuery
新手快速上手webpack4打包工具的使用详解
2019/01/28 Javascript
微信小程序可滑动周日历组件使用详解
2019/10/21 Javascript
忘记ftp密码使用python ftplib库暴力破解密码的方法示例
2014/01/22 Python
python网络编程学习笔记(五):socket的一些补充
2014/06/09 Python
举例讲解Python中的算数运算符的用法
2015/05/13 Python
Python性能提升之延迟初始化
2016/12/04 Python
python利用高阶函数实现剪枝函数
2018/03/20 Python
基于Python和PyYAML读取yaml配置文件数据
2020/01/13 Python
tensorflow将图片保存为tfrecord和tfrecord的读取方式
2020/02/17 Python
CSS3制作气泡对话框的实例教程
2016/05/10 HTML / CSS
关于HTML5你必须知道的28个新特性,新技巧以及新技术
2012/05/28 HTML / CSS
体育教学随笔感言
2014/02/24 职场文书
爱国主义教育活动总结
2014/05/07 职场文书
建设单位项目负责人任命书
2014/06/06 职场文书
活动总结结尾怎么写
2014/08/30 职场文书
初中作文评语
2014/12/25 职场文书
行政处罚告知书
2015/07/01 职场文书