]> source.dussan.org Git - gitea.git/commitdiff
Add metrics to get issues by repository (#17225)
authorRomain <romdum@users.noreply.github.com>
Tue, 5 Oct 2021 18:39:37 +0000 (20:39 +0200)
committerGitHub <noreply@github.com>
Tue, 5 Oct 2021 18:39:37 +0000 (20:39 +0200)
custom/conf/app.example.ini
docs/content/doc/advanced/config-cheat-sheet.en-us.md
models/statistic.go
modules/metrics/collector.go
modules/setting/setting.go

index d8b73aa7eb6ed71f0408f95e2df63f3b65165b0b..0a25e7e5cd540c3f4f7da2534615a47e5fb684cc 100644 (file)
@@ -2043,6 +2043,8 @@ PATH =
 ;TOKEN =
 ;; Enable issue by label metrics; default is false
 ;ENABLED_ISSUE_BY_LABEL = false
+;; Enable issue by repository metrics; default is false
+;ENABLED_ISSUE_BY_REPOSITORY = false
 
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
index 5726473d240f03658c89cd6b3bb0cb23021a14eb..d224533e964c32e7d20487eeeadf65d33052a122 100644 (file)
@@ -853,7 +853,8 @@ 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
+- `ENABLED_ISSUE_BY_LABEL`: **false**: Enable issue by label metrics with format `gitea_issues_by_label{label="bug"} 2`.
+- `ENABLED_ISSUE_BY_REPOSITORY`: **false**: Enable issue by repository metrics with format `gitea_issues_by_repository{repository="org/repo"} 5`.
 - `TOKEN`: **\<empty\>**: 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`)
index c80cebba99feb1521a0a32d475793e03f7def95f..5e72dc713dccad023b6345065000decb078d92dd 100644 (file)
@@ -21,7 +21,8 @@ type Statistic struct {
                Milestone, Label, HookTask,
                Team, UpdateTask, Project,
                ProjectBoard, Attachment int64
-               IssueByLabel []IssueByLabelCount
+               IssueByLabel      []IssueByLabelCount
+               IssueByRepository []IssueByRepositoryCount
        }
 }
 
@@ -31,6 +32,13 @@ type IssueByLabelCount struct {
        Label string
 }
 
+// IssueByRepositoryCount contains the number of issue group by repository
+type IssueByRepositoryCount struct {
+       Count      int64
+       OwnerName  string
+       Repository string
+}
+
 // GetStatistic returns the database statistics
 func GetStatistic() (stats Statistic) {
        e := db.GetEngine(db.DefaultContext)
@@ -58,6 +66,16 @@ func GetStatistic() (stats Statistic) {
                        Find(&stats.Counter.IssueByLabel)
        }
 
+       if setting.Metrics.EnabledIssueByRepository {
+               stats.Counter.IssueByRepository = []IssueByRepositoryCount{}
+
+               _ = e.Select("COUNT(*) AS count, r.owner_name, r.name AS repository").
+                       Join("LEFT", "repository r", "r.id=i.repo_id").
+                       Table("issue i").
+                       GroupBy("r.owner_name, r.name").
+                       Find(&stats.Counter.IssueByRepository)
+       }
+
        issueCounts := []IssueCount{}
 
        _ = e.Select("COUNT(*) AS count, is_closed").Table("issue").GroupBy("is_closed").Find(&issueCounts)
index dcc147631b7023406a4eac16aba7260905f252a2..527202e0a6d6f35df0157a330afc7b62ffaa537f 100755 (executable)
@@ -15,33 +15,34 @@ const namespace = "gitea_"
 // Collector implements the prometheus.Collector interface and
 // exposes gitea metrics for prometheus
 type Collector struct {
-       Accesses      *prometheus.Desc
-       Actions       *prometheus.Desc
-       Attachments   *prometheus.Desc
-       Comments      *prometheus.Desc
-       Follows       *prometheus.Desc
-       HookTasks     *prometheus.Desc
-       Issues        *prometheus.Desc
-       IssuesOpen    *prometheus.Desc
-       IssuesClosed  *prometheus.Desc
-       IssuesByLabel *prometheus.Desc
-       Labels        *prometheus.Desc
-       LoginSources  *prometheus.Desc
-       Milestones    *prometheus.Desc
-       Mirrors       *prometheus.Desc
-       Oauths        *prometheus.Desc
-       Organizations *prometheus.Desc
-       Projects      *prometheus.Desc
-       ProjectBoards *prometheus.Desc
-       PublicKeys    *prometheus.Desc
-       Releases      *prometheus.Desc
-       Repositories  *prometheus.Desc
-       Stars         *prometheus.Desc
-       Teams         *prometheus.Desc
-       UpdateTasks   *prometheus.Desc
-       Users         *prometheus.Desc
-       Watches       *prometheus.Desc
-       Webhooks      *prometheus.Desc
+       Accesses           *prometheus.Desc
+       Actions            *prometheus.Desc
+       Attachments        *prometheus.Desc
+       Comments           *prometheus.Desc
+       Follows            *prometheus.Desc
+       HookTasks          *prometheus.Desc
+       Issues             *prometheus.Desc
+       IssuesOpen         *prometheus.Desc
+       IssuesClosed       *prometheus.Desc
+       IssuesByLabel      *prometheus.Desc
+       IssuesByRepository *prometheus.Desc
+       Labels             *prometheus.Desc
+       LoginSources       *prometheus.Desc
+       Milestones         *prometheus.Desc
+       Mirrors            *prometheus.Desc
+       Oauths             *prometheus.Desc
+       Organizations      *prometheus.Desc
+       Projects           *prometheus.Desc
+       ProjectBoards      *prometheus.Desc
+       PublicKeys         *prometheus.Desc
+       Releases           *prometheus.Desc
+       Repositories       *prometheus.Desc
+       Stars              *prometheus.Desc
+       Teams              *prometheus.Desc
+       UpdateTasks        *prometheus.Desc
+       Users              *prometheus.Desc
+       Watches            *prometheus.Desc
+       Webhooks           *prometheus.Desc
 }
 
 // NewCollector returns a new Collector with all prometheus.Desc initialized
@@ -88,6 +89,11 @@ func NewCollector() Collector {
                        "Number of Issues",
                        []string{"label"}, nil,
                ),
+               IssuesByRepository: prometheus.NewDesc(
+                       namespace+"issues_by_repository",
+                       "Number of Issues",
+                       []string{"repository"}, nil,
+               ),
                IssuesOpen: prometheus.NewDesc(
                        namespace+"issues_open",
                        "Number of open Issues",
@@ -196,6 +202,7 @@ func (c Collector) Describe(ch chan<- *prometheus.Desc) {
        ch <- c.HookTasks
        ch <- c.Issues
        ch <- c.IssuesByLabel
+       ch <- c.IssuesByRepository
        ch <- c.IssuesOpen
        ch <- c.IssuesClosed
        ch <- c.Labels
@@ -264,6 +271,14 @@ func (c Collector) Collect(ch chan<- prometheus.Metric) {
                        il.Label,
                )
        }
+       for _, ir := range stats.Counter.IssueByRepository {
+               ch <- prometheus.MustNewConstMetric(
+                       c.IssuesByRepository,
+                       prometheus.GaugeValue,
+                       float64(ir.Count),
+                       ir.OwnerName+"/"+ir.Repository,
+               )
+       }
        ch <- prometheus.MustNewConstMetric(
                c.IssuesClosed,
                prometheus.GaugeValue,
index bdb3b1fd7b93dd7e81ca3655525c09e106ce2d66..88302be1d3ec96b106ee0b8de9fa25203fa2c79a 100644 (file)
@@ -390,13 +390,15 @@ var (
 
        // Metrics settings
        Metrics = struct {
-               Enabled             bool
-               Token               string
-               EnabledIssueByLabel bool
+               Enabled                  bool
+               Token                    string
+               EnabledIssueByLabel      bool
+               EnabledIssueByRepository bool
        }{
-               Enabled:             false,
-               Token:               "",
-               EnabledIssueByLabel: false,
+               Enabled:                  false,
+               Token:                    "",
+               EnabledIssueByLabel:      false,
+               EnabledIssueByRepository: false,
        }
 
        // I18n settings