package middleware import ( "finclip-app-manager/infrastructure/config" "net/http" "strconv" "strings" "time" "github.com/gin-gonic/gin" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promhttp" ) var ( //单次请求耗时 RequestDurationGauge = prometheus.NewGaugeVec( prometheus.GaugeOpts{ Name: "http_request_duration", Help: "duration of request.", }, []string{"interface", "method", "code"}, ) //请求次数累加 RequestCounter = prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "http_request_count", Help: "count of request.", }, []string{"interface", "method", "code"}, ) //请求次数耗时累加 RequestDurationTotalCounter = prometheus.NewCounterVec( prometheus.CounterOpts{ Name: "http_request_duration_total", Help: "total duration of request.", }, []string{"interface", "method", "code"}, ) //请求耗时分布 RequestDurationHistogram = prometheus.NewHistogramVec( prometheus.HistogramOpts{ Name: "http_request_duration_histogram", Help: "duration histogram of request.", Buckets: prometheus.LinearBuckets(20, 20, 10), //第一个桶20起,每个桶间隔20, 共10个桶,这里使用场景是请求耗时,所以单位是ms }, []string{"interface", "method", "code"}, ) ) func init() { if config.GetConfig().OpenMonitor { prometheus.MustRegister(RequestDurationGauge) prometheus.MustRegister(RequestCounter) prometheus.MustRegister(RequestDurationTotalCounter) prometheus.MustRegister(RequestDurationHistogram) http.Handle("/metrics", promhttp.Handler()) go http.ListenAndServe(":"+config.GetConfig().MonitorPort, nil) } } func RequestDuration() gin.HandlerFunc { return func(c *gin.Context) { if config.GetConfig().OpenMonitor { fullPath := c.FullPath() if fullPath == "/ready" || fullPath == "/down" || fullPath == "/test" || fullPath == "/" { c.Next() return } start := time.Now() c.Next() duration := float64(time.Since(start)) / float64(time.Second) * 1000 //path := GetSimplePath(c.Request.URL.Path) path := GetSimplePath(fullPath) method := c.Request.Method code := strconv.Itoa(c.Writer.Status()) RequestDurationGauge.WithLabelValues(path, method, code).Set(duration) RequestDurationTotalCounter.WithLabelValues(path, method, code).Add(duration) RequestDurationHistogram.WithLabelValues(path, method, code).Observe(duration) } } } func RequestCount(c *gin.Context) { if config.GetConfig().OpenMonitor { fullPath := c.FullPath() if fullPath == "/ready" || fullPath == "/down" || fullPath == "/test" || fullPath == "/" { c.Next() return } c.Next() method := c.Request.Method //path := GetSimplePath(c.Request.URL.Path) path := GetSimplePath(fullPath) code := strconv.Itoa(c.Writer.Status()) RequestCounter.WithLabelValues(path, method, code).Inc() } } func GetSimplePath(path string) string { simplePath := path if strings.Contains(simplePath, "/api/v1/mop/finstore/dev/apps/publishRequest") || strings.Contains(simplePath, "/api/v1/mop/finstore/dev/apps/publish-request") { simplePath = "/api/v1/mop/finstore/dev/apps/publish-request" } else if strings.Contains(simplePath, "/api/v1/mop/finstore/dev/apps/publishRequestWithdrawal") || strings.Contains(simplePath, "/api/v1/mop/finstore/dev/apps/publish-request-withdrawal") { simplePath = "/api/v1/mop/finstore/dev/apps/publish-request-withdrawal" } else if strings.Contains(simplePath, "/api/v1/mop/finstore/dev/appsAndReviews") || strings.Contains(simplePath, "/api/v1/mop/finstore/dev/apps-and-reviews") { simplePath = "/api/v1/mop/finstore/dev/apps-and-reviews" } else if strings.Contains(simplePath, "/api/v1/mop/finstore/admin/linkApplets") || strings.Contains(simplePath, "/api/v1/mop/finstore/admin/link-applets") { simplePath = "/api/v1/mop/finstore/admin/link-applets" } else if strings.Contains(simplePath, "/api/v1/mop/finstore/admin/statistics/appReviewTrend") || strings.Contains(simplePath, "/api/v1/mop/finstore/admin/statistics/app-review-trend") { simplePath = "/api/v1/mop/finstore/admin/statistics/app-review-trend" } else if strings.Contains(simplePath, "/api/v1/mop/finstore/ruleEngine/permitPub/:appId") || strings.Contains(simplePath, "/api/v1/mop/finstore/rule-engine/permit-pub/:appId") { simplePath = "/api/v1/mop/finstore/rule-engine/permit-pub/:appId" } else if strings.Contains(simplePath, "/api/v1/mop/finstore/ruleEngine/app/:appId") || strings.Contains(simplePath, "/api/v1/mop/finstore/rule-engine/app/:appId") { simplePath = "/api/v1/mop/finstore/rule-engine/app/:appId" } else if strings.Contains(simplePath, "/api/v1/mop/finstore/ruleEngine/app/:appId/:version") || strings.Contains(simplePath, "/api/v1/mop/finstore/rule-engine/app/:appId/:version") { simplePath = "/api/v1/mop/finstore/rule-engine/app/:appId/:version" } else if strings.Contains(simplePath, "/api/v1/mop/finstore/ruleEngine/grayNotify") || strings.Contains(simplePath, "/api/v1/mop/finstore/rule-engine/gray-notify") { simplePath = "/api/v1/mop/finstore/rule-engine/gray-notify" } else if strings.Contains(simplePath, "/api/v1/mop/finstore/bindingInfo") || strings.Contains(simplePath, "/api/v1/mop/finstore/binding-info") { simplePath = "/api/v1/mop/finstore/binding-info" /*else if strings.Contains(simplePath, "/api/v1/mop/finstore/openapi/bindingId") || strings.Contains(simplePath, "/api/v1/mop/finstore/open-api/binding-id") { simplePath = "/api/v1/mop/finstore/open-api/binding-id" }*/ } else if strings.Contains(simplePath, "/api/v1/mop/finstore/openapi/app/list") || strings.Contains(simplePath, "/api/v1/mop/finstore/open-api/app/list") { simplePath = "/api/v1/mop/finstore/open-api/app/list" } else if strings.Contains(simplePath, "/api/v1/mop/finstore/openapi/apps/info") || strings.Contains(simplePath, "/api/v1/mop/finstore/open-api/apps/info") { simplePath = "/api/v1/mop/finstore/open-api/apps/info" } else if strings.Contains(simplePath, "/api/v1/mop/finstore/openapi/app/search") || strings.Contains(simplePath, "/api/v1/mop/finstore/open-api/app/search") { simplePath = "/api/v1/mop/finstore/open-api/app/search" } else if strings.Contains(simplePath, "/api/v1/mop/finstore/openapi/appver/:appId/:sequence") || strings.Contains(simplePath, "/api/v1/mop/finstore/open-api/appver/:appId/:sequenceo") { simplePath = "/api/v1/mop/finstore/open-api/appver/:appId/:sequence" } else if strings.Contains(simplePath, "/api/v1/mop/finstore/openapi/secret") || strings.Contains(simplePath, "/api/v1/mop/finstore/open-api/secret") { simplePath = "/api/v1/mop/finstore/open-api/secret" } else if strings.Contains(simplePath, "/api/v1/finclip-app-manager/typeConfig") || strings.Contains(simplePath, "/api/v1/finclip-app-manager/type-config") { simplePath = "/api/v1/finclip-app-manager/type-config" } else if strings.Contains(simplePath, "/api/v1/mop/finstore/dev/typeConfig") || strings.Contains(simplePath, "/api/v1/mop/finstore/dev/type-config") { simplePath = "/api/v1/mop/finstore/dev/type-config" } else if strings.Contains(simplePath, "/api/v1/mop/finstore/admin/typeConfig") || strings.Contains(simplePath, "/api/v1/mop/finstore/admin/type-config") { simplePath = "/api/v1/mop/finstore/admin/type-config" } else if strings.Contains(simplePath, "/api/v1/mop/finstore/admin/typeConfig/:typeConfigId") || strings.Contains(simplePath, "/api/v1/mop/finstore/admin/type_config/:typeConfigId") { simplePath = "/api/v1/mop/finstore/admin" } /*} else if strings.Contains(simplePath, "/api/v1/mop/finstore/dev/bindings/appIdInfoList") || strings.Contains(simplePath, "/api/v1/mop/finstore/dev/bindings/appid-info-list") { simplePath = "/api/v1/mop/finstore/dev/bindings/appid-info-list" } else if strings.Contains(simplePath, "/api/v1/mop/finstore/dev/limit/bundleId") || strings.Contains(simplePath, "/api/v1/mop/finstore/dev/limit/bundle-id") { simplePath = "/api/v1/mop/finstore/dev/limit/bundle-id" } else if strings.Contains(simplePath, "/api/v1/mop/finstore/openapi/bindingInfo") || strings.Contains(simplePath, "/api/v1/mop/finstore/open-api/binding-info") { simplePath = "/api/v1/mop/finstore/open-api/bindingInfo" } */ return simplePath }