From 14762abf0bebc57d355cf763c248cca4cbb60043 Mon Sep 17 00:00:00 2001
From: Romain <romdum@users.noreply.github.com>
Date: Sat, 7 Aug 2021 11:43:50 +0200
Subject: [PATCH] Separate open and closed issue in metrics (#16637)

* Get the issue counts in one query

Signed-off-by: Andrew Thornton <art27@cantab.net>

Co-authored-by: Andrew Thornton <art27@cantab.net>
---
 models/models.go             | 22 ++++++++++++++++++++--
 modules/metrics/collector.go | 24 ++++++++++++++++++++++++
 2 files changed, 44 insertions(+), 2 deletions(-)
 mode change 100644 => 100755 models/models.go
 mode change 100644 => 100755 modules/metrics/collector.go

diff --git a/models/models.go b/models/models.go
old mode 100644
new mode 100755
index 610933d327..378747dbce
--- a/models/models.go
+++ b/models/models.go
@@ -272,7 +272,8 @@ type Statistic struct {
 	Counter struct {
 		User, Org, PublicKey,
 		Repo, Watch, Star, Action, Access,
-		Issue, Comment, Oauth, Follow,
+		Issue, IssueClosed, IssueOpen,
+		Comment, Oauth, Follow,
 		Mirror, Release, LoginSource, Webhook,
 		Milestone, Label, HookTask,
 		Team, UpdateTask, Attachment int64
@@ -289,7 +290,24 @@ func GetStatistic() (stats Statistic) {
 	stats.Counter.Star, _ = x.Count(new(Star))
 	stats.Counter.Action, _ = x.Count(new(Action))
 	stats.Counter.Access, _ = x.Count(new(Access))
-	stats.Counter.Issue, _ = x.Count(new(Issue))
+
+	type IssueCount struct {
+		Count    int64
+		IsClosed bool
+	}
+	issueCounts := []IssueCount{}
+
+	_ = x.Select("COUNT(*) AS count, is_closed").Table("issue").GroupBy("is_closed").Find(&issueCounts)
+	for _, c := range issueCounts {
+		if c.IsClosed {
+			stats.Counter.IssueClosed = c.Count
+		} else {
+			stats.Counter.IssueOpen = c.Count
+		}
+	}
+
+	stats.Counter.Issue = stats.Counter.IssueClosed + stats.Counter.IssueOpen
+
 	stats.Counter.Comment, _ = x.Count(new(Comment))
 	stats.Counter.Oauth = 0
 	stats.Counter.Follow, _ = x.Count(new(Follow))
diff --git a/modules/metrics/collector.go b/modules/metrics/collector.go
old mode 100644
new mode 100755
index 6f6cf7cb64..f906b58f7d
--- a/modules/metrics/collector.go
+++ b/modules/metrics/collector.go
@@ -22,6 +22,8 @@ type Collector struct {
 	Follows       *prometheus.Desc
 	HookTasks     *prometheus.Desc
 	Issues        *prometheus.Desc
+	IssuesOpen    *prometheus.Desc
+	IssuesClosed  *prometheus.Desc
 	Labels        *prometheus.Desc
 	LoginSources  *prometheus.Desc
 	Milestones    *prometheus.Desc
@@ -77,6 +79,16 @@ func NewCollector() Collector {
 			"Number of Issues",
 			nil, nil,
 		),
+		IssuesOpen: prometheus.NewDesc(
+			namespace+"issues_open",
+			"Number of open Issues",
+			nil, nil,
+		),
+		IssuesClosed: prometheus.NewDesc(
+			namespace+"issues_closed",
+			"Number of closed Issues",
+			nil, nil,
+		),
 		Labels: prometheus.NewDesc(
 			namespace+"labels",
 			"Number of Labels",
@@ -165,6 +177,8 @@ func (c Collector) Describe(ch chan<- *prometheus.Desc) {
 	ch <- c.Follows
 	ch <- c.HookTasks
 	ch <- c.Issues
+	ch <- c.IssuesOpen
+	ch <- c.IssuesClosed
 	ch <- c.Labels
 	ch <- c.LoginSources
 	ch <- c.Milestones
@@ -221,6 +235,16 @@ func (c Collector) Collect(ch chan<- prometheus.Metric) {
 		prometheus.GaugeValue,
 		float64(stats.Counter.Issue),
 	)
+	ch <- prometheus.MustNewConstMetric(
+		c.IssuesClosed,
+		prometheus.GaugeValue,
+		float64(stats.Counter.IssueClosed),
+	)
+	ch <- prometheus.MustNewConstMetric(
+		c.IssuesOpen,
+		prometheus.GaugeValue,
+		float64(stats.Counter.IssueOpen),
+	)
 	ch <- prometheus.MustNewConstMetric(
 		c.Labels,
 		prometheus.GaugeValue,