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类的基础入门知识
Nov 24 Python
Python标准库os.path包、glob包使用实例
Nov 25 Python
python批量提取word内信息
Aug 09 Python
Python随机生成带特殊字符的密码
Mar 02 Python
Python中第三方库Requests库的高级用法详解
Mar 12 Python
python 3利用BeautifulSoup抓取div标签的方法示例
May 28 Python
浅谈flask截获所有访问及before/after_request修饰器
Jan 18 Python
深入理解Python异常处理的哲学
Feb 01 Python
TensorFlow实现从txt文件读取数据
Feb 05 Python
使用Pycharm分段执行代码
Apr 15 Python
Python logging模块原理解析及应用
Aug 13 Python
Django实现在线无水印抖音视频下载(附源码及地址)
May 06 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 日志缩略名的创建函数代码
2010/05/26 PHP
PHP句法规则详解 入门学习
2011/11/09 PHP
基于php权限分配的实现代码
2013/04/28 PHP
探讨:如何通过stats命令分析Memcached的内部状态
2013/06/14 PHP
使用PHP导出Redis数据到另一个Redis中的代码
2014/03/12 PHP
php实现图片文件与下载文件防盗链的方法
2014/11/03 PHP
CodeIgniter读写分离实现方法详解
2016/01/20 PHP
PHP调用接口用post方法传送json数据的实例
2018/05/31 PHP
在laravel中实现事务回滚的方法
2019/10/10 PHP
javascript里模拟sleep(两种实现方式)
2013/01/25 Javascript
让浏览器DOM元素最后加载的js方法
2014/07/29 Javascript
jQuery原型属性和原型方法详解
2015/07/07 Javascript
JavaScript实现百度搜索框效果
2020/03/26 Javascript
jQuery实现图片上传预览效果功能完整实例【测试可用】
2018/05/28 jQuery
详解Vue组件之作用域插槽
2018/11/22 Javascript
vue.js的双向数据绑定Object.defineProperty方法的神奇之处
2019/01/18 Javascript
React实现todolist功能
2020/12/28 Javascript
Python字符遍历的艺术
2008/09/06 Python
python控制台英汉汉英电子词典
2020/04/23 Python
Python入门篇之正则表达式
2014/10/20 Python
python3.x实现发送邮件功能
2018/05/22 Python
python3.4实现邮件发送功能
2018/05/28 Python
numpy返回array中元素的index方法
2018/06/27 Python
python基于celery实现异步任务周期任务定时任务
2019/12/30 Python
在pytorch中对非叶节点的变量计算梯度实例
2020/01/10 Python
Python 给下载文件显示进度条和下载时间的实现
2020/04/02 Python
python脚本监控logstash进程并邮件告警实例
2020/04/28 Python
10款最佳Python开发工具推荐,每一款都是神器
2020/10/15 Python
localStorage 设置过期时间的方法实现
2018/12/21 HTML / CSS
canvas中普通动效与粒子动效的实现代码示例
2019/01/03 HTML / CSS
印度在线内衣和时尚目的地:Zivame
2017/09/28 全球购物
车间班组长的职责
2013/12/13 职场文书
房地产开盘策划方案
2014/02/10 职场文书
2014年幼儿园国庆主题活动方案
2014/09/16 职场文书
医院护士党的群众路线教育实践活动对照检查材料思想汇报
2014/10/04 职场文书
Python基础详解之描述符
2021/04/28 Python