octopus/pkg/middlewares/metrics/middleware.go
2023-03-22 22:45:17 +08:00

136 lines
3.4 KiB
Go

package metrics
import (
"strconv"
"time"
"github.com/gofiber/fiber/v2"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
)
const serviceName = "cp-service"
var (
labels = prometheus.Labels{"service": serviceName}
KafkaConsumeSuccessCounter = promauto.NewCounterVec(
prometheus.CounterOpts{
Name: prometheus.BuildFQName("cp", "kafka", "consume_success"),
Help: "记录kafka消息消费成功的次数",
ConstLabels: labels,
}, []string{"topic", "bid"},
)
KafkaConsumeErrorCounter = promauto.NewCounterVec(
prometheus.CounterOpts{
Name: prometheus.BuildFQName("cp", "kafka", "consume_error"),
Help: "记录kafka消息消费失败的次数",
ConstLabels: labels,
}, []string{"topic", "bid"},
)
KafkaConsumeProcessingCounter = promauto.NewGaugeVec(prometheus.GaugeOpts{
Name: prometheus.BuildFQName("cp", "kafka", "consume_processing"),
Help: "当前正在处理的kafka消息个数",
ConstLabels: labels,
}, []string{"topic", "bid"},
)
requestInProgressTotal = promauto.NewGaugeVec(prometheus.GaugeOpts{
Name: prometheus.BuildFQName("cp", "http", "requests_in_progress_total"),
Help: "All the requests in progress",
ConstLabels: labels,
}, []string{"method"})
requestsTotal = promauto.NewCounterVec(prometheus.CounterOpts{
Name: prometheus.BuildFQName("cp", "http", "requests_total"),
Help: "Count all http requests by status code, method and path.",
ConstLabels: labels,
},
[]string{"status_code", "method", "path"},
)
requestDuration = promauto.NewHistogramVec(prometheus.HistogramOpts{
Name: prometheus.BuildFQName("cp", "http", "request_duration_seconds"),
Help: "Duration of all HTTP requests by status code, method and path.",
ConstLabels: labels,
Buckets: []float64{
0.000000001, // 1ns
0.000000002,
0.000000005,
0.00000001, // 10ns
0.00000002,
0.00000005,
0.0000001, // 100ns
0.0000002,
0.0000005,
0.000001, // 1µs
0.000002,
0.000005,
0.00001, // 10µs
0.00002,
0.00005,
0.0001, // 100µs
0.0002,
0.0005,
0.001, // 1ms
0.002,
0.005,
0.01, // 10ms
0.02,
0.05,
0.1, // 100 ms
0.2,
0.5,
1.0, // 1s
2.0,
5.0,
10.0, // 10s
15.0,
20.0,
30.0,
},
},
[]string{"status_code", "method", "path"},
)
)
func NewMiddleware(cfgs ...Config) fiber.Handler {
cfg := configDefault(cfgs...)
return func(ctx *fiber.Ctx) error {
if cfg.Next != nil && cfg.Next(ctx) {
return ctx.Next()
}
start := time.Now()
method := ctx.Route().Method
if ctx.Route().Path == "/metrics" {
return ctx.Next()
}
requestInProgressTotal.WithLabelValues(method).Inc()
defer requestInProgressTotal.WithLabelValues(method).Dec()
err := ctx.Next()
// initialize with default error code
// https://docs.gofiber.io/guide/error-handling
status := fiber.StatusInternalServerError
if err != nil {
if e, ok := err.(*fiber.Error); ok {
// Get correct error code from fiber.Error type
status = e.Code
}
} else {
status = ctx.Response().StatusCode()
}
path := ctx.Route().Path
statusCode := strconv.Itoa(status)
requestsTotal.WithLabelValues(statusCode, method, path).Inc()
elapsed := float64(time.Since(start).Nanoseconds()) / 1e9
requestDuration.WithLabelValues(statusCode, method, path).Observe(elapsed)
return err
}
}