• 自定义exporter与gin框架集成


    原文链接 https://www.cnblogs.com/wt11/p/15122036.html

    参考链接 https://www.cnblogs.com/dongyuq1/p/13572477.html

    1. 先自定义exporter

    package utils
    
    import (
        "github.com/gin-gonic/gin"
        "github.com/prometheus/client_golang/prometheus"
        "github.com/prometheus/client_golang/prometheus/promhttp"
        "github.com/prometheus/common/log"
    )
    
    // 最终生成的指标数据
    // # HELP dns_query_count_total Count of DNS Query.
    // # TYPE dns_query_count_total counter
    // dns_query_count_total{kkkk="self",net="udp",query_proto="dns","query_help": "queryHelp", "xxxxxx": "queryHelp"} 999999
    
    // 1. 定义一个结构体,用于存放描述信息
    type Exporter struct {
        queryCountDesc *prometheus.Desc
    }
    
    // 2. 定义一个Collector接口,用于存放两个必备函数,Describe和Collect
    type Collector interface {
        Describe(chan<- *prometheus.Desc)
        Collect(chan<- prometheus.Metric)
    }
    
    // 3. 定义两个必备函数Describe和Collect
    func (e *Exporter) Describe(ch chan<- *prometheus.Desc) {
        // 将描述信息放入队列
        ch <- e.queryCountDesc
    }
    
    func (e *Exporter) Collect(ch chan<- prometheus.Metric) {
        //  采集业务指标数据
        queryCount := e.QueryState() // 获取指标数据值
        ch <- prometheus.MustNewConstMetric(
            e.queryCountDesc,        // 将指标数据与自定义描述信息绑定
            prometheus.CounterValue, // 指定该指标数据的类型,这里表示counter类型
            float64(queryCount),     // 指标数据的值转为float64类型,必须的
            "dns",                   // 指标的标签值,多个标签值的话,继续往后写即可。与NewExporter中prometheus.NewDesc的第三个参数
            "udp",                   // 是一一对应的。这里的dns就是query_proto的值
            "self",
        )
    }
    
    // 4. 自定义一个生成业务指标数据的函数
    func (e *Exporter) QueryState() (queryCount float64) {
        queryCount = 999999
        return
    }
    
    // 5. 定义一个实例化函数,用于生成prometheus数据
    func NewExporter() *Exporter {
        return &Exporter{
            queryCountDesc: prometheus.NewDesc(
                "dns_query_count_total",                // 自定义指标名称
                "Count of DNS Query.",                  // 指标的help信息
                []string{"query_proto", "net", "kkkk"}, // 指标的标签名称,多个就写到数组里,与Collect中prometheus.MustNewConstMetric最后的几个标签值是一一对应的
                prometheus.Labels{"query_help": "queryHelp", "xxxxxx": "queryHelp"}, // 也是定义指标标签名称,不过通常用于定义全局唯一的指标标签名称,用的少一些。
                // 这个不是必须的, 不需要的话,可以写为nil。
            ),
        }
    }
    
    func getGatherers() (reg *prometheus.Registry, gatherers *prometheus.Gatherers) {
        // 6. 实例化并注册数据采集器exporter
        exporter := NewExporter()
        registry := prometheus.NewPedanticRegistry()
        registry.MustRegister(exporter)
    
        // 7. 定义一个采集数据的采集器集合,它可以合并多个不同的采集器数据到一个结果集合中
        gatherers = &prometheus.Gatherers{
            // prometheus.DefaultGatherer, // 默认的数据采集器,包含go运行时的指标信息
            registry, // 自定义的采集器
        }
        return registry, gatherers
    }
    
    // 8. 启动http服务
    // 8.1 (与gin框架集成)
    func PrometheusHandler() gin.HandlerFunc {
        registry, gatherers := getGatherers()
        h := promhttp.InstrumentMetricHandler(
            registry, promhttp.HandlerFor(gatherers, promhttp.HandlerOpts{
                ErrorLog:      log.NewErrorLogger(),     // 采集过程中如果出现错误,记录日志
                ErrorHandling: promhttp.ContinueOnError, // 采集过程中如果出现错误,继续采集其他数据,不会中断采集器的工作
            }),
        )
        return func(c *gin.Context) {
            h.ServeHTTP(c.Writer, c.Request)
        }
    }
    
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////
    // 8.2 (独立启动,不与gin框架集成)
    // func init() {
    //     _, gatherers := getGatherers()
    //     h := promhttp.HandlerFor(gatherers,
    //         // HandlerFor函数传递上边的gatherers对象,并返回一个httpHandler对象h。
    //         // 这个httpHandler对象h可以调用其自身的ServHTTP函数来接收HTTP请求,并返回响应
    //         promhttp.HandlerOpts{
    //             ErrorLog:      log.NewErrorLogger(),     // 采集过程中如果出现错误,记录日志
    //             ErrorHandling: promhttp.ContinueOnError, // 采集过程中如果出现错误,继续采集其他数据,不会中断采集器的工作
    //         })
    //     http.HandleFunc("/metrics", func(w http.ResponseWriter, r *http.Request) {
    //         fmt.Println("listen exporter on :9999")
    //         h.ServeHTTP(w, r)
    //     })
    //     log.Fatal(http.ListenAndServe(":9999", nil))
    // }
    /////////////////////////////////////////////////////////////////////////////////////////////////////////////////////

    2. gin框架路由配置

    package routes
    
    import (
        "dnsmanager/utils"
    
        "github.com/gin-gonic/gin"
    )
    
    func SetRoutes(router *gin.Engine) {
        router.Use(gin.Recovery()) // error handle
    
        
        router.GET("/metrics", utils.PrometheusHandler())        ------------------> 设置路由
    }
  • 相关阅读:
    Nmap绕过防火墙&脚本的使用
    Nmap在实战中的高级用法
    kali&BT安装好之后无法上网或者无法获得内网IP
    [转]谈渗透测试方法和流程
    xssless
    国内外有名的安全扫描工具,你知道几个?
    Linux下如果忘记了Mysql的root密码该怎么办?
    JSP手动注入 全
    sqlmap用户手册 [详细]
    Windows系统如何使用sqlmap
  • 原文地址:https://www.cnblogs.com/wt11/p/15122036.html
Copyright © 2020-2023  润新知