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实现异步回调机制代码分享
Jan 10 Python
python比较两个列表大小的方法
Jul 11 Python
Python实现ping指定IP的示例
Jun 04 Python
一步步教你用python的scrapy编写一个爬虫
Apr 17 Python
Python3.5内置模块之time与datetime模块用法实例分析
Apr 27 Python
python multiprocessing模块用法及原理介绍
Aug 20 Python
Python笔记之观察者模式
Nov 20 Python
nginx+uwsgi+django环境搭建的方法步骤
Nov 25 Python
kafka监控获取指定topic的消息总量示例
Dec 23 Python
解决pycharm不能自动补全第三方库的函数和属性问题
Mar 12 Python
Jupyter notebook如何修改平台字体
May 13 Python
python+opencv3.4.0 实现HOG+SVM行人检测的示例代码
Jan 28 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
我的论坛源代码(六)
2006/10/09 PHP
php adodb介绍
2009/03/19 PHP
PHP5.3.1 不再支持ISAPI
2010/01/08 PHP
JQuery 控制内容长度超出规定长度显示省略号
2014/05/23 Javascript
JS在可编辑的div中的光标位置插入内容的方法
2014/11/20 Javascript
jQuery的css() 方法使用指南
2015/05/03 Javascript
JavaScript比较当前时间是否在指定时间段内的方法
2016/08/02 Javascript
bootstrap-table实现服务器分页的示例 (spring 后台)
2017/09/01 Javascript
解决npm管理员身份install时出现权限的问题
2018/03/16 Javascript
js中DOM事件绑定分析
2018/03/18 Javascript
ssm+vue前后端分离框架整合实现(附源码)
2020/07/08 Javascript
使用element-ui +Vue 解决 table 里包含表单验证的问题
2020/07/17 Javascript
jquery+ajax实现异步上传文件显示进度条
2020/08/17 jQuery
vue实现div可拖动位置也可改变盒子大小的原理
2020/09/16 Javascript
[04:40]2016个国际邀请赛中国区预选赛场地——华西村观战指南
2016/06/25 DOTA
python持久性管理pickle模块详细介绍
2015/02/18 Python
对于Python的Django框架部署的一些建议
2015/04/09 Python
Python正则表达式教程之二:捕获篇
2017/03/02 Python
Python代码块批量添加Tab缩进的方法
2018/06/25 Python
Django使用中间件解决前后端同源策略问题
2019/09/02 Python
用OpenCV将视频分解成单帧图片,图片合成视频示例
2019/12/10 Python
python orm 框架中sqlalchemy用法实例详解
2020/02/02 Python
Python使用pickle进行序列化和反序列化的示例代码
2020/09/22 Python
Django自带的用户验证系统实现
2020/12/18 Python
python中HTMLParser模块知识点总结
2021/01/25 Python
新秀丽官方旗舰店:Samsonite拉杆箱、双肩包、皮具
2018/03/05 全球购物
初一科学教学反思
2014/01/27 职场文书
主管竞聘书范文
2014/03/31 职场文书
公司合作意向书
2014/04/01 职场文书
主持人演讲稿
2014/05/13 职场文书
介绍信怎么写
2015/05/05 职场文书
2016年社区创先争优活动总结
2016/04/05 职场文书
2019员工保密协议书(3篇)
2019/09/23 职场文书
HAM-2000摩机图
2021/04/22 无线电
Ubuntu安装Mysql+启用远程连接的完整过程
2022/06/21 Servers
Win11 PC上的Outlook搜索错误怎么办?
2022/07/15 数码科技