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)
}
Go1.9接入prometheus监控小实例
最新推荐文章于 2024-09-19 18:51:38 发布