Add metrics to get issues by repository (#17225)
This commit is contained in:
parent
760d61b411
commit
987152ba40
5 changed files with 73 additions and 35 deletions
|
@ -2043,6 +2043,8 @@ PATH =
|
||||||
;TOKEN =
|
;TOKEN =
|
||||||
;; Enable issue by label metrics; default is false
|
;; Enable issue by label metrics; default is false
|
||||||
;ENABLED_ISSUE_BY_LABEL = 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`)
|
## Metrics (`metrics`)
|
||||||
|
|
||||||
- `ENABLED`: **false**: Enables /metrics endpoint for prometheus.
|
- `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`.
|
- `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`)
|
## API (`api`)
|
||||||
|
|
|
@ -21,7 +21,8 @@ type Statistic struct {
|
||||||
Milestone, Label, HookTask,
|
Milestone, Label, HookTask,
|
||||||
Team, UpdateTask, Project,
|
Team, UpdateTask, Project,
|
||||||
ProjectBoard, Attachment int64
|
ProjectBoard, Attachment int64
|
||||||
IssueByLabel []IssueByLabelCount
|
IssueByLabel []IssueByLabelCount
|
||||||
|
IssueByRepository []IssueByRepositoryCount
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -31,6 +32,13 @@ type IssueByLabelCount struct {
|
||||||
Label string
|
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
|
// GetStatistic returns the database statistics
|
||||||
func GetStatistic() (stats Statistic) {
|
func GetStatistic() (stats Statistic) {
|
||||||
e := db.GetEngine(db.DefaultContext)
|
e := db.GetEngine(db.DefaultContext)
|
||||||
|
@ -58,6 +66,16 @@ func GetStatistic() (stats Statistic) {
|
||||||
Find(&stats.Counter.IssueByLabel)
|
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{}
|
issueCounts := []IssueCount{}
|
||||||
|
|
||||||
_ = e.Select("COUNT(*) AS count, is_closed").Table("issue").GroupBy("is_closed").Find(&issueCounts)
|
_ = e.Select("COUNT(*) AS count, is_closed").Table("issue").GroupBy("is_closed").Find(&issueCounts)
|
||||||
|
|
|
@ -15,33 +15,34 @@ const namespace = "gitea_"
|
||||||
// Collector implements the prometheus.Collector interface and
|
// Collector implements the prometheus.Collector interface and
|
||||||
// exposes gitea metrics for prometheus
|
// exposes gitea metrics for prometheus
|
||||||
type Collector struct {
|
type Collector struct {
|
||||||
Accesses *prometheus.Desc
|
Accesses *prometheus.Desc
|
||||||
Actions *prometheus.Desc
|
Actions *prometheus.Desc
|
||||||
Attachments *prometheus.Desc
|
Attachments *prometheus.Desc
|
||||||
Comments *prometheus.Desc
|
Comments *prometheus.Desc
|
||||||
Follows *prometheus.Desc
|
Follows *prometheus.Desc
|
||||||
HookTasks *prometheus.Desc
|
HookTasks *prometheus.Desc
|
||||||
Issues *prometheus.Desc
|
Issues *prometheus.Desc
|
||||||
IssuesOpen *prometheus.Desc
|
IssuesOpen *prometheus.Desc
|
||||||
IssuesClosed *prometheus.Desc
|
IssuesClosed *prometheus.Desc
|
||||||
IssuesByLabel *prometheus.Desc
|
IssuesByLabel *prometheus.Desc
|
||||||
Labels *prometheus.Desc
|
IssuesByRepository *prometheus.Desc
|
||||||
LoginSources *prometheus.Desc
|
Labels *prometheus.Desc
|
||||||
Milestones *prometheus.Desc
|
LoginSources *prometheus.Desc
|
||||||
Mirrors *prometheus.Desc
|
Milestones *prometheus.Desc
|
||||||
Oauths *prometheus.Desc
|
Mirrors *prometheus.Desc
|
||||||
Organizations *prometheus.Desc
|
Oauths *prometheus.Desc
|
||||||
Projects *prometheus.Desc
|
Organizations *prometheus.Desc
|
||||||
ProjectBoards *prometheus.Desc
|
Projects *prometheus.Desc
|
||||||
PublicKeys *prometheus.Desc
|
ProjectBoards *prometheus.Desc
|
||||||
Releases *prometheus.Desc
|
PublicKeys *prometheus.Desc
|
||||||
Repositories *prometheus.Desc
|
Releases *prometheus.Desc
|
||||||
Stars *prometheus.Desc
|
Repositories *prometheus.Desc
|
||||||
Teams *prometheus.Desc
|
Stars *prometheus.Desc
|
||||||
UpdateTasks *prometheus.Desc
|
Teams *prometheus.Desc
|
||||||
Users *prometheus.Desc
|
UpdateTasks *prometheus.Desc
|
||||||
Watches *prometheus.Desc
|
Users *prometheus.Desc
|
||||||
Webhooks *prometheus.Desc
|
Watches *prometheus.Desc
|
||||||
|
Webhooks *prometheus.Desc
|
||||||
}
|
}
|
||||||
|
|
||||||
// NewCollector returns a new Collector with all prometheus.Desc initialized
|
// NewCollector returns a new Collector with all prometheus.Desc initialized
|
||||||
|
@ -88,6 +89,11 @@ func NewCollector() Collector {
|
||||||
"Number of Issues",
|
"Number of Issues",
|
||||||
[]string{"label"}, nil,
|
[]string{"label"}, nil,
|
||||||
),
|
),
|
||||||
|
IssuesByRepository: prometheus.NewDesc(
|
||||||
|
namespace+"issues_by_repository",
|
||||||
|
"Number of Issues",
|
||||||
|
[]string{"repository"}, nil,
|
||||||
|
),
|
||||||
IssuesOpen: prometheus.NewDesc(
|
IssuesOpen: prometheus.NewDesc(
|
||||||
namespace+"issues_open",
|
namespace+"issues_open",
|
||||||
"Number of open Issues",
|
"Number of open Issues",
|
||||||
|
@ -196,6 +202,7 @@ func (c Collector) Describe(ch chan<- *prometheus.Desc) {
|
||||||
ch <- c.HookTasks
|
ch <- c.HookTasks
|
||||||
ch <- c.Issues
|
ch <- c.Issues
|
||||||
ch <- c.IssuesByLabel
|
ch <- c.IssuesByLabel
|
||||||
|
ch <- c.IssuesByRepository
|
||||||
ch <- c.IssuesOpen
|
ch <- c.IssuesOpen
|
||||||
ch <- c.IssuesClosed
|
ch <- c.IssuesClosed
|
||||||
ch <- c.Labels
|
ch <- c.Labels
|
||||||
|
@ -264,6 +271,14 @@ func (c Collector) Collect(ch chan<- prometheus.Metric) {
|
||||||
il.Label,
|
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(
|
ch <- prometheus.MustNewConstMetric(
|
||||||
c.IssuesClosed,
|
c.IssuesClosed,
|
||||||
prometheus.GaugeValue,
|
prometheus.GaugeValue,
|
||||||
|
|
|
@ -390,13 +390,15 @@ var (
|
||||||
|
|
||||||
// Metrics settings
|
// Metrics settings
|
||||||
Metrics = struct {
|
Metrics = struct {
|
||||||
Enabled bool
|
Enabled bool
|
||||||
Token string
|
Token string
|
||||||
EnabledIssueByLabel bool
|
EnabledIssueByLabel bool
|
||||||
|
EnabledIssueByRepository bool
|
||||||
}{
|
}{
|
||||||
Enabled: false,
|
Enabled: false,
|
||||||
Token: "",
|
Token: "",
|
||||||
EnabledIssueByLabel: false,
|
EnabledIssueByLabel: false,
|
||||||
|
EnabledIssueByRepository: false,
|
||||||
}
|
}
|
||||||
|
|
||||||
// I18n settings
|
// I18n settings
|
||||||
|
|
Reference in a new issue