From 7842fd13ef3058e4e1f60ff72164edc41a1fe819 Mon Sep 17 00:00:00 2001 From: Thomas Boerger Date: Thu, 23 Mar 2023 09:14:37 +0100 Subject: [PATCH 1/4] feat: implement admin stats --- CHANGELOG.md | 10 + changelog/unreleased/admin-stats.md | 9 + docs/partials/envvars.md | 3 + docs/partials/metrics.md | 102 +++++ hack/generate-metrics-docs.go | 5 + pkg/action/server.go | 14 + pkg/command/command.go | 7 + pkg/config/config.go | 1 + pkg/exporter/admin.go | 633 ++++++++++++++++++++++++++++ 9 files changed, 784 insertions(+) create mode 100644 changelog/unreleased/admin-stats.md create mode 100644 pkg/exporter/admin.go diff --git a/CHANGELOG.md b/CHANGELOG.md index 17996f6..75d8469 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -8,6 +8,7 @@ The following sections list the changes for unreleased. * Enh #123: Add metrics for GitHub workflows * Enh #174: Merge all billing related metrics * Enh #174: Update all releated dependencies + * Enh #183: Integrate admin stats for GitHub enterprise ## Details @@ -39,6 +40,15 @@ The following sections list the changes for unreleased. https://github.com/promhippie/github_exporter/pull/174 + * Enhancement #183: Integrate admin stats for GitHub enterprise + + We've integrated another collector within this exporter to provide admin stats as metrics to + get a general overview about the amount of repos, issues, pull requests and so on. Special + thanks for the great initial work by @mafrosis, your effort is highly appreciated. + + https://github.com/promhippie/github_exporter/issues/183 + https://github.com/promhippie/github_exporter/pull/23 + # Changelog for 1.2.0 diff --git a/changelog/unreleased/admin-stats.md b/changelog/unreleased/admin-stats.md new file mode 100644 index 0000000..8f6f438 --- /dev/null +++ b/changelog/unreleased/admin-stats.md @@ -0,0 +1,9 @@ +Enhancement: Integrate admin stats for GitHub enterprise + +We've integrated another collector within this exporter to provide admin stats +as metrics to get a general overview about the amount of repos, issues, pull +requests and so on. Special thanks for the great initial work by @mafrosis, your +effort is highly appreciated. + +https://github.com/promhippie/github_exporter/issues/183 +https://github.com/promhippie/github_exporter/pull/23 diff --git a/docs/partials/envvars.md b/docs/partials/envvars.md index d6c1c38..be86c1c 100644 --- a/docs/partials/envvars.md +++ b/docs/partials/envvars.md @@ -46,6 +46,9 @@ GITHUB_EXPORTER_ORG, GITHUB_EXPORTER_ORGS GITHUB_EXPORTER_REPO, GITHUB_EXPORTER_REPOS : Repositories to scrape metrics from, comma-separated list +GITHUB_EXPORTER_COLLECTOR_ADMIN +: Enable collector for admin stats, defaults to `false` + GITHUB_EXPORTER_COLLECTOR_ORGS : Enable collector for orgs, defaults to `true` diff --git a/docs/partials/metrics.md b/docs/partials/metrics.md index 539a43e..26ce249 100644 --- a/docs/partials/metrics.md +++ b/docs/partials/metrics.md @@ -10,6 +10,108 @@ github_action_billing_minutes_used_breakdown{type, name, os} github_action_billing_paid_minutes{type, name} : Total paid minutes used for this type +github_admin_comments_commit{} +: Number of commit comments + +github_admin_comments_gist{} +: Number of gist comments + +github_admin_comments_issue{} +: Number of issue comments + +github_admin_comments_pull_request{} +: Number of pull request comments + +github_admin_gists_private{} +: Number of private gists + +github_admin_gists_public{} +: Number of public gists + +github_admin_gists_total{} +: Total number of gists + +github_admin_hooks_active{} +: Number of active hooks + +github_admin_hooks_inactive{} +: Number of inactive hooks + +github_admin_hooks_total{} +: Total number of hooks + +github_admin_issues_closed{} +: Number of closed issues + +github_admin_issues_open{} +: Number of open issues + +github_admin_issues_total{} +: Total number of issues + +github_admin_milestones_closed{} +: Number of closed milestones + +github_admin_milestones_open{} +: Number of open milestones + +github_admin_milestones_total{} +: Total number of milestones + +github_admin_orgs_disabled{} +: Number of disabled organizations + +github_admin_orgs_members{} +: Number of organization team members + +github_admin_orgs_teams{} +: Number of organization teams + +github_admin_orgs_total{} +: Total number of organizations + +github_admin_pages_total{} +: Total number of pages + +github_admin_pulls_mergeable{} +: Number of mergeable pull requests + +github_admin_pulls_merged{} +: Number of merged pull requests + +github_admin_pulls_total{} +: Total number of pull requests + +github_admin_pulls_unmergeable{} +: Number of unmergeable pull requests + +github_admin_repos_fork{} +: Number of fork repositories + +github_admin_repos_org{} +: Number of organization repos + +github_admin_repos_pushes_total{} +: Total number of pushes + +github_admin_repos_root{} +: Number of root repositories + +github_admin_repos_total{} +: Total number of repositories + +github_admin_repos_wikis_total{} +: Total number of wikis + +github_admin_users_admin{} +: Number of admin users + +github_admin_users_suspended{} +: Number of suspended users + +github_admin_users_total{} +: Total number of users + github_org_collaborators{name} : Number of collaborators within org diff --git a/hack/generate-metrics-docs.go b/hack/generate-metrics-docs.go index 022a82c..a2ad3b5 100644 --- a/hack/generate-metrics-docs.go +++ b/hack/generate-metrics-docs.go @@ -24,6 +24,11 @@ type metric struct { func main() { collectors := make([]*prometheus.Desc, 0) + collectors = append( + collectors, + exporter.NewAdminCollector(nil, nil, nil, nil, config.Load().Target).Metrics()..., + ) + collectors = append( collectors, exporter.NewOrgCollector(nil, nil, nil, nil, config.Load().Target).Metrics()..., diff --git a/pkg/action/server.go b/pkg/action/server.go index 5aef4c5..f6a64eb 100644 --- a/pkg/action/server.go +++ b/pkg/action/server.go @@ -189,6 +189,20 @@ func handler(cfg *config.Config, logger log.Logger, client *github.Client) *chi. mux.Use(middleware.Timeout) mux.Use(middleware.Cache) + if cfg.Collector.Admin { + level.Debug(logger).Log( + "msg", "Admin collector registered", + ) + + registry.MustRegister(exporter.NewAdminCollector( + logger, + client, + requestFailures, + requestDuration, + cfg.Target, + )) + } + if cfg.Collector.Orgs { level.Debug(logger).Log( "msg", "Org collector registered", diff --git a/pkg/command/command.go b/pkg/command/command.go index e30d49e..c307d2d 100644 --- a/pkg/command/command.go +++ b/pkg/command/command.go @@ -163,6 +163,13 @@ func RootFlags(cfg *config.Config) []cli.Flag { EnvVars: []string{"GITHUB_EXPORTER_REPO", "GITHUB_EXPORTER_REPOS"}, Destination: &cfg.Target.Repos, }, + &cli.BoolFlag{ + Name: "collector.admin", + Value: false, + Usage: "Enable collector for admin stats", + EnvVars: []string{"GITHUB_EXPORTER_COLLECTOR_ADMIN"}, + Destination: &cfg.Collector.Admin, + }, &cli.BoolFlag{ Name: "collector.orgs", Value: true, diff --git a/pkg/config/config.go b/pkg/config/config.go index 3adc2bd..a2dcf20 100644 --- a/pkg/config/config.go +++ b/pkg/config/config.go @@ -36,6 +36,7 @@ type Target struct { // Collector defines the collector specific configuration. type Collector struct { + Admin bool Orgs bool Repos bool Billing bool diff --git a/pkg/exporter/admin.go b/pkg/exporter/admin.go new file mode 100644 index 0000000..3ae4ae5 --- /dev/null +++ b/pkg/exporter/admin.go @@ -0,0 +1,633 @@ +package exporter + +import ( + "context" + "time" + + "github.com/go-kit/log" + "github.com/go-kit/log/level" + "github.com/google/go-github/v50/github" + "github.com/prometheus/client_golang/prometheus" + "github.com/promhippie/github_exporter/pkg/config" +) + +// AdminCollector collects metrics about the servers. +type AdminCollector struct { + client *github.Client + logger log.Logger + failures *prometheus.CounterVec + duration *prometheus.HistogramVec + config config.Target + + ReposTotal *prometheus.Desc + ReposRoot *prometheus.Desc + ReposFork *prometheus.Desc + ReposOrg *prometheus.Desc + ReposTotalPushes *prometheus.Desc + ReposTotalWikis *prometheus.Desc + + HooksTotal *prometheus.Desc + HooksActive *prometheus.Desc + HooksInactive *prometheus.Desc + + PagesTotal *prometheus.Desc + + OrgsTotal *prometheus.Desc + OrgsDisabled *prometheus.Desc + OrgsTotalTeams *prometheus.Desc + OrgsTotalMembers *prometheus.Desc + + UsersTotal *prometheus.Desc + UsersAdmin *prometheus.Desc + UsersSuspended *prometheus.Desc + + PullsTotal *prometheus.Desc + PullsMerged *prometheus.Desc + PullsMergeable *prometheus.Desc + PullsUnmergeable *prometheus.Desc + + IssuesTotal *prometheus.Desc + IssuesOpen *prometheus.Desc + IssuesClosed *prometheus.Desc + + MilestonesTotal *prometheus.Desc + MilestonesOpen *prometheus.Desc + MilestonesClosed *prometheus.Desc + + GistsTotal *prometheus.Desc + GistsPrivate *prometheus.Desc + GistsPublic *prometheus.Desc + + CommentsCommit *prometheus.Desc + CommentsGist *prometheus.Desc + CommentsIssue *prometheus.Desc + CommentsPullRequest *prometheus.Desc +} + +// NewAdminCollector returns a new AdminCollector. +func NewAdminCollector(logger log.Logger, client *github.Client, failures *prometheus.CounterVec, duration *prometheus.HistogramVec, cfg config.Target) *AdminCollector { + if failures != nil { + failures.WithLabelValues("admin").Add(0) + } + + labels := []string{} + return &AdminCollector{ + client: client, + logger: log.With(logger, "collector", "admin"), + failures: failures, + duration: duration, + config: cfg, + + ReposTotal: prometheus.NewDesc( + "github_admin_repos_total", + "Total number of repositories", + labels, + nil, + ), + ReposRoot: prometheus.NewDesc( + "github_admin_repos_root", + "Number of root repositories", + labels, + nil, + ), + ReposFork: prometheus.NewDesc( + "github_admin_repos_fork", + "Number of fork repositories", + labels, + nil, + ), + ReposOrg: prometheus.NewDesc( + "github_admin_repos_org", + "Number of organization repos", + labels, + nil, + ), + ReposTotalPushes: prometheus.NewDesc( + "github_admin_repos_pushes_total", + "Total number of pushes", + labels, + nil, + ), + ReposTotalWikis: prometheus.NewDesc( + "github_admin_repos_wikis_total", + "Total number of wikis", + labels, + nil, + ), + + HooksTotal: prometheus.NewDesc( + "github_admin_hooks_total", + "Total number of hooks", + labels, + nil, + ), + HooksActive: prometheus.NewDesc( + "github_admin_hooks_active", + "Number of active hooks", + labels, + nil, + ), + HooksInactive: prometheus.NewDesc( + "github_admin_hooks_inactive", + "Number of inactive hooks", + labels, + nil, + ), + + PagesTotal: prometheus.NewDesc( + "github_admin_pages_total", + "Total number of pages", + labels, + nil, + ), + + OrgsTotal: prometheus.NewDesc( + "github_admin_orgs_total", + "Total number of organizations", + labels, + nil, + ), + OrgsDisabled: prometheus.NewDesc( + "github_admin_orgs_disabled", + "Number of disabled organizations", + labels, + nil, + ), + OrgsTotalTeams: prometheus.NewDesc( + "github_admin_orgs_teams", + "Number of organization teams", + labels, + nil, + ), + OrgsTotalMembers: prometheus.NewDesc( + "github_admin_orgs_members", + "Number of organization team members", + labels, + nil, + ), + + UsersTotal: prometheus.NewDesc( + "github_admin_users_total", + "Total number of users", + labels, + nil, + ), + UsersAdmin: prometheus.NewDesc( + "github_admin_users_admin", + "Number of admin users", + labels, + nil, + ), + UsersSuspended: prometheus.NewDesc( + "github_admin_users_suspended", + "Number of suspended users", + labels, + nil, + ), + + PullsTotal: prometheus.NewDesc( + "github_admin_pulls_total", + "Total number of pull requests", + labels, + nil, + ), + PullsMerged: prometheus.NewDesc( + "github_admin_pulls_merged", + "Number of merged pull requests", + labels, + nil, + ), + PullsMergeable: prometheus.NewDesc( + "github_admin_pulls_mergeable", + "Number of mergeable pull requests", + labels, + nil, + ), + PullsUnmergeable: prometheus.NewDesc( + "github_admin_pulls_unmergeable", + "Number of unmergeable pull requests", + labels, + nil, + ), + + IssuesTotal: prometheus.NewDesc( + "github_admin_issues_total", + "Total number of issues", + labels, + nil, + ), + IssuesOpen: prometheus.NewDesc( + "github_admin_issues_open", + "Number of open issues", + labels, + nil, + ), + IssuesClosed: prometheus.NewDesc( + "github_admin_issues_closed", + "Number of closed issues", + labels, + nil, + ), + + MilestonesTotal: prometheus.NewDesc( + "github_admin_milestones_total", + "Total number of milestones", + labels, + nil, + ), + MilestonesOpen: prometheus.NewDesc( + "github_admin_milestones_open", + "Number of open milestones", + labels, + nil, + ), + MilestonesClosed: prometheus.NewDesc( + "github_admin_milestones_closed", + "Number of closed milestones", + labels, + nil, + ), + + GistsTotal: prometheus.NewDesc( + "github_admin_gists_total", + "Total number of gists", + labels, + nil, + ), + GistsPrivate: prometheus.NewDesc( + "github_admin_gists_private", + "Number of private gists", + labels, + nil, + ), + GistsPublic: prometheus.NewDesc( + "github_admin_gists_public", + "Number of public gists", + labels, + nil, + ), + + CommentsCommit: prometheus.NewDesc( + "github_admin_comments_commit", + "Number of commit comments", + labels, + nil, + ), + CommentsGist: prometheus.NewDesc( + "github_admin_comments_gist", + "Number of gist comments", + labels, + nil, + ), + CommentsIssue: prometheus.NewDesc( + "github_admin_comments_issue", + "Number of issue comments", + labels, + nil, + ), + CommentsPullRequest: prometheus.NewDesc( + "github_admin_comments_pull_request", + "Number of pull request comments", + labels, + nil, + ), + } +} + +// Metrics simply returns the list metric descriptors for generating a documentation. +func (c *AdminCollector) Metrics() []*prometheus.Desc { + return []*prometheus.Desc{ + c.ReposTotal, + c.ReposRoot, + c.ReposFork, + c.ReposOrg, + c.ReposTotalPushes, + c.ReposTotalWikis, + c.HooksTotal, + c.HooksActive, + c.HooksInactive, + c.PagesTotal, + c.OrgsTotal, + c.OrgsDisabled, + c.OrgsTotalTeams, + c.OrgsTotalMembers, + c.UsersTotal, + c.UsersAdmin, + c.UsersSuspended, + c.PullsTotal, + c.PullsMerged, + c.PullsMergeable, + c.PullsUnmergeable, + c.IssuesTotal, + c.IssuesOpen, + c.IssuesClosed, + c.MilestonesTotal, + c.MilestonesOpen, + c.MilestonesClosed, + c.GistsTotal, + c.GistsPrivate, + c.GistsPublic, + c.CommentsCommit, + c.CommentsGist, + c.CommentsIssue, + c.CommentsPullRequest, + } +} + +// Describe sends the super-set of all possible descriptors of metrics collected by this Collector. +func (c *AdminCollector) Describe(ch chan<- *prometheus.Desc) { + ch <- c.ReposTotal + ch <- c.ReposRoot + ch <- c.ReposFork + ch <- c.ReposOrg + ch <- c.ReposTotalPushes + ch <- c.ReposTotalWikis + ch <- c.HooksTotal + ch <- c.HooksActive + ch <- c.HooksInactive + ch <- c.PagesTotal + ch <- c.OrgsTotal + ch <- c.OrgsDisabled + ch <- c.OrgsTotalTeams + ch <- c.OrgsTotalMembers + ch <- c.UsersTotal + ch <- c.UsersAdmin + ch <- c.UsersSuspended + ch <- c.PullsTotal + ch <- c.PullsMerged + ch <- c.PullsMergeable + ch <- c.PullsUnmergeable + ch <- c.IssuesTotal + ch <- c.IssuesOpen + ch <- c.IssuesClosed + ch <- c.MilestonesTotal + ch <- c.MilestonesOpen + ch <- c.MilestonesClosed + ch <- c.GistsTotal + ch <- c.GistsPrivate + ch <- c.GistsPublic + ch <- c.CommentsCommit + ch <- c.CommentsGist + ch <- c.CommentsIssue + ch <- c.CommentsPullRequest +} + +// Collect is called by the Prometheus registry when collecting metrics. +func (c *AdminCollector) Collect(ch chan<- prometheus.Metric) { + ctx, cancel := context.WithTimeout(context.Background(), c.config.Timeout) + defer cancel() + + now := time.Now() + record, _, err := c.client.Admin.GetAdminStats(ctx) + c.duration.WithLabelValues("admin").Observe(time.Since(now).Seconds()) + + if err != nil { + level.Error(c.logger).Log( + "msg", "Failed to fetch admin stats", + "err", err, + ) + + c.failures.WithLabelValues("admin").Inc() + return + } + + labels := []string{} + + ch <- prometheus.MustNewConstMetric( + c.ReposTotal, + prometheus.GaugeValue, + float64(record.GetRepos().GetTotalRepos()), + labels..., + ) + + ch <- prometheus.MustNewConstMetric( + c.ReposRoot, + prometheus.GaugeValue, + float64(record.GetRepos().GetRootRepos()), + labels..., + ) + + ch <- prometheus.MustNewConstMetric( + c.ReposFork, + prometheus.GaugeValue, + float64(record.GetRepos().GetForkRepos()), + labels..., + ) + + ch <- prometheus.MustNewConstMetric( + c.ReposOrg, + prometheus.GaugeValue, + float64(record.GetRepos().GetOrgRepos()), + labels..., + ) + + ch <- prometheus.MustNewConstMetric( + c.ReposTotalPushes, + prometheus.GaugeValue, + float64(record.GetRepos().GetTotalPushes()), + labels..., + ) + + ch <- prometheus.MustNewConstMetric( + c.ReposTotalWikis, + prometheus.GaugeValue, + float64(record.GetRepos().GetTotalWikis()), + labels..., + ) + + ch <- prometheus.MustNewConstMetric( + c.HooksTotal, + prometheus.GaugeValue, + float64(record.GetHooks().GetTotalHooks()), + labels..., + ) + + ch <- prometheus.MustNewConstMetric( + c.HooksActive, + prometheus.GaugeValue, + float64(record.GetHooks().GetActiveHooks()), + labels..., + ) + + ch <- prometheus.MustNewConstMetric( + c.HooksInactive, + prometheus.GaugeValue, + float64(record.GetHooks().GetInactiveHooks()), + labels..., + ) + + ch <- prometheus.MustNewConstMetric( + c.PagesTotal, + prometheus.GaugeValue, + float64(record.GetPages().GetTotalPages()), + labels..., + ) + + ch <- prometheus.MustNewConstMetric( + c.OrgsTotal, + prometheus.GaugeValue, + float64(record.GetOrgs().GetTotalOrgs()), + labels..., + ) + + ch <- prometheus.MustNewConstMetric( + c.OrgsDisabled, + prometheus.GaugeValue, + float64(record.GetOrgs().GetDisabledOrgs()), + labels..., + ) + + ch <- prometheus.MustNewConstMetric( + c.OrgsTotalTeams, + prometheus.GaugeValue, + float64(record.GetOrgs().GetTotalTeams()), + labels..., + ) + + ch <- prometheus.MustNewConstMetric( + c.OrgsTotalMembers, + prometheus.GaugeValue, + float64(record.GetOrgs().GetTotalTeamMembers()), + labels..., + ) + + ch <- prometheus.MustNewConstMetric( + c.UsersTotal, + prometheus.GaugeValue, + float64(record.GetUsers().GetTotalUsers()), + labels..., + ) + + ch <- prometheus.MustNewConstMetric( + c.UsersAdmin, + prometheus.GaugeValue, + float64(record.GetUsers().GetAdminUsers()), + labels..., + ) + + ch <- prometheus.MustNewConstMetric( + c.UsersSuspended, + prometheus.GaugeValue, + float64(record.GetUsers().GetSuspendedUsers()), + labels..., + ) + + ch <- prometheus.MustNewConstMetric( + c.PullsTotal, + prometheus.GaugeValue, + float64(record.GetPulls().GetTotalPulls()), + labels..., + ) + + ch <- prometheus.MustNewConstMetric( + c.PullsMerged, + prometheus.GaugeValue, + float64(record.GetPulls().GetMergedPulls()), + labels..., + ) + + ch <- prometheus.MustNewConstMetric( + c.PullsMergeable, + prometheus.GaugeValue, + float64(record.GetPulls().GetMergablePulls()), + labels..., + ) + + ch <- prometheus.MustNewConstMetric( + c.PullsUnmergeable, + prometheus.GaugeValue, + float64(record.GetPulls().GetUnmergablePulls()), + labels..., + ) + + ch <- prometheus.MustNewConstMetric( + c.IssuesTotal, + prometheus.GaugeValue, + float64(record.GetIssues().GetTotalIssues()), + labels..., + ) + + ch <- prometheus.MustNewConstMetric( + c.IssuesOpen, + prometheus.GaugeValue, + float64(record.GetIssues().GetOpenIssues()), + labels..., + ) + + ch <- prometheus.MustNewConstMetric( + c.IssuesClosed, + prometheus.GaugeValue, + float64(record.GetIssues().GetClosedIssues()), + labels..., + ) + + ch <- prometheus.MustNewConstMetric( + c.MilestonesTotal, + prometheus.GaugeValue, + float64(record.GetMilestones().GetTotalMilestones()), + labels..., + ) + + ch <- prometheus.MustNewConstMetric( + c.MilestonesOpen, + prometheus.GaugeValue, + float64(record.GetMilestones().GetOpenMilestones()), + labels..., + ) + + ch <- prometheus.MustNewConstMetric( + c.MilestonesClosed, + prometheus.GaugeValue, + float64(record.GetMilestones().GetClosedMilestones()), + labels..., + ) + + ch <- prometheus.MustNewConstMetric( + c.GistsTotal, + prometheus.GaugeValue, + float64(record.GetGists().GetTotalGists()), + labels..., + ) + + ch <- prometheus.MustNewConstMetric( + c.GistsPrivate, + prometheus.GaugeValue, + float64(record.GetGists().GetPrivateGists()), + labels..., + ) + + ch <- prometheus.MustNewConstMetric( + c.GistsPublic, + prometheus.GaugeValue, + float64(record.GetGists().GetPublicGists()), + labels..., + ) + + ch <- prometheus.MustNewConstMetric( + c.CommentsCommit, + prometheus.GaugeValue, + float64(record.GetComments().GetTotalCommitComments()), + labels..., + ) + + ch <- prometheus.MustNewConstMetric( + c.CommentsGist, + prometheus.GaugeValue, + float64(record.GetComments().GetTotalGistComments()), + labels..., + ) + + ch <- prometheus.MustNewConstMetric( + c.CommentsIssue, + prometheus.GaugeValue, + float64(record.GetComments().GetTotalIssueComments()), + labels..., + ) + + ch <- prometheus.MustNewConstMetric( + c.CommentsPullRequest, + prometheus.GaugeValue, + float64(record.GetComments().GetTotalPullRequestComments()), + labels..., + ) +} From ee3695bd927cc21378af0f90380cf353aae38947 Mon Sep 17 00:00:00 2001 From: Thomas Boerger Date: Thu, 23 Mar 2023 09:30:57 +0100 Subject: [PATCH 2/4] feat: use getter functions --- CHANGELOG.md | 9 + changelog/unreleased/use-getters.md | 7 + pkg/exporter/org.go | 130 ++++++-------- pkg/exporter/repo.go | 262 ++++++++++++---------------- pkg/exporter/workflow.go | 6 +- 5 files changed, 188 insertions(+), 226 deletions(-) create mode 100644 changelog/unreleased/use-getters.md diff --git a/CHANGELOG.md b/CHANGELOG.md index 75d8469..ecf71e8 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -9,6 +9,7 @@ The following sections list the changes for unreleased. * Enh #174: Merge all billing related metrics * Enh #174: Update all releated dependencies * Enh #183: Integrate admin stats for GitHub enterprise + * Enh #183: Use getter functions to get values ## Details @@ -49,6 +50,14 @@ The following sections list the changes for unreleased. https://github.com/promhippie/github_exporter/issues/183 https://github.com/promhippie/github_exporter/pull/23 + * Enhancement #183: Use getter functions to get values + + To reduce the used boilerplate code and to better use the GitHub library we have updated most of + the available collectors to simply use the provided getter functions instead of checking for + nil values everywhere on our own. + + https://github.com/promhippie/github_exporter/pull/183 + # Changelog for 1.2.0 diff --git a/changelog/unreleased/use-getters.md b/changelog/unreleased/use-getters.md new file mode 100644 index 0000000..da0a35a --- /dev/null +++ b/changelog/unreleased/use-getters.md @@ -0,0 +1,7 @@ +Enhancement: Use getter functions to get values + +To reduce the used boilerplate code and to better use the GitHub library we have +updated most of the available collectors to simply use the provided getter +functions instead of checking for nil values everywhere on our own. + +https://github.com/promhippie/github_exporter/pull/183 diff --git a/pkg/exporter/org.go b/pkg/exporter/org.go index bcff3a3..b876302 100644 --- a/pkg/exporter/org.go +++ b/pkg/exporter/org.go @@ -172,98 +172,80 @@ func (c *OrgCollector) Collect(ch chan<- prometheus.Metric) { name, } - if record.PublicRepos != nil { - ch <- prometheus.MustNewConstMetric( - c.PublicRepos, - prometheus.GaugeValue, - float64(*record.PublicRepos), - labels..., - ) - } + ch <- prometheus.MustNewConstMetric( + c.PublicRepos, + prometheus.GaugeValue, + float64(record.GetPublicRepos()), + labels..., + ) - if record.PublicGists != nil { - ch <- prometheus.MustNewConstMetric( - c.PublicGists, - prometheus.GaugeValue, - float64(*record.PublicGists), - labels..., - ) - } + ch <- prometheus.MustNewConstMetric( + c.PublicGists, + prometheus.GaugeValue, + float64(record.GetPublicGists()), + labels..., + ) - if record.PrivateGists != nil { - ch <- prometheus.MustNewConstMetric( - c.PrivateGists, - prometheus.GaugeValue, - float64(*record.PrivateGists), - labels..., - ) - } + ch <- prometheus.MustNewConstMetric( + c.PrivateGists, + prometheus.GaugeValue, + float64(record.GetPrivateGists()), + labels..., + ) - if record.Followers != nil { - ch <- prometheus.MustNewConstMetric( - c.Followers, - prometheus.GaugeValue, - float64(*record.Followers), - labels..., - ) - } + ch <- prometheus.MustNewConstMetric( + c.Followers, + prometheus.GaugeValue, + float64(record.GetFollowers()), + labels..., + ) - if record.Following != nil { - ch <- prometheus.MustNewConstMetric( - c.Following, - prometheus.GaugeValue, - float64(*record.Following), - labels..., - ) - } + ch <- prometheus.MustNewConstMetric( + c.Following, + prometheus.GaugeValue, + float64(record.GetFollowing()), + labels..., + ) - if record.Collaborators != nil { - ch <- prometheus.MustNewConstMetric( - c.Collaborators, - prometheus.GaugeValue, - float64(*record.Collaborators), - labels..., - ) - } + ch <- prometheus.MustNewConstMetric( + c.Collaborators, + prometheus.GaugeValue, + float64(record.GetCollaborators()), + labels..., + ) - if record.DiskUsage != nil { - ch <- prometheus.MustNewConstMetric( - c.DiskUsage, - prometheus.GaugeValue, - float64(*record.DiskUsage), - labels..., - ) - } + ch <- prometheus.MustNewConstMetric( + c.DiskUsage, + prometheus.GaugeValue, + float64(record.GetDiskUsage()), + labels..., + ) - if record.TotalPrivateRepos != nil { - ch <- prometheus.MustNewConstMetric( - c.PrivateReposTotal, - prometheus.GaugeValue, - float64(*record.TotalPrivateRepos), - labels..., - ) - } + ch <- prometheus.MustNewConstMetric( + c.PrivateReposTotal, + prometheus.GaugeValue, + float64(record.GetTotalPrivateRepos()), + labels..., + ) - if record.OwnedPrivateRepos != nil { - ch <- prometheus.MustNewConstMetric( - c.PrivateReposOwned, - prometheus.GaugeValue, - float64(*record.OwnedPrivateRepos), - labels..., - ) - } + ch <- prometheus.MustNewConstMetric( + c.PrivateReposOwned, + prometheus.GaugeValue, + float64(record.GetOwnedPrivateRepos()), + labels..., + ) ch <- prometheus.MustNewConstMetric( c.Created, prometheus.GaugeValue, - float64(record.CreatedAt.Unix()), + float64(record.GetCreatedAt().Unix()), labels..., ) ch <- prometheus.MustNewConstMetric( c.Updated, prometheus.GaugeValue, - float64(record.UpdatedAt.Unix()), + float64(record.GetUpdatedAt().Unix()), labels..., ) } diff --git a/pkg/exporter/repo.go b/pkg/exporter/repo.go index 81ec043..6cced6f 100644 --- a/pkg/exporter/repo.go +++ b/pkg/exporter/repo.go @@ -275,195 +275,159 @@ func (c *RepoCollector) Collect(ch chan<- prometheus.Metric) { } for _, record := range records { - if !glob.Glob(name, *record.FullName) { + if !glob.Glob(name, record.GetFullName()) { continue } labels := []string{ owner, - *record.Name, + record.GetName(), } - if record.Fork != nil { - ch <- prometheus.MustNewConstMetric( - c.Forked, - prometheus.GaugeValue, - boolToFloat64(*record.Fork), - labels..., - ) - } + ch <- prometheus.MustNewConstMetric( + c.Forked, + prometheus.GaugeValue, + boolToFloat64(record.GetFork()), + labels..., + ) - if record.ForksCount != nil { - ch <- prometheus.MustNewConstMetric( - c.Forks, - prometheus.GaugeValue, - float64(*record.ForksCount), - labels..., - ) - } + ch <- prometheus.MustNewConstMetric( + c.Forks, + prometheus.GaugeValue, + float64(record.GetForksCount()), + labels..., + ) - if record.NetworkCount != nil { - ch <- prometheus.MustNewConstMetric( - c.Network, - prometheus.GaugeValue, - float64(*record.NetworkCount), - labels..., - ) - } + ch <- prometheus.MustNewConstMetric( + c.Network, + prometheus.GaugeValue, + float64(record.GetNetworkCount()), + labels..., + ) - if record.OpenIssuesCount != nil { - ch <- prometheus.MustNewConstMetric( - c.Issues, - prometheus.GaugeValue, - float64(*record.OpenIssuesCount), - labels..., - ) - } + ch <- prometheus.MustNewConstMetric( + c.Issues, + prometheus.GaugeValue, + float64(record.GetOpenIssuesCount()), + labels..., + ) - if record.StargazersCount != nil { - ch <- prometheus.MustNewConstMetric( - c.Stargazers, - prometheus.GaugeValue, - float64(*record.StargazersCount), - labels..., - ) - } + ch <- prometheus.MustNewConstMetric( + c.Stargazers, + prometheus.GaugeValue, + float64(record.GetStargazersCount()), + labels..., + ) - if record.SubscribersCount != nil { - ch <- prometheus.MustNewConstMetric( - c.Subscribers, - prometheus.GaugeValue, - float64(*record.SubscribersCount), - labels..., - ) - } + ch <- prometheus.MustNewConstMetric( + c.Subscribers, + prometheus.GaugeValue, + float64(record.GetSubscribersCount()), + labels..., + ) - if record.WatchersCount != nil { - ch <- prometheus.MustNewConstMetric( - c.Watchers, - prometheus.GaugeValue, - float64(*record.WatchersCount), - labels..., - ) - } + ch <- prometheus.MustNewConstMetric( + c.Watchers, + prometheus.GaugeValue, + float64(record.GetWatchersCount()), + labels..., + ) - if record.Size != nil { - ch <- prometheus.MustNewConstMetric( - c.Size, - prometheus.GaugeValue, - float64(*record.Size), - labels..., - ) - } + ch <- prometheus.MustNewConstMetric( + c.Size, + prometheus.GaugeValue, + float64(record.GetSize()), + labels..., + ) - if record.AllowRebaseMerge != nil { - ch <- prometheus.MustNewConstMetric( - c.AllowRebaseMerge, - prometheus.GaugeValue, - boolToFloat64(*record.AllowRebaseMerge), - labels..., - ) - } + ch <- prometheus.MustNewConstMetric( + c.AllowRebaseMerge, + prometheus.GaugeValue, + boolToFloat64(record.GetAllowRebaseMerge()), + labels..., + ) - if record.AllowSquashMerge != nil { - ch <- prometheus.MustNewConstMetric( - c.AllowSquashMerge, - prometheus.GaugeValue, - boolToFloat64(*record.AllowSquashMerge), - labels..., - ) - } + ch <- prometheus.MustNewConstMetric( + c.AllowSquashMerge, + prometheus.GaugeValue, + boolToFloat64(record.GetAllowSquashMerge()), + labels..., + ) - if record.AllowMergeCommit != nil { - ch <- prometheus.MustNewConstMetric( - c.AllowMergeCommit, - prometheus.GaugeValue, - boolToFloat64(*record.AllowMergeCommit), - labels..., - ) - } + ch <- prometheus.MustNewConstMetric( + c.AllowMergeCommit, + prometheus.GaugeValue, + boolToFloat64(record.GetAllowMergeCommit()), + labels..., + ) - if record.Archived != nil { - ch <- prometheus.MustNewConstMetric( - c.Archived, - prometheus.GaugeValue, - boolToFloat64(*record.Archived), - labels..., - ) - } + ch <- prometheus.MustNewConstMetric( + c.Archived, + prometheus.GaugeValue, + boolToFloat64(record.GetArchived()), + labels..., + ) - if record.Private != nil { - ch <- prometheus.MustNewConstMetric( - c.Private, - prometheus.GaugeValue, - boolToFloat64(*record.Private), - labels..., - ) - } + ch <- prometheus.MustNewConstMetric( + c.Private, + prometheus.GaugeValue, + boolToFloat64(record.GetPrivate()), + labels..., + ) - if record.HasIssues != nil { - ch <- prometheus.MustNewConstMetric( - c.HasIssues, - prometheus.GaugeValue, - boolToFloat64(*record.HasIssues), - labels..., - ) - } + ch <- prometheus.MustNewConstMetric( + c.HasIssues, + prometheus.GaugeValue, + boolToFloat64(record.GetHasIssues()), + labels..., + ) - if record.HasWiki != nil { - ch <- prometheus.MustNewConstMetric( - c.HasWiki, - prometheus.GaugeValue, - boolToFloat64(*record.HasWiki), - labels..., - ) - } + ch <- prometheus.MustNewConstMetric( + c.HasWiki, + prometheus.GaugeValue, + boolToFloat64(record.GetHasWiki()), + labels..., + ) - if record.HasPages != nil { - ch <- prometheus.MustNewConstMetric( - c.HasPages, - prometheus.GaugeValue, - boolToFloat64(*record.HasPages), - labels..., - ) - } + ch <- prometheus.MustNewConstMetric( + c.HasPages, + prometheus.GaugeValue, + boolToFloat64(record.GetHasPages()), + labels..., + ) - if record.HasProjects != nil { - ch <- prometheus.MustNewConstMetric( - c.HasProjects, - prometheus.GaugeValue, - boolToFloat64(*record.HasProjects), - labels..., - ) - } + ch <- prometheus.MustNewConstMetric( + c.HasProjects, + prometheus.GaugeValue, + boolToFloat64(record.GetHasProjects()), + labels..., + ) - if record.HasDownloads != nil { - ch <- prometheus.MustNewConstMetric( - c.HasDownloads, - prometheus.GaugeValue, - boolToFloat64(*record.HasDownloads), - labels..., - ) - } + ch <- prometheus.MustNewConstMetric( + c.HasDownloads, + prometheus.GaugeValue, + boolToFloat64(record.GetHasDownloads()), + labels..., + ) ch <- prometheus.MustNewConstMetric( c.Pushed, prometheus.GaugeValue, - float64(record.PushedAt.Unix()), + float64(record.GetPushedAt().Unix()), labels..., ) ch <- prometheus.MustNewConstMetric( c.Created, prometheus.GaugeValue, - float64(record.CreatedAt.Unix()), + float64(record.GetCreatedAt().Unix()), labels..., ) ch <- prometheus.MustNewConstMetric( c.Updated, prometheus.GaugeValue, - float64(record.UpdatedAt.Unix()), + float64(record.GetUpdatedAt().Unix()), labels..., ) } diff --git a/pkg/exporter/workflow.go b/pkg/exporter/workflow.go index 7d69842..0fc4888 100644 --- a/pkg/exporter/workflow.go +++ b/pkg/exporter/workflow.go @@ -78,8 +78,8 @@ func (c *WorkflowCollector) Collect(ch chan<- prometheus.Metric) { for _, record := range records { labels := []string{ - *record.Repository.Owner.Login, - *record.Repository.Name, + record.GetRepository().GetOwner().GetLogin(), + record.GetRepository().GetName(), record.GetEvent(), record.GetName(), record.GetStatus(), @@ -98,7 +98,7 @@ func (c *WorkflowCollector) Collect(ch chan<- prometheus.Metric) { ch <- prometheus.MustNewConstMetric( c.Duration, prometheus.GaugeValue, - float64((record.UpdatedAt.Time.Unix()-record.CreatedAt.Time.Unix())*1000), + float64((record.GetUpdatedAt().Time.Unix()-record.GetCreatedAt().Time.Unix())*1000), labels..., ) } From 63eeef195ceee1d9ce4be769be8064a42876dc8a Mon Sep 17 00:00:00 2001 From: Thomas Boerger Date: Thu, 23 Mar 2023 09:37:30 +0100 Subject: [PATCH 3/4] fix: set right name/owner for runner metrics --- CHANGELOG.md | 9 ++++++ changelog/unreleased/runner-labels.md | 7 +++++ pkg/exporter/runner.go | 44 +++++++++++++++++++-------- 3 files changed, 48 insertions(+), 12 deletions(-) create mode 100644 changelog/unreleased/runner-labels.md diff --git a/CHANGELOG.md b/CHANGELOG.md index ecf71e8..8062c6f 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,6 +4,7 @@ The following sections list the changes for unreleased. ## Summary + * Fix #183: Set right name/owner labels for runner metrics * Enh #123: Add metrics for GitHub runners * Enh #123: Add metrics for GitHub workflows * Enh #174: Merge all billing related metrics @@ -13,6 +14,14 @@ The following sections list the changes for unreleased. ## Details + * Bugfix #183: Set right name/owner labels for runner metrics + + We introduced metrics for GitHub self-hosted runners but we missed some important labels as + remaining todos. With this change this gets corrected to properly show the + repo/org/enterprise where the runner have been attached to. + + https://github.com/promhippie/github_exporter/pull/183 + * Enhancement #123: Add metrics for GitHub runners We've added new metrics for selfhosted runners used per repo, org or enterprise to give the diff --git a/changelog/unreleased/runner-labels.md b/changelog/unreleased/runner-labels.md new file mode 100644 index 0000000..03213ca --- /dev/null +++ b/changelog/unreleased/runner-labels.md @@ -0,0 +1,7 @@ +Bugfix: Set right name/owner labels for runner metrics + +We introduced metrics for GitHub self-hosted runners but we missed some +important labels as remaining todos. With this change this gets corrected to +properly show the repo/org/enterprise where the runner have been attached to. + +https://github.com/promhippie/github_exporter/pull/183 diff --git a/pkg/exporter/runner.go b/pkg/exporter/runner.go index bdceaa3..e26cbac 100644 --- a/pkg/exporter/runner.go +++ b/pkg/exporter/runner.go @@ -118,7 +118,7 @@ func (c *RunnerCollector) Collect(ch chan<- prometheus.Metric) { ) labels := []string{ - "TODO: repo", + record.Owner, strconv.FormatInt(record.GetID(), 10), record.GetName(), record.GetOS(), @@ -156,7 +156,7 @@ func (c *RunnerCollector) Collect(ch chan<- prometheus.Metric) { ) labels := []string{ - "TODO: enterprise", + record.Owner, strconv.FormatInt(record.GetID(), 10), record.GetName(), record.GetOS(), @@ -194,7 +194,7 @@ func (c *RunnerCollector) Collect(ch chan<- prometheus.Metric) { ) labels := []string{ - "TODO: org", + record.Owner, strconv.FormatInt(record.GetID(), 10), record.GetName(), record.GetOS(), @@ -222,8 +222,8 @@ func (c *RunnerCollector) Collect(ch chan<- prometheus.Metric) { } } -func (c *RunnerCollector) repoRunners() []*github.Runner { - result := make([]*github.Runner, 0) +func (c *RunnerCollector) repoRunners() []runner { + result := make([]runner, 0) for _, name := range c.config.Repos.Value() { n := strings.Split(name, "/") @@ -274,7 +274,12 @@ func (c *RunnerCollector) repoRunners() []*github.Runner { continue } - result = append(result, records...) + for _, row := range records { + result = append(result, runner{ + Owner: name, + Runner: row, + }) + } } } @@ -317,8 +322,8 @@ func (c *RunnerCollector) pagedRepoRunners(ctx context.Context, owner, name stri return runners, nil } -func (c *RunnerCollector) enterpriseRunners() []*github.Runner { - result := make([]*github.Runner, 0) +func (c *RunnerCollector) enterpriseRunners() []runner { + result := make([]runner, 0) for _, name := range c.config.Enterprises.Value() { ctx, cancel := context.WithTimeout(context.Background(), c.config.Timeout) @@ -337,7 +342,12 @@ func (c *RunnerCollector) enterpriseRunners() []*github.Runner { continue } - result = append(result, records...) + for _, row := range records { + result = append(result, runner{ + Owner: name, + Runner: row, + }) + } } return result @@ -378,8 +388,8 @@ func (c *RunnerCollector) pagedEnterpriseRunners(ctx context.Context, name strin return runners, nil } -func (c *RunnerCollector) orgRunners() []*github.Runner { - result := make([]*github.Runner, 0) +func (c *RunnerCollector) orgRunners() []runner { + result := make([]runner, 0) for _, name := range c.config.Orgs.Value() { ctx, cancel := context.WithTimeout(context.Background(), c.config.Timeout) @@ -398,7 +408,12 @@ func (c *RunnerCollector) orgRunners() []*github.Runner { continue } - result = append(result, records...) + for _, row := range records { + result = append(result, runner{ + Owner: name, + Runner: row, + }) + } } return result @@ -438,3 +453,8 @@ func (c *RunnerCollector) pagedOrgRunners(ctx context.Context, name string) ([]* return runners, nil } + +type runner struct { + Owner string + *github.Runner +} From 415b559520497d21a5f0da01db2cb7fe661e7852 Mon Sep 17 00:00:00 2001 From: Thomas Boerger Date: Thu, 23 Mar 2023 09:40:14 +0100 Subject: [PATCH 4/4] docs: use right references for changelog --- CHANGELOG.md | 12 ++++++------ changelog/unreleased/runner-labels.md | 2 +- .../{runner-emtrics.md => runner-metrics.md} | 0 changelog/unreleased/use-getters.md | 2 +- 4 files changed, 8 insertions(+), 8 deletions(-) rename changelog/unreleased/{runner-emtrics.md => runner-metrics.md} (100%) diff --git a/CHANGELOG.md b/CHANGELOG.md index 8062c6f..397bfbf 100644 --- a/CHANGELOG.md +++ b/CHANGELOG.md @@ -4,23 +4,23 @@ The following sections list the changes for unreleased. ## Summary - * Fix #183: Set right name/owner labels for runner metrics + * Fix #184: Set right name/owner labels for runner metrics * Enh #123: Add metrics for GitHub runners * Enh #123: Add metrics for GitHub workflows * Enh #174: Merge all billing related metrics * Enh #174: Update all releated dependencies * Enh #183: Integrate admin stats for GitHub enterprise - * Enh #183: Use getter functions to get values + * Enh #184: Use getter functions to get values ## Details - * Bugfix #183: Set right name/owner labels for runner metrics + * Bugfix #184: Set right name/owner labels for runner metrics We introduced metrics for GitHub self-hosted runners but we missed some important labels as remaining todos. With this change this gets corrected to properly show the repo/org/enterprise where the runner have been attached to. - https://github.com/promhippie/github_exporter/pull/183 + https://github.com/promhippie/github_exporter/pull/184 * Enhancement #123: Add metrics for GitHub runners @@ -59,13 +59,13 @@ The following sections list the changes for unreleased. https://github.com/promhippie/github_exporter/issues/183 https://github.com/promhippie/github_exporter/pull/23 - * Enhancement #183: Use getter functions to get values + * Enhancement #184: Use getter functions to get values To reduce the used boilerplate code and to better use the GitHub library we have updated most of the available collectors to simply use the provided getter functions instead of checking for nil values everywhere on our own. - https://github.com/promhippie/github_exporter/pull/183 + https://github.com/promhippie/github_exporter/pull/184 # Changelog for 1.2.0 diff --git a/changelog/unreleased/runner-labels.md b/changelog/unreleased/runner-labels.md index 03213ca..c8707db 100644 --- a/changelog/unreleased/runner-labels.md +++ b/changelog/unreleased/runner-labels.md @@ -4,4 +4,4 @@ We introduced metrics for GitHub self-hosted runners but we missed some important labels as remaining todos. With this change this gets corrected to properly show the repo/org/enterprise where the runner have been attached to. -https://github.com/promhippie/github_exporter/pull/183 +https://github.com/promhippie/github_exporter/pull/184 diff --git a/changelog/unreleased/runner-emtrics.md b/changelog/unreleased/runner-metrics.md similarity index 100% rename from changelog/unreleased/runner-emtrics.md rename to changelog/unreleased/runner-metrics.md diff --git a/changelog/unreleased/use-getters.md b/changelog/unreleased/use-getters.md index da0a35a..7ea54b9 100644 --- a/changelog/unreleased/use-getters.md +++ b/changelog/unreleased/use-getters.md @@ -4,4 +4,4 @@ To reduce the used boilerplate code and to better use the GitHub library we have updated most of the available collectors to simply use the provided getter functions instead of checking for nil values everywhere on our own. -https://github.com/promhippie/github_exporter/pull/183 +https://github.com/promhippie/github_exporter/pull/184