From fc5ee1edf90eb826a67921bb8d5c6b3e8c746225 Mon Sep 17 00:00:00 2001 From: Romain Date: Mon, 4 Oct 2021 00:46:44 +0200 Subject: [PATCH] Add metrics to get issues by label (#17201) * Add metrics to get issues by label * Add comment on IssueByLabelCount * Code review - Unify "AS" in SQL (#17201) * Code review - Remove useless join (#17201) * Code review - Disable issue_by_label by default in settings (#17201) * use e * restore empty line * update docs Co-authored-by: 6543 <6543@obermui.de> Co-authored-by: techknowlogick Co-authored-by: techknowlogick --- custom/conf/app.example.ini | 2 ++ .../doc/advanced/config-cheat-sheet.en-us.md | 1 + models/statistic.go | 19 +++++++++++++++++++ modules/metrics/collector.go | 17 ++++++++++++++++- modules/setting/setting.go | 10 ++++++---- 5 files changed, 44 insertions(+), 5 deletions(-) diff --git a/custom/conf/app.example.ini b/custom/conf/app.example.ini index 12a172f5ac..d8b73aa7eb 100644 --- a/custom/conf/app.example.ini +++ b/custom/conf/app.example.ini @@ -2041,6 +2041,8 @@ PATH = ;ENABLED = false ;; If you want to add authorization, specify a token here ;TOKEN = +;; Enable issue by label metrics; default is false +;ENABLED_ISSUE_BY_LABEL = false ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; diff --git a/docs/content/doc/advanced/config-cheat-sheet.en-us.md b/docs/content/doc/advanced/config-cheat-sheet.en-us.md index d80f96b3de..5726473d24 100644 --- a/docs/content/doc/advanced/config-cheat-sheet.en-us.md +++ b/docs/content/doc/advanced/config-cheat-sheet.en-us.md @@ -853,6 +853,7 @@ NB: You must have `DISABLE_ROUTER_LOG` set to `false` for this option to take ef ## Metrics (`metrics`) - `ENABLED`: **false**: Enables /metrics endpoint for prometheus. +- `ENABLED_ISSUE_BY_LABEL`: **false**: Enable issue by label metrics - `TOKEN`: **\**: You need to specify the token, if you want to include in the authorization the metrics . The same token need to be used in prometheus parameters `bearer_token` or `bearer_token_file`. ## API (`api`) diff --git a/models/statistic.go b/models/statistic.go index 1fdcc44a6f..c80cebba99 100644 --- a/models/statistic.go +++ b/models/statistic.go @@ -7,6 +7,7 @@ package models import ( "code.gitea.io/gitea/models/db" "code.gitea.io/gitea/models/login" + "code.gitea.io/gitea/modules/setting" ) // Statistic contains the database statistics @@ -20,9 +21,16 @@ type Statistic struct { Milestone, Label, HookTask, Team, UpdateTask, Project, ProjectBoard, Attachment int64 + IssueByLabel []IssueByLabelCount } } +// IssueByLabelCount contains the number of issue group by label +type IssueByLabelCount struct { + Count int64 + Label string +} + // GetStatistic returns the database statistics func GetStatistic() (stats Statistic) { e := db.GetEngine(db.DefaultContext) @@ -39,6 +47,17 @@ func GetStatistic() (stats Statistic) { Count int64 IsClosed bool } + + if setting.Metrics.EnabledIssueByLabel { + stats.Counter.IssueByLabel = []IssueByLabelCount{} + + _ = e.Select("COUNT(*) AS count, l.name AS label"). + Join("LEFT", "label l", "l.id=il.label_id"). + Table("issue_label il"). + GroupBy("l.name"). + Find(&stats.Counter.IssueByLabel) + } + issueCounts := []IssueCount{} _ = e.Select("COUNT(*) AS count, is_closed").Table("issue").GroupBy("is_closed").Find(&issueCounts) diff --git a/modules/metrics/collector.go b/modules/metrics/collector.go index 29374583d6..dcc147631b 100755 --- a/modules/metrics/collector.go +++ b/modules/metrics/collector.go @@ -24,6 +24,7 @@ type Collector struct { Issues *prometheus.Desc IssuesOpen *prometheus.Desc IssuesClosed *prometheus.Desc + IssuesByLabel *prometheus.Desc Labels *prometheus.Desc LoginSources *prometheus.Desc Milestones *prometheus.Desc @@ -45,6 +46,7 @@ type Collector struct { // NewCollector returns a new Collector with all prometheus.Desc initialized func NewCollector() Collector { + return Collector{ Accesses: prometheus.NewDesc( namespace+"accesses", @@ -81,6 +83,11 @@ func NewCollector() Collector { "Number of Issues", nil, nil, ), + IssuesByLabel: prometheus.NewDesc( + namespace+"issues_by_label", + "Number of Issues", + []string{"label"}, nil, + ), IssuesOpen: prometheus.NewDesc( namespace+"issues_open", "Number of open Issues", @@ -177,7 +184,6 @@ func NewCollector() Collector { nil, nil, ), } - } // Describe returns all possible prometheus.Desc @@ -189,6 +195,7 @@ func (c Collector) Describe(ch chan<- *prometheus.Desc) { ch <- c.Follows ch <- c.HookTasks ch <- c.Issues + ch <- c.IssuesByLabel ch <- c.IssuesOpen ch <- c.IssuesClosed ch <- c.Labels @@ -249,6 +256,14 @@ func (c Collector) Collect(ch chan<- prometheus.Metric) { prometheus.GaugeValue, float64(stats.Counter.Issue), ) + for _, il := range stats.Counter.IssueByLabel { + ch <- prometheus.MustNewConstMetric( + c.IssuesByLabel, + prometheus.GaugeValue, + float64(il.Count), + il.Label, + ) + } ch <- prometheus.MustNewConstMetric( c.IssuesClosed, prometheus.GaugeValue, diff --git a/modules/setting/setting.go b/modules/setting/setting.go index afd1e49aed..bdb3b1fd7b 100644 --- a/modules/setting/setting.go +++ b/modules/setting/setting.go @@ -390,11 +390,13 @@ var ( // Metrics settings Metrics = struct { - Enabled bool - Token string + Enabled bool + Token string + EnabledIssueByLabel bool }{ - Enabled: false, - Token: "", + Enabled: false, + Token: "", + EnabledIssueByLabel: false, } // I18n settings