Go1.9接入prometheus监控小实例

package main

import (
    "bytes"
    "fmt"
    "net/http"
    "strings"
    "sync/atomic"

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

type statusCollect struct {
    reqDesc       *prometheus.CounterVec
    respsizeDesc  *prometheus.Desc
    respsizevalue int64
}

func (s *statusCollect) ReqAdd(code, method string) {
    s.reqDesc.WithLabelValues(code, method).Inc()
}

func (s *statusCollect) ReqSizeAdd(size int64) {
    atomic.AddInt64(&s.respsizevalue, size)
}

func (s *statusCollect) Describe(ch chan<- *prometheus.Desc) {
    ch <- s.respsizeDesc
    s.reqDesc.Describe(ch)
}

func (s *statusCollect) Collect(ch chan<- prometheus.Metric) {
    ch <- prometheus.MustNewConstMetric(s.respsizeDesc, prometheus.CounterValue, float64(s.respsizevalue))
    s.reqDesc.Collect(ch)
}

func NewStatusCollect() *statusCollect {
    opts := prometheus.CounterOpts{Namespace: "Test", Subsystem: "http", Name: "request count", Help: "requst count"}
    return &statusCollect{
        reqDesc:      prometheus.NewCounterVec(opts, []string{"code", "method"}),
        respsizeDesc: prometheus.NewDesc("Namespace_http_respsize_count", "http respsize count", nil, nil),
    }
}

const (
    contentTypeHeader   = "Content-Type"
    contentLengthHeader = "Content-Length"
)

func main() {
    status := NewStatusCollect()
    regist := prometheus.NewRegistry()
    regist.MustRegister(status)

    http.HandleFunc("/api/metric", func(w http.ResponseWriter, r *http.Request) {
        status.ReqAdd("200", strings.ToLower(r.Method))

        entry, err := regist.Gather()
        if err != nil {
            http.Error(w, "An error has occurred during metrics collection:\n\n"+err.Error(), http.StatusInternalServerError)
            return
        }

        buf := bytes.NewBuffer(nil)
        contentType := expfmt.Negotiate(r.Header)
        enc := expfmt.NewEncoder(buf, contentType)

        for _, met := range entry {
            if err := enc.Encode(met); err != nil {
                http.Error(w, "An error has occurred during metrics encoding:\n\n"+err.Error(), http.StatusInternalServerError)
                return
            }
        }

        if buf.Len() == 0 {
            http.Error(w, "No metrics encoded, last error:\n\n"+err.Error(), http.StatusInternalServerError)
            return
        }
        status.ReqSizeAdd(int64(buf.Len()))
        header := w.Header()
        header.Set(contentTypeHeader, string(contentType))
        header.Set(contentLengthHeader, fmt.Sprint(buf.Len()))
        w.Write(buf.Bytes())
    })

    http.ListenAndServe(":1789", nil)
}

猜你喜欢

转载自blog.csdn.net/fyxichen/article/details/78733083