mirror of
				https://gitee.com/gitea/gitea
				synced 2025-11-04 16:40:24 +08:00 
			
		
		
		
	Add metrics to get issues by repository (#17225)
This commit is contained in:
		@@ -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
 | 
			
		||||
 | 
			
		||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | 
			
		||||
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
 | 
			
		||||
 
 | 
			
		||||
@@ -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`)
 | 
			
		||||
 
 | 
			
		||||
@@ -22,6 +22,7 @@ type Statistic struct {
 | 
			
		||||
		Team, UpdateTask, Project,
 | 
			
		||||
		ProjectBoard, Attachment int64
 | 
			
		||||
		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)
 | 
			
		||||
 
 | 
			
		||||
@@ -25,6 +25,7 @@ type Collector struct {
 | 
			
		||||
	IssuesOpen         *prometheus.Desc
 | 
			
		||||
	IssuesClosed       *prometheus.Desc
 | 
			
		||||
	IssuesByLabel      *prometheus.Desc
 | 
			
		||||
	IssuesByRepository *prometheus.Desc
 | 
			
		||||
	Labels             *prometheus.Desc
 | 
			
		||||
	LoginSources       *prometheus.Desc
 | 
			
		||||
	Milestones         *prometheus.Desc
 | 
			
		||||
@@ -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,
 | 
			
		||||
 
 | 
			
		||||
@@ -393,10 +393,12 @@ var (
 | 
			
		||||
		Enabled                  bool
 | 
			
		||||
		Token                    string
 | 
			
		||||
		EnabledIssueByLabel      bool
 | 
			
		||||
		EnabledIssueByRepository bool
 | 
			
		||||
	}{
 | 
			
		||||
		Enabled:                  false,
 | 
			
		||||
		Token:                    "",
 | 
			
		||||
		EnabledIssueByLabel:      false,
 | 
			
		||||
		EnabledIssueByRepository: false,
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// I18n settings
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user