zoukankan      html  css  js  c++  java
  • 开发一个简单的golang prometheus exporter.

    以下是一个简单的学习关于golang 开发prometheus exporter 的说明

    环境准备

    • go mod
    module ladap-exporter
    go 1.14
    require (
        github.com/go-ldap/ldap/v3 v3.2.3 // indirect
        github.com/prometheus/client_golang v1.7.1
    )
     
     
    • main.go
    package main
    import (
        "flag"
        "net/http"
        "github.com/prometheus/client_golang/prometheus"
        "github.com/prometheus/client_golang/prometheus/promhttp"
    )
    var addr = flag.String("listen-address", ":9001", "The address to listen on for HTTP requests.")
    var rpcDurations = prometheus.NewSummaryVec(
        prometheus.SummaryOpts{
            Name:       "rpc_durations_seconds",
            Help:       "RPC latency distributions.",
            Objectives: map[float64]float64{0.5: 0.05, 0.9: 0.01, 0.99: 0.001},
        },
        []string{"service"},
    )
    var up = prometheus.NewDesc(
        "ldap_up",
        "watch ladap info",
        []string{"name", "class"},
        nil,
    )
    var rpc = prometheus.NewDesc(
        "rpc_request_total",
        "rpc request total",
        []string{"rpc_func", "rpc_source"},
        nil,
    )
    var version = prometheus.MustNewConstMetric(
        prometheus.NewDesc("ldap_exporter_version", "ldap exporter version", []string{"type", "build"}, nil),
        prometheus.GaugeValue,
        1.0,
        "cust", "2020-09-08",
    )
    // MyLDAPCollector myLDAPCollector
    type MyLDAPCollector struct {
        up      *prometheus.Desc
        rpc     *prometheus.Desc
        version *prometheus.Desc
    }
    //Describe describe
    func (c MyLDAPCollector) Describe(ch chan<- *prometheus.Desc) {
        ch <- c.up
        ch <- c.rpc
        ch <- c.version
    }
    //Collect collect
    func (c MyLDAPCollector) Collect(ch chan<- prometheus.Metric) {
        upMetrics := prometheus.MustNewConstMetric(up, prometheus.GaugeValue, 1, "dalong", "demo")
        rpcRequest := prometheus.MustNewConstMetric(rpc, prometheus.CounterValue, 1000, "login", "a")
        ch <- version
        ch <- upMetrics
        ch <- rpcRequest
    }
    func init() {
        myLDAPCollector := MyLDAPCollector{
            up:      up,
            rpc:     rpc,
            version: version.Desc(),
        }
        // Add MyCus Collector
        prometheus.MustRegister(myLDAPCollector)
        // Add rpc summary collector
        prometheus.MustRegister(rpcDurations)
        // Add Go module build info.
        prometheus.MustRegister(prometheus.NewBuildInfoCollector())
    }
    func main() {
        flag.Parse()
        server := http.NewServeMux()
        server.HandleFunc("/", func(response http.ResponseWriter, Request *http.Request) {
            indexpage := `<html>
                    <body>
                       <h1>ldap exporter</h1>
                       <p><a href="/metrics">metrics</a></p>
                    </body>
              </html>`
            response.Write([]byte(indexpage))
        })
        server.HandleFunc("/api", func(response http.ResponseWriter, Request *http.Request) {
            rpcDurations.WithLabelValues("mydemo").Observe(22)
            response.Write([]byte("dalongdemo"))
        })
        server.Handle("/metrics", promhttp.Handler())
        http.ListenAndServe(*addr, server)
    }
     
    • 代码说明
      以上代码同时包含了基于自定义collector 以及内置默认的处理,对于自定义的collector 我们需要实现
      参考接口定义
     
    type Collector interface {
        // Describe sends the super-set of all possible descriptors of metrics
        // collected by this Collector to the provided channel and returns once
        // the last descriptor has been sent. The sent descriptors fulfill the
        // consistency and uniqueness requirements described in the Desc
        // documentation.
        //
        // It is valid if one and the same Collector sends duplicate
        // descriptors. Those duplicates are simply ignored. However, two
        // different Collectors must not send duplicate descriptors.
        //
        // Sending no descriptor at all marks the Collector as “unchecked”,
        // i.e. no checks will be performed at registration time, and the
        // Collector may yield any Metric it sees fit in its Collect method.
        //
        // This method idempotently sends the same descriptors throughout the
        // lifetime of the Collector. It may be called concurrently and
        // therefore must be implemented in a concurrency safe way.
        //
        // If a Collector encounters an error while executing this method, it
        // must send an invalid descriptor (created with NewInvalidDesc) to
        // signal the error to the registry.
        Describe(chan<- *Desc)
        // Collect is called by the Prometheus registry when collecting
        // metrics. The implementation sends each collected metric via the
        // provided channel and returns once the last metric has been sent. The
        // descriptor of each sent metric is one of those returned by Describe
        // (unless the Collector is unchecked, see above). Returned metrics that
        // share the same descriptor must differ in their variable label
        // values.
        //
        // This method may be called concurrently and must therefore be
        // implemented in a concurrency safe way. Blocking occurs at the expense
        // of total performance of rendering all registered metrics. Ideally,
        // Collector implementations support concurrent readers.
        Collect(chan<- Metric)
    }

    type MyLDAPCollector struct 说明
    为了方便统计添加了up version 以及rpc 的定义,up 是标记exporter 运行准备的,version 记录exporter 版本的
    rpc 是一个简单的total 模式的metrics 定义
    对于golang prometheus metrics 的定义,一般我们需要的是desc(表明metrics 的名称,帮助信息,以及可能包含的label)
    自定义collector 的Describe主要是进行metrics desc 信息的暴露,Collect 是实际的metrics 处理(拉取数据库,其他中间件的信息拉取。。。。)
    定义完collector之后我们需要进行注册才能使用,具体的注册比较简单prometheus.MustRegister 就可以了,同时golang 版本的sdk
    已经提供了好多便捷的metrics 帮助没(count,gauge.summary,histogram)都是比较方便的,同时也内置了一些golang runtime 的metrics
    都是可以注册使用的
    prometheus exporter http server 的暴露也比较简单,默认以及提供了http handler 的实现,我们注册就可以了

     
    server.Handle("/metrics", promhttp.Handler())
    • 运行效果

    go run main.go

    说明

    以上是一个简单的metrics 实现,而且好多语言的框架已经提供了类似的中间件扩展我们可以直接使用

    参考资料

    https://github.com/prometheus/client_golang

  • 相关阅读:
    实现简单高效的网址(文本)缩短服务
    Xsl模板应用基础(三、模板嵌套)
    Xsl模板应用基础(二、程序转换)
    Xsl模板应用基础(一、介绍)
    C#调用360杀毒软件查杀指定路径
    微信公众平台网页授权获取用户基本信息(VS.NET版)
    微信公众平台开发者模式自动回复功能与自定义菜单
    微信公众平台接入
    Git常用操作整理
    JVM知识点总结(一)——运行时数据区
  • 原文地址:https://www.cnblogs.com/rongfengliang/p/13635864.html
Copyright © 2011-2022 走看看