From 2ea5b6fe3371d3f956b77130fcebcc5a88b915c3 Mon Sep 17 00:00:00 2001 From: Marcus Efraimsson Date: Fri, 25 May 2018 14:33:37 +0200 Subject: [PATCH] add additional usage stats metrics nr of folders nr of folder permissions nr of dashboard permissions nr of snapshots nr of teams nr of provisioned dashboards --- pkg/metrics/metrics.go | 6 +++++ pkg/metrics/metrics_test.go | 28 ++++++++++++++------ pkg/models/stats.go | 30 ++++++++++++++++------ pkg/services/sqlstore/sqlstore.go | 6 ++--- pkg/services/sqlstore/stats.go | 40 ++++++++++++++++++++++++++--- pkg/services/sqlstore/stats_test.go | 27 +++++++++++++++++++ 6 files changed, 114 insertions(+), 23 deletions(-) create mode 100644 pkg/services/sqlstore/stats_test.go diff --git a/pkg/metrics/metrics.go b/pkg/metrics/metrics.go index fbab8af51dd..03836abe2ad 100644 --- a/pkg/metrics/metrics.go +++ b/pkg/metrics/metrics.go @@ -368,6 +368,12 @@ func sendUsageStats() { metrics["stats.active_users.count"] = statsQuery.Result.ActiveUsers metrics["stats.datasources.count"] = statsQuery.Result.Datasources metrics["stats.stars.count"] = statsQuery.Result.Stars + metrics["stats.folders.count"] = statsQuery.Result.Folders + metrics["stats.dashboard_permissions.count"] = statsQuery.Result.DashboardPermissions + metrics["stats.folder_permissions.count"] = statsQuery.Result.FolderPermissions + metrics["stats.provisioned_dashboards.count"] = statsQuery.Result.ProvisionedDashboards + metrics["stats.snapshots.count"] = statsQuery.Result.Snapshots + metrics["stats.teams.count"] = statsQuery.Result.Teams dsStats := models.GetDataSourceStatsQuery{} if err := bus.Dispatch(&dsStats); err != nil { diff --git a/pkg/metrics/metrics_test.go b/pkg/metrics/metrics_test.go index a27e44d7105..77a0aef3f24 100644 --- a/pkg/metrics/metrics_test.go +++ b/pkg/metrics/metrics_test.go @@ -24,14 +24,20 @@ func TestMetrics(t *testing.T) { var getSystemStatsQuery *models.GetSystemStatsQuery bus.AddHandler("test", func(query *models.GetSystemStatsQuery) error { query.Result = &models.SystemStats{ - Dashboards: 1, - Datasources: 2, - Users: 3, - ActiveUsers: 4, - Orgs: 5, - Playlists: 6, - Alerts: 7, - Stars: 8, + Dashboards: 1, + Datasources: 2, + Users: 3, + ActiveUsers: 4, + Orgs: 5, + Playlists: 6, + Alerts: 7, + Stars: 8, + Folders: 9, + DashboardPermissions: 10, + FolderPermissions: 11, + ProvisionedDashboards: 12, + Snapshots: 13, + Teams: 14, } getSystemStatsQuery = query return nil @@ -126,6 +132,12 @@ func TestMetrics(t *testing.T) { So(metrics.Get("stats.active_users.count").MustInt(), ShouldEqual, getSystemStatsQuery.Result.ActiveUsers) So(metrics.Get("stats.datasources.count").MustInt(), ShouldEqual, getSystemStatsQuery.Result.Datasources) So(metrics.Get("stats.stars.count").MustInt(), ShouldEqual, getSystemStatsQuery.Result.Stars) + So(metrics.Get("stats.folders.count").MustInt(), ShouldEqual, getSystemStatsQuery.Result.Folders) + So(metrics.Get("stats.dashboard_permissions.count").MustInt(), ShouldEqual, getSystemStatsQuery.Result.DashboardPermissions) + So(metrics.Get("stats.folder_permissions.count").MustInt(), ShouldEqual, getSystemStatsQuery.Result.FolderPermissions) + So(metrics.Get("stats.provisioned_dashboards.count").MustInt(), ShouldEqual, getSystemStatsQuery.Result.ProvisionedDashboards) + So(metrics.Get("stats.snapshots.count").MustInt(), ShouldEqual, getSystemStatsQuery.Result.Snapshots) + So(metrics.Get("stats.teams.count").MustInt(), ShouldEqual, getSystemStatsQuery.Result.Teams) So(metrics.Get("stats.ds."+models.DS_ES+".count").MustInt(), ShouldEqual, 9) So(metrics.Get("stats.ds."+models.DS_PROMETHEUS+".count").MustInt(), ShouldEqual, 10) diff --git a/pkg/models/stats.go b/pkg/models/stats.go index e132d88c030..0e497621e14 100644 --- a/pkg/models/stats.go +++ b/pkg/models/stats.go @@ -1,14 +1,20 @@ package models type SystemStats struct { - Dashboards int64 - Datasources int64 - Users int64 - ActiveUsers int64 - Orgs int64 - Playlists int64 - Alerts int64 - Stars int64 + Dashboards int64 + Datasources int64 + Users int64 + ActiveUsers int64 + Orgs int64 + Playlists int64 + Alerts int64 + Stars int64 + Snapshots int64 + Teams int64 + DashboardPermissions int64 + FolderPermissions int64 + Folders int64 + ProvisionedDashboards int64 } type DataSourceStats struct { @@ -40,3 +46,11 @@ type AdminStats struct { type GetAdminStatsQuery struct { Result *AdminStats } + +type SystemUserCountStats struct { + Count int64 +} + +type GetSystemUserCountStatsQuery struct { + Result *SystemUserCountStats +} diff --git a/pkg/services/sqlstore/sqlstore.go b/pkg/services/sqlstore/sqlstore.go index 39aa2cb7ead..6af56f2f169 100644 --- a/pkg/services/sqlstore/sqlstore.go +++ b/pkg/services/sqlstore/sqlstore.go @@ -86,13 +86,13 @@ func (ss *SqlStore) Init() error { } func (ss *SqlStore) ensureAdminUser() error { - statsQuery := m.GetSystemStatsQuery{} + systemUserCountQuery := m.GetSystemUserCountStatsQuery{} - if err := bus.Dispatch(&statsQuery); err != nil { + if err := bus.Dispatch(&systemUserCountQuery); err != nil { fmt.Errorf("Could not determine if admin user exists: %v", err) } - if statsQuery.Result.Users > 0 { + if systemUserCountQuery.Result.Count > 0 { return nil } diff --git a/pkg/services/sqlstore/stats.go b/pkg/services/sqlstore/stats.go index 173a1e56634..e0bc0e2091e 100644 --- a/pkg/services/sqlstore/stats.go +++ b/pkg/services/sqlstore/stats.go @@ -11,6 +11,7 @@ func init() { bus.AddHandler("sql", GetSystemStats) bus.AddHandler("sql", GetDataSourceStats) bus.AddHandler("sql", GetAdminStats) + bus.AddHandler("sql", GetSystemUserCountStats) } var activeUserTimeLimit = time.Hour * 24 * 30 @@ -51,14 +52,32 @@ func GetSystemStats(query *m.GetSystemStatsQuery) error { SELECT COUNT(*) FROM ` + dialect.Quote("alert") + ` ) AS alerts, - ( - SELECT COUNT(*) FROM ` + dialect.Quote("user") + ` where last_seen_at > ? - ) as active_users + ( + SELECT COUNT(*) FROM ` + dialect.Quote("user") + ` where last_seen_at > ? + ) as active_users, + ( + SELECT COUNT(id) FROM ` + dialect.Quote("dashboard") + ` where is_folder = ? + ) as folders, + ( + SELECT COUNT(acl.id) FROM ` + dialect.Quote("dashboard_acl") + ` as acl inner join ` + dialect.Quote("dashboard") + ` as d on d.id = acl.dashboard_id where d.is_folder = ? + ) as dashboard_permissions, + ( + SELECT COUNT(acl.id) FROM ` + dialect.Quote("dashboard_acl") + ` as acl inner join ` + dialect.Quote("dashboard") + ` as d on d.id = acl.dashboard_id where d.is_folder = ? + ) as folder_permissions, + ( + SELECT COUNT(id) FROM ` + dialect.Quote("dashboard_provisioning") + ` + ) as provisioned_dashboards, + ( + SELECT COUNT(id) FROM ` + dialect.Quote("dashboard_snapshot") + ` + ) as snapshots, + ( + SELECT COUNT(id) FROM ` + dialect.Quote("team") + ` + ) as teams ` activeUserDeadlineDate := time.Now().Add(-activeUserTimeLimit) var stats m.SystemStats - _, err := x.SQL(rawSql, activeUserDeadlineDate).Get(&stats) + _, err := x.SQL(rawSql, activeUserDeadlineDate, dialect.BooleanStr(true), dialect.BooleanStr(false), dialect.BooleanStr(true)).Get(&stats) if err != nil { return err } @@ -122,3 +141,16 @@ func GetAdminStats(query *m.GetAdminStatsQuery) error { query.Result = &stats return err } + +func GetSystemUserCountStats(query *m.GetSystemUserCountStatsQuery) error { + var rawSql = `SELECT COUNT(id) AS Count FROM ` + dialect.Quote("user") + var stats m.SystemUserCountStats + _, err := x.SQL(rawSql).Get(&stats) + if err != nil { + return err + } + + query.Result = &stats + + return err +} diff --git a/pkg/services/sqlstore/stats_test.go b/pkg/services/sqlstore/stats_test.go new file mode 100644 index 00000000000..c98556a68d3 --- /dev/null +++ b/pkg/services/sqlstore/stats_test.go @@ -0,0 +1,27 @@ +package sqlstore + +import ( + "testing" + + m "github.com/grafana/grafana/pkg/models" + . "github.com/smartystreets/goconvey/convey" +) + +func TestStatsDataAccess(t *testing.T) { + + Convey("Testing Stats Data Access", t, func() { + InitTestDB(t) + + Convey("Get system stats should not results in error", func() { + query := m.GetSystemStatsQuery{} + err := GetSystemStats(&query) + So(err, ShouldBeNil) + }) + + Convey("Get system user count stats should not results in error", func() { + query := m.GetSystemUserCountStatsQuery{} + err := GetSystemUserCountStats(&query) + So(err, ShouldBeNil) + }) + }) +}