Wei / Prometheus exporter 代码参考

Created Sun, 31 Mar 2024 13:26:00 +0000 Modified Mon, 23 Sep 2024 07:21:40 +0000

这篇笔记主要记录如何自行编写 Prometheus exporter 。


                                       (@@) (  ) (@)  ( )  @@    ()    @     O     @     O      @
                                  (   )
                              (@@@@)
                           (    )

                         (@@@)
                       ====        ________                ___________
                   _D _|  |_______/        \__I_I_____===__|_________|
                    |(_)---  |   H\________/ |   |        =|___ ___|      _________________
                    /     |  |   H  |  |     |   |         ||_| |_||     _|                \_____A
                   |      |  |   H  |__--------------------| [___] |   =|                        |
                   | ________|___H__/__|_____/[][]~\_______|       |   -|                        |
                   |/ |   |-----------I_____I [][] []  D   |=======|____|________________________|_
                 __/ =| o |=-~O=====O=====O=====O\ ____Y___________|__|__________________________|_
                  |/-=|___|=    ||    ||    ||    |_____/~\___/          |_D__D__D_|  |_D__D__D_|
                   \_/      \__/  \__/  \__/  \__/      \_/               \_/   \_/    \_/   \_/

本篇根据网络上找到的样板修改而来,首先通过 go mod init myexporter 来创建模块,具体的代码结构如下:

.
├── collector
│   └── http.go
├── go.mod
├── go.sum
└── main.go

http.go 代码内容如下:

package collector

import (
	"github.com/prometheus/client_golang/prometheus"
	"net/http"
	"sync"
	"time"
)

type StatusCollector struct {
	requestDesc *prometheus.Desc
	mutex       sync.Mutex
}

func NewStatusCollector() prometheus.Collector {
	return &StatusCollector{
		requestDesc: prometheus.NewDesc(
			"http_request_status",
			"The Status Code of http request",
			nil,
			prometheus.Labels{"url": "https://www.baidu.com"}),
	}
}

func (n *StatusCollector) Describe(ch chan<- *prometheus.Desc) {
	ch <- n.requestDesc
}

func (n *StatusCollector) Collect(ch chan<- prometheus.Metric) {
	n.mutex.Lock()
	client := http.Client{
		Timeout: 5 * time.Second,
	}
	resp, err := client.Head("https://www.baidu.com")
	if err != nil {
		ch <- prometheus.MustNewConstMetric(n.requestDesc, prometheus.GaugeValue, 0)
		n.mutex.Unlock()
		return
	}
	ch <- prometheus.MustNewConstMetric(n.requestDesc, prometheus.GaugeValue, float64(resp.StatusCode))
	n.mutex.Unlock()
}

main.go 代码内容如下:

package main

import (
	"myexporter/collector"
	"fmt"
	"github.com/prometheus/client_golang/prometheus"
	"github.com/prometheus/client_golang/prometheus/promhttp"
	"net/http"
)

func main() {
	r := prometheus.NewRegistry()
	r.MustRegister(collector.NewStatusCollector())
	handler := promhttp.HandlerFor(r, promhttp.HandlerOpts{})
	http.Handle("/metrics", handler)
	if err := http.ListenAndServe(":8080", nil); err != nil {
		fmt.Printf("Error occur when start server %v", err)
	}
}

代码编写完成后,直接通过 go getgo build 下载依赖模块和编译代码,就可以得到可执行文件。

建议通过 CGO_ENABLED=0 go build -ldflags="-w -s" main.go 进行编译,可以得到静态链接的可执行文件并且文件体积比较小。