From 37d0ee6e72937e28ebf146e44000f4026c7c4016 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E6=9D=8E=E4=BC=9F=E4=B9=90?= Date: Wed, 13 Sep 2023 17:51:56 +0800 Subject: [PATCH] promethues --- middleware/prome/prome.go | 83 +++++++++++++++++++++++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 middleware/prome/prome.go diff --git a/middleware/prome/prome.go b/middleware/prome/prome.go new file mode 100644 index 0000000..d94ee2d --- /dev/null +++ b/middleware/prome/prome.go @@ -0,0 +1,83 @@ +package prome + +import ( + "context" + "fmt" + "git.diulo.com/mogfee/kit/errors" + "git.diulo.com/mogfee/kit/middleware" + "git.diulo.com/mogfee/kit/transport" + "github.com/prometheus/client_golang/prometheus" + "time" +) + +const namespace = "service" + +var ( + labels = []string{"status", "endpoint", "method"} + + uptime = prometheus.NewCounterVec(prometheus.CounterOpts{ + Namespace: namespace, + Name: "uptime", + Help: "HTTP service uptime.", + }, nil) + + reqCount = prometheus.NewCounterVec(prometheus.CounterOpts{ + Namespace: namespace, + Name: "http_request_count_total", + Help: "Total number of HTTP requests made.", + }, labels) + + reqDuration = prometheus.NewHistogramVec(prometheus.HistogramOpts{ + Namespace: namespace, + Name: "http_request_duration_seconds", + Help: "HTTP request latencies in seconds.", + }, labels) + reqSizeBytes = prometheus.NewSummaryVec(prometheus.SummaryOpts{ + Namespace: namespace, + Name: "http_request_size_bytes", + Help: "HTTP request sizes in bytes.", + }, labels) + respSizeBytes = prometheus.NewSummaryVec(prometheus.SummaryOpts{ + Namespace: namespace, + Name: "http_response_size_bytes", + Help: "HTTP request sizes in bytes.", + }, labels) +) + +func init() { + prometheus.MustRegister(uptime, reqCount, reqDuration, reqSizeBytes, respSizeBytes) + go recordUptime() +} +func recordUptime() { + for range time.Tick(time.Second) { + uptime.WithLabelValues().Inc() + } +} + +func Prometheus() middleware.Middleware { + return func(handler middleware.Handler) middleware.Handler { + return func(ctx context.Context, a any) (any, error) { + tr, ok := transport.FromServerContext(ctx) + if !ok { + return handler(ctx, a) + } + start := time.Now() + resp, err := handler(ctx, a) + code := "500" + if err != nil { + switch aerr := err.(type) { + case *errors.Error: + code = fmt.Sprintf("%d", aerr.Code) + default: + code = "500" + } + } + lvs := []string{code, tr.Endpoint(), tr.Operation()} + + reqCount.WithLabelValues(lvs...).Inc() + reqDuration.WithLabelValues(lvs...).Observe(time.Since(start).Seconds()) + + return resp, err + } + } +}