feat(metrics): add cache, process and http metrics

This commit is contained in:
TheFox0x7 2025-01-14 00:01:21 +01:00
parent e94f37f95e
commit 73266df0f5
4 changed files with 58 additions and 0 deletions

View File

@ -9,11 +9,33 @@ import (
"time" "time"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
_ "gitea.com/go-chi/cache/memcache" //nolint:depguard // memcache plugin for cache, it is required for config "ADAPTER=memcache" _ "gitea.com/go-chi/cache/memcache" //nolint:depguard // memcache plugin for cache, it is required for config "ADAPTER=memcache"
) )
var defaultCache StringCache var defaultCache StringCache
var hitCounter = promauto.NewCounter(prometheus.CounterOpts{
Namespace: "gitea",
Help: "Cache hit count",
Subsystem: "cache",
Name: "hit",
})
var missCounter = promauto.NewCounter(prometheus.CounterOpts{
Namespace: "gitea",
Help: "Cache miss count",
Subsystem: "cache",
Name: "miss",
})
var latencyHistogram = promauto.NewHistogram(
prometheus.HistogramOpts{
Namespace: "gitea",
Help: "Cache latency",
Subsystem: "cache",
Name: "duration",
},
)
// Init start cache service // Init start cache service
func Init() error { func Init() error {

View File

@ -6,6 +6,7 @@ package cache
import ( import (
"errors" "errors"
"strings" "strings"
"time"
"code.gitea.io/gitea/modules/json" "code.gitea.io/gitea/modules/json"
"code.gitea.io/gitea/modules/setting" "code.gitea.io/gitea/modules/setting"
@ -63,10 +64,15 @@ func (sc *stringCache) Ping() error {
} }
func (sc *stringCache) Get(key string) (string, bool) { func (sc *stringCache) Get(key string) (string, bool) {
start := time.Now()
v := sc.chiCache.Get(key) v := sc.chiCache.Get(key)
elapsed := time.Since(start).Seconds()
latencyHistogram.Observe(elapsed)
if v == nil { if v == nil {
missCounter.Add(1)
return "", false return "", false
} }
hitCounter.Add(1)
s, ok := v.(string) s, ok := v.(string)
return s, ok return s, ok
} }

View File

@ -7,6 +7,7 @@ import (
"fmt" "fmt"
"net/http" "net/http"
"strings" "strings"
"time"
"code.gitea.io/gitea/modules/cache" "code.gitea.io/gitea/modules/cache"
"code.gitea.io/gitea/modules/gtprof" "code.gitea.io/gitea/modules/gtprof"
@ -19,8 +20,17 @@ import (
"gitea.com/go-chi/session" "gitea.com/go-chi/session"
"github.com/chi-middleware/proxy" "github.com/chi-middleware/proxy"
"github.com/go-chi/chi/v5" "github.com/go-chi/chi/v5"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promauto"
) )
var responseLatency = promauto.NewHistogramVec(prometheus.HistogramOpts{
Namespace: "http",
Subsystem: "request",
Name: "duration_seconds",
Help: "Gitea response time",
}, []string{"route"})
// ProtocolMiddlewares returns HTTP protocol related middlewares, and it provides a global panic recovery // ProtocolMiddlewares returns HTTP protocol related middlewares, and it provides a global panic recovery
func ProtocolMiddlewares() (handlers []any) { func ProtocolMiddlewares() (handlers []any) {
// the order is important // the order is important
@ -38,6 +48,9 @@ func ProtocolMiddlewares() (handlers []any) {
if setting.IsAccessLogEnabled() { if setting.IsAccessLogEnabled() {
handlers = append(handlers, context.AccessLogger()) handlers = append(handlers, context.AccessLogger())
} }
if setting.Metrics.Enabled {
handlers = append(handlers, RouteMetrics())
}
return handlers return handlers
} }
@ -107,6 +120,21 @@ func ForwardedHeadersHandler(limit int, trustedProxies []string) func(h http.Han
return proxy.ForwardedHeaders(opt) return proxy.ForwardedHeaders(opt)
} }
func RouteMetrics() func(h http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(resp http.ResponseWriter, req *http.Request) {
start := time.Now()
next.ServeHTTP(resp, req)
elapsed := time.Since(start).Seconds()
route := "ui"
if strings.HasPrefix(req.URL.Path, "/api") {
route = "api"
}
responseLatency.WithLabelValues(route).Observe(elapsed)
})
}
}
func Sessioner() func(next http.Handler) http.Handler { func Sessioner() func(next http.Handler) http.Handler {
return session.Sessioner(session.Options{ return session.Sessioner(session.Options{
Provider: setting.SessionConfig.Provider, Provider: setting.SessionConfig.Provider,

View File

@ -52,6 +52,7 @@ import (
"github.com/go-chi/cors" "github.com/go-chi/cors"
"github.com/klauspost/compress/gzhttp" "github.com/klauspost/compress/gzhttp"
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/collectors"
) )
var GzipMinSize = 1400 // min size to compress for the body size of response var GzipMinSize = 1400 // min size to compress for the body size of response
@ -258,6 +259,7 @@ func Routes() *web.Router {
} }
if setting.Metrics.Enabled { if setting.Metrics.Enabled {
prometheus.MustRegister(collectors.NewProcessCollector(collectors.ProcessCollectorOpts{Namespace: "gitea"}))
prometheus.MustRegister(metrics.NewCollector()) prometheus.MustRegister(metrics.NewCollector())
routes.Get("/metrics", append(mid, Metrics)...) routes.Get("/metrics", append(mid, Metrics)...)
} }