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统计日志ip访问数的方法
Jul 06 Python
python下读取公私钥做加解密实例详解
Mar 29 Python
python实现用户答题功能
Jan 17 Python
Pytorch反向求导更新网络参数的方法
Aug 17 Python
使用Python脚本zabbix自定义key监控oracle连接状态
Aug 28 Python
在Python 的线程中运行协程的方法
Feb 24 Python
Python接口测试结果集实现封装比较
May 01 Python
Tensorflow加载Vgg预训练模型操作
May 26 Python
python 实现单例模式的5种方法
Sep 23 Python
python 实现aes256加密
Nov 27 Python
python推导式的使用方法实例
Feb 28 Python
python模块与C和C++动态库相互调用实现过程示例
Nov 02 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中strtotime函数使用方法详解
2011/11/27 PHP
PHP MPDF中文乱码的解决方式
2015/12/08 PHP
PHP7.1方括号数组符号多值复制及指定键值赋值用法分析
2016/09/26 PHP
vmware linux系统安装最新的php7图解
2019/04/14 PHP
PHP 出现 http500 错误的解决方法
2021/03/09 PHP
自己动手制作jquery插件之自动添加删除行的实现
2011/10/13 Javascript
JavaScript 用Node.js写Shell脚本[译]
2012/09/20 Javascript
js仿微信抢红包功能
2020/09/25 Javascript
Javascript实现运算符重载详解
2018/04/07 Javascript
微信小程序实现文字无限轮播效果
2018/12/28 Javascript
Vue匿名插槽与作用域插槽的合并和覆盖行为
2019/04/22 Javascript
iphone刘海屏页面适配方法
2019/05/07 Javascript
mpvue实现左侧导航与右侧内容的联动
2019/10/21 Javascript
vue实现网络图片瀑布流 + 下拉刷新 + 上拉加载更多(步骤详解)
2020/01/14 Javascript
[02:09]DOTA2辉夜杯 EHOME夺冠举杯现场
2015/12/28 DOTA
[45:18]完美世界DOTA2联赛循环赛 PXG vs IO 第二场 11.06
2020/11/09 DOTA
Python程序员开发中常犯的10个错误
2014/07/07 Python
Python中的Classes和Metaclasses详解
2015/04/02 Python
python字典get()方法用法分析
2015/04/17 Python
python 实现一次性在文件中写入多行的方法
2019/01/28 Python
浅谈pandas筛选出表中满足另一个表所有条件的数据方法
2019/02/08 Python
Python unittest生成测试报告过程解析
2020/09/08 Python
python解决OpenCV在读取显示图片的时候闪退的问题
2021/02/23 Python
纯CSS3代码实现switch滑动开关按钮效果
2016/08/30 HTML / CSS
移动HTML5前端框架—MUI的使用
2017/12/18 HTML / CSS
英文自荐信
2013/12/19 职场文书
《九色鹿》教学反思
2014/02/27 职场文书
学生不讲诚信检讨书
2014/09/29 职场文书
开除通知书范本
2015/04/25 职场文书
卫生院义诊活动总结
2015/05/07 职场文书
2015秋季开学典礼演讲稿
2015/07/16 职场文书
幼儿园保教工作总结2015
2015/10/15 职场文书
Vue中插槽slot的使用方法与应用场景详析
2021/06/08 Vue.js
详解如何用Python实现感知器算法
2021/06/18 Python
每日六道java新手入门面试题,通往自由的道路
2021/06/30 Java/Android
了解Kubernetes中的Service和Endpoint
2022/04/01 Servers