From 333444b4e17ecc707fefeadaba3bd0e634d59bf0 Mon Sep 17 00:00:00 2001 From: kolaente Date: Fri, 15 May 2020 14:42:32 +0200 Subject: [PATCH] Improve metrics performance --- pkg/metrics/active_users.go | 26 ++++++++++++++++++++++---- pkg/metrics/metrics.go | 5 +++++ pkg/routes/metrics.go | 25 +------------------------ 3 files changed, 28 insertions(+), 28 deletions(-) diff --git a/pkg/metrics/active_users.go b/pkg/metrics/active_users.go index e0ae26e78a..2d07f5a5e2 100644 --- a/pkg/metrics/active_users.go +++ b/pkg/metrics/active_users.go @@ -19,6 +19,7 @@ package metrics import ( "bytes" "code.vikunja.io/api/pkg/log" + "code.vikunja.io/web" "encoding/gob" "github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus/promauto" @@ -37,7 +38,15 @@ type ActiveUser struct { LastSeen time.Time } +// ActiveUsersMap is the type used to save active users +type ActiveUsersMap map[int64]*ActiveUser + +// activeUsers holds a map with all active users +var activeUsers ActiveUsersMap + func init() { + activeUsers = make(ActiveUsersMap) + promauto.NewGaugeFunc(prometheus.GaugeOpts{ Name: "vikunja_active_users", Help: "The currently active users on this node", @@ -57,8 +66,17 @@ func init() { }) } +// SetUserActive sets a user as active and pushes it to redis +func SetUserActive(a web.Auth) (err error) { + activeUsers[a.GetID()] = &ActiveUser{ + UserID: a.GetID(), + LastSeen: time.Now(), + } + return PushActiveUsers() +} + // GetActiveUsers returns the active users from redis -func GetActiveUsers() (users []*ActiveUser, err error) { +func GetActiveUsers() (users ActiveUsersMap, err error) { activeUsersR, err := r.Get(ActiveUsersKey).Bytes() if err != nil { @@ -80,11 +98,11 @@ func GetActiveUsers() (users []*ActiveUser, err error) { return } -// SetActiveUsers sets the active users from redis -func SetActiveUsers(users []*ActiveUser) (err error) { +// PushActiveUsers pushed the content of the activeUsers map to redis +func PushActiveUsers() (err error) { var b bytes.Buffer e := gob.NewEncoder(&b) - if err := e.Encode(users); err != nil { + if err := e.Encode(activeUsers); err != nil { return err } diff --git a/pkg/metrics/metrics.go b/pkg/metrics/metrics.go index 335da531da..715543ef87 100644 --- a/pkg/metrics/metrics.go +++ b/pkg/metrics/metrics.go @@ -48,6 +48,11 @@ const ( func InitMetrics() { r = red.GetRedis() + // init active users, sometimes we'll have garbage from previous runs in redis instead + if err := PushActiveUsers(); err != nil { + log.Fatalf("Could not set initial count for active users, error was %s", err) + } + // Register total list count metric promauto.NewGaugeFunc(prometheus.GaugeOpts{ Name: "vikunja_list_count", diff --git a/pkg/routes/metrics.go b/pkg/routes/metrics.go index 1f811abfbc..a0a9031c79 100644 --- a/pkg/routes/metrics.go +++ b/pkg/routes/metrics.go @@ -26,7 +26,6 @@ import ( "code.vikunja.io/api/pkg/user" "github.com/labstack/echo/v4" "github.com/prometheus/client_golang/prometheus/promhttp" - "time" ) func setupMetrics(a *echo.Group) { @@ -77,11 +76,6 @@ func setupMetrics(a *echo.Group) { } } - // init active users, sometimes we'll have garbage from previous runs in redis instead - if err := metrics.SetActiveUsers([]*metrics.ActiveUser{}); err != nil { - log.Fatalf("Could not set initial count for active users, error was %s", err) - } - a.GET("/metrics", echo.WrapHandler(promhttp.Handler())) } @@ -110,22 +104,5 @@ func updateActiveUsersFromContext(c echo.Context) (err error) { return } - allActiveUsers, err := metrics.GetActiveUsers() - if err != nil { - return - } - - var uupdated bool - for in, u := range allActiveUsers { - if u.UserID == auth.GetID() { - allActiveUsers[in].LastSeen = time.Now() - uupdated = true - } - } - - if !uupdated { - allActiveUsers = append(allActiveUsers, &metrics.ActiveUser{UserID: auth.GetID(), LastSeen: time.Now()}) - } - - return metrics.SetActiveUsers(allActiveUsers) + return metrics.SetUserActive(auth) }