Prometheus自定义exporter

写的 exporter 做个记录,除了业务逻辑不同,模板都是一个,语言是 golang

main 方法

/**
 * @Author: xuyasong
 * @Description:
 * @File:  main
 * @Version: 1.0.0
 * @Date: 2019/2/22
 */

package main

import (
    "flag"
    "log"
    "net/http"

    "demo/collector"

    "github.com/prometheus/client_golang/prometheus"
    "github.com/prometheus/client_golang/prometheus/promhttp"
)

var (
    // 命令行参数
    listenAddr       = flag.String("web.listen-port", "9002", "An port to listen on for web interface and telemetry.")
    metricsPath      = flag.String("web.telemetry-path", "/metrics", "A path under which to expose metrics.")
    metricsNamespace = flag.String("metric.namespace", "bec", "Prometheus metrics namespace, as the prefix of metrics name")
)

func main() {
    flag.Parse()

    metrics := collector.NewMetrics(*metricsNamespace)
    registry := prometheus.NewRegistry()
    registry.MustRegister(metrics)

    http.Handle(*metricsPath, promhttp.HandlerFor(registry, promhttp.HandlerOpts{}))

    http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
        w.Write([]byte(`<html>
            <head><title>A Prometheus Exporter</title></head>
            <body>
            <h1>A Prometheus Exporter</h1>
            <p><a href='/metrics'>Metrics</a></p>
            </body>
            </html>`))
    })

    log.Printf("Starting Server at http://localhost:%s%s", *listenAddr, *metricsPath)
    log.Fatal(http.ListenAndServe(":" + *listenAddr, nil))
}

Collector方法

/**
 * @Author: xuyasong
 * @Description:
 * @File:  network
 * @Version: 1.0.0
 * @Date: 
 */

package collector

import (
    "context"
    "encoding/json"
    "fmt"
    "strconv"
    "strings"
    "sync"
    "time"

    "github.com/prometheus/client_golang/prometheus"
    "github.com/prometheus/common/log"
)

type Metrics struct {
    metrics map[string]*prometheus.Desc
    mutex   sync.Mutex
}

func newGlobalMetric(namespace string, metricName string, docString string, labels []string) *prometheus.Desc {
    return prometheus.NewDesc(namespace+"_"+metricName, docString, labels, nil)
}


func NewMetrics(namespace string) *Metrics {
    return &Metrics{
        metrics: map[string]*prometheus.Desc{
            "pod_network_receive_bytes":  newGlobalMetric(namespace, "pod_network_receive_bytes", "network receive bytes of pod ", []string{"pod_name", "namespace", "node_name"}),
    }
}

/**
 * 接口:Describe
 * 功能:传递结构体中的指标描述符到channel
 */
func (c *Metrics) Describe(ch chan<- *prometheus.Desc) {
    for _, m := range c.metrics {
        ch <- m
    }
}

/**
 * 接口:Collect
 * 功能:抓取最新的数据,传递给channel
 */
func (c *Metrics) Collect(ch chan<- prometheus.Metric) {
    c.mutex.Lock() // 加锁
    defer c.mutex.Unlock()
   // do something ,add metric to channel
    ch <- prometheus.MustNewConstMetric(c.metrics["pod_network_receive_bytes"], prometheus.CounterValue, 0, pod.podName, pod.namespace, hostname)
}

部署

Dockerfile

FROM nginx:stable-alpine

MAINTAINER xuyasong

RUN sed -i 's/dl-cdn.alpinelinux.org/mirrors.ustc.edu.cn/g' /etc/apk/repositories

RUN mkdir -p /opt/bin && chown -R root:root /opt \
    && apk update&&apk add --no-cache  wget curl less util-linux

COPY bin/demo-exporter /opt/bin/demo-exporter

COPY scripts /opt/bin/scripts

CMD ["/opt/bin/scripts/entrypoint.sh"]

entrypoint.sh

#!/bin/sh

cd /opt
mkdir -p log
chmod 755 log
bin/demo-exporter 2>>log/demo-exporter.log

deployment部署:

---
kind: Deployment
apiVersion: apps/v1
metadata:
  name: demo-exporter
  namespace: monitor
  labels:
    k8s-app: demo-exporter
spec:
  selector:
    matchLabels:
      k8s-app: demo-exporter
  template:
    metadata:
      labels:
        k8s-app: demo-exporter
      annotations:
        "prometheus.io/scrape": "true"
    spec:
      containers:
        - name: demo-exporter
          image: demo-exporter
          imagePullPolicy: Always
          resources:
            limits:
              cpu: "1"
              memory: "500Mi"
            requests:
              cpu: "1"
              memory: "200Mi"
          securityContext:
            privileged: true
          volumeMounts:
          - mountPath: /opt/log
            name: demo-exporter-log
      volumes:
        - hostPath:
            path: /var/demo-exporter
          name: demo-exporter-log
---
apiVersion: v1
kind: Service
metadata:
  annotations:
    prometheus.io/scrape: "true"
  labels:
    k8s-app: demo-exporter
  name: demo-exporter
  namespace: monitor
spec:
  ports:
  - name: http-metrics
    port: 9006
    protocol: TCP
    targetPort: 9006
  selector:
    k8s-app: demo-exporter
  type: ClusterIP

Written by

说点什么

1 评论 在 "Prometheus自定义exporter"

avatar

此站点使用Akismet来减少垃圾评论。了解我们如何处理您的评论数据

  Subscribe  
最新 最旧 得票最多
提醒
trackback

[…] 还有各种场景下的自定义 exporter,如日志提取后面会再做介绍。 […]