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多进程编程技术实例分析
Sep 16 Python
Python使用ftplib实现简易FTP客户端的方法
Jun 03 Python
Python基于递归实现电话号码映射功能示例
Apr 13 Python
详解Python 数据库的Connection、Cursor两大对象
Jun 25 Python
Python 16进制与中文相互转换的实现方法
Jul 09 Python
在ubuntu16.04中将python3设置为默认的命令写法
Oct 31 Python
Python Pexpect库的简单使用方法
Jan 29 Python
Python的条件表达式和lambda表达式实例
Jan 31 Python
使用python制作一个为hex文件增加版本号的脚本实例
Jun 12 Python
python3 中的字符串(单引号、双引号、三引号)以及字符串与数字的运算
Jul 18 Python
python 基于opencv操作摄像头
Dec 24 Python
python设置 matplotlib 正确显示中文的四种方式
May 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
Ajax PHP简单入门教程代码
2008/04/25 PHP
比较全的PHP 会话(session 时间设定)使用入门代码
2008/06/05 PHP
PHP setcookie指定domain参数后,在IE下设置cookie失效的解决方法
2011/09/09 PHP
php在程序中将网页生成word文档并提供下载的代码
2012/10/09 PHP
CodeIgniter删除和设置Cookie的方法
2015/04/07 PHP
PHP截取IE浏览器并缩小原图的方法
2016/03/04 PHP
PHP读取大文件的多种方法介绍
2016/04/04 PHP
php实现文件与16进制相互转换的方法示例
2017/02/16 PHP
PHP7数组的底层实现示例
2019/08/25 PHP
php字符串函数 str类常见用法示例
2020/05/15 PHP
使用jQuery validate 验证注册表单实例演示
2013/03/25 Javascript
jquery改变disabled的boolean状态的三种方法
2013/12/13 Javascript
jQuery晃动层特效实现方法
2015/03/09 Javascript
javascript实现判断鼠标的状态
2015/07/10 Javascript
jquery获取css的color值返回RGB的方法
2015/12/18 Javascript
Angular的Bootstrap(引导)和Compiler(编译)机制
2016/06/20 Javascript
AngularJS实现ajax请求的方法
2016/11/22 Javascript
javascript 定时器工作原理分析
2016/12/03 Javascript
浅谈Javascript事件对象
2017/02/05 Javascript
vue-cli+webpack在生成的项目中使用bootstrap实例代码
2017/05/26 Javascript
JavaScript之生成器_动力节点Java学院整理
2017/06/30 Javascript
关于定制FileField中的上传文件名称问题
2017/08/22 Javascript
JS实现运动缓冲效果的封装函数示例
2018/02/18 Javascript
把vue-router和express项目部署到服务器的方法
2018/02/21 Javascript
解决Angular.js中使用Swiper插件不能滑动的问题
2018/02/26 Javascript
vue-cli脚手架-bulid下的配置文件
2018/03/27 Javascript
node 解析图片二维码的内容代码实例
2019/09/11 Javascript
python shell命令行中import多层目录下的模块操作
2020/03/09 Python
娇韵诗Clarins意大利官方网站:法国天然护肤品牌
2020/03/11 全球购物
Expedia瑞典官网:预订度假屋、酒店、汽车租赁、机票等
2021/01/23 全球购物
网络体系结构及协议的定义
2014/03/13 面试题
狂人日记读书笔记
2015/06/30 职场文书
2016年小学端午节活动总结
2016/04/01 职场文书
Python编写可视化界面的全过程(Python+PyCharm+PyQt)
2021/05/17 Python
漫画「狩龙人拉格纳」公开TV动画预告图
2022/03/22 日漫
Jmerte 分布式压测及分布式压测配置
2022/04/30 Java/Android