feat: add label 'state' to metric 'gitea_users' (#34326)

This PR adds the label _state_ to the metric _gitea_users_. With the
change, _gitea_users_ would be reported like this:

```
...
# HELP gitea_users Number of Users
# TYPE gitea_users gauge
gitea_users{state="active"} 20
gitea_users{state="inactive"} 10
...
```

The metrics above would be from a Gitea instance with 30 user accounts.
20 of the accounts are active and 10 of the accounts are not active.

Resolve #34325
This commit is contained in:
Tobias Balle-Petersen
2025-05-07 20:00:53 +02:00
committed by GitHub
parent dd886d729f
commit 020e774b91
3 changed files with 30 additions and 4 deletions

View File

@ -17,13 +17,15 @@ import (
repo_model "code.gitea.io/gitea/models/repo"
user_model "code.gitea.io/gitea/models/user"
"code.gitea.io/gitea/models/webhook"
"code.gitea.io/gitea/modules/optional"
"code.gitea.io/gitea/modules/setting"
)
// Statistic contains the database statistics
type Statistic struct {
Counter struct {
User, Org, PublicKey,
UsersActive, UsersNotActive,
Org, PublicKey,
Repo, Watch, Star, Access,
Issue, IssueClosed, IssueOpen,
Comment, Oauth, Follow,
@ -53,7 +55,19 @@ type IssueByRepositoryCount struct {
// GetStatistic returns the database statistics
func GetStatistic(ctx context.Context) (stats Statistic) {
e := db.GetEngine(ctx)
stats.Counter.User = user_model.CountUsers(ctx, nil)
// Number of active users
usersActiveOpts := user_model.CountUserFilter{
IsActive: optional.Some(true),
}
stats.Counter.UsersActive = user_model.CountUsers(ctx, &usersActiveOpts)
// Number of inactive users
usersNotActiveOpts := user_model.CountUserFilter{
IsActive: optional.Some(false),
}
stats.Counter.UsersNotActive = user_model.CountUsers(ctx, &usersNotActiveOpts)
stats.Counter.Org, _ = db.Count[organization.Organization](ctx, organization.FindOrgOptions{IncludePrivate: true})
stats.Counter.PublicKey, _ = e.Count(new(asymkey_model.PublicKey))
stats.Counter.Repo, _ = repo_model.CountRepositories(ctx, repo_model.CountRepositoryOptions{})

View File

@ -828,6 +828,7 @@ func IsLastAdminUser(ctx context.Context, user *User) bool {
type CountUserFilter struct {
LastLoginSince *int64
IsAdmin optional.Option[bool]
IsActive optional.Option[bool]
}
// CountUsers returns number of users.
@ -848,6 +849,10 @@ func countUsers(ctx context.Context, opts *CountUserFilter) int64 {
if opts.IsAdmin.Has() {
cond = cond.And(builder.Eq{"is_admin": opts.IsAdmin.Value()})
}
if opts.IsActive.Has() {
cond = cond.And(builder.Eq{"is_active": opts.IsActive.Value()})
}
}
count, err := sess.Where(cond).Count(new(User))

View File

@ -184,7 +184,7 @@ func NewCollector() Collector {
Users: prometheus.NewDesc(
namespace+"users",
"Number of Users",
nil, nil,
[]string{"state"}, nil,
),
Watches: prometheus.NewDesc(
namespace+"watches",
@ -373,7 +373,14 @@ func (c Collector) Collect(ch chan<- prometheus.Metric) {
ch <- prometheus.MustNewConstMetric(
c.Users,
prometheus.GaugeValue,
float64(stats.Counter.User),
float64(stats.Counter.UsersActive),
"active", // state label
)
ch <- prometheus.MustNewConstMetric(
c.Users,
prometheus.GaugeValue,
float64(stats.Counter.UsersNotActive),
"inactive", // state label
)
ch <- prometheus.MustNewConstMetric(
c.Watches,