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 相关文章推荐
pyside写ui界面入门示例
Jan 22 Python
Python操作RabbitMQ服务器实现消息队列的路由功能
Jun 29 Python
Python SQLite3数据库日期与时间常见函数用法分析
Aug 14 Python
Python基于pyCUDA实现GPU加速并行计算功能入门教程
Jun 19 Python
python 通过 socket 发送文件的实例代码
Aug 14 Python
使用urllib库的urlretrieve()方法下载网络文件到本地的方法
Dec 19 Python
Python 获取 datax 执行结果保存到数据库的方法
Jul 11 Python
对Django中内置的User模型实例详解
Aug 16 Python
python中的数组赋值与拷贝的区别详解
Nov 26 Python
Python 内置变量和函数的查看及说明介绍
Dec 25 Python
如何配置关联Python 解释器 Anaconda的教程(图解)
Apr 30 Python
浅析Python面向对象编程
Jul 10 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定时自动生成静态HTML的实现代码
2010/06/20 PHP
php四种基础算法代码实例
2013/10/29 PHP
php实现邮件发送并带有附件
2014/01/24 PHP
php面向对象中的魔术方法中文说明
2014/03/04 PHP
php中隐形字符65279(utf-8的BOM头)问题
2014/08/16 PHP
PHP预定义变量9大超全局数组用法详解
2016/04/23 PHP
PHP实现页面静态化的超简单方法
2016/09/06 PHP
php基于curl主动推送最新内容给百度收录的方法
2016/10/14 PHP
php抽象方法和抽象类实例分析
2016/12/07 PHP
Yii框架分页实现方法详解
2017/05/20 PHP
新浪刚打开页面出来的全屏广告代码
2007/04/02 Javascript
替代window.event.srcElement效果的可兼容性的函数
2009/12/18 Javascript
js控制浏览器全屏示例代码
2014/02/20 Javascript
JS判断客服QQ号在线还是离线状态的方法
2015/01/13 Javascript
javascript与jquery动态创建html元素示例
2016/07/25 Javascript
关于Vue.js一些问题和思考学习笔记(1)
2016/12/02 Javascript
微信小程序 picker 组件详解及简单实例
2017/01/10 Javascript
jquery实现回车键触发事件(实例讲解)
2017/11/21 jQuery
jQuery实现炫丽的3d旋转星空效果
2018/07/04 jQuery
vue项目中定义全局变量、函数的几种方法
2019/11/08 Javascript
进一步了解Python中的XML 工具
2015/04/13 Python
详解Python中的Cookie模块使用
2015/07/06 Python
详解Pytorch 使用Pytorch拟合多项式(多项式回归)
2018/05/24 Python
解决pandas使用read_csv()读取文件遇到的问题
2018/06/15 Python
python区分不同数据类型的方法
2019/10/14 Python
Python pip安装模块提示错误解决方案
2020/05/22 Python
Anaconda详细安装步骤图文教程
2020/11/12 Python
详解CSS3的opacity属性设置透明效果的用法
2016/05/09 HTML / CSS
Solaris操作系统的线程机制
2012/12/23 面试题
vue+django实现下载文件的示例
2021/03/24 Vue.js
党风廉政承诺书
2014/03/27 职场文书
1亿有多大教学反思
2014/05/01 职场文书
2014小学语文教师个人工作总结
2014/12/03 职场文书
2015年党建工作目标责任书
2015/05/08 职场文书
社区服务活动感想
2015/08/11 职场文书
反腐倡廉心得体会2016
2016/01/13 职场文书