From eb8af01a8a900494fc4acbf849431cc051372b93 Mon Sep 17 00:00:00 2001 From: Carl Bergquist Date: Wed, 24 Apr 2019 13:18:16 +0200 Subject: [PATCH] admin: add more stats about roles (#16667) closes #14967 --- pkg/models/stats.go | 27 +++--- pkg/services/sqlstore/stars_test.go | 1 - pkg/services/sqlstore/stats.go | 114 +++++++++++++++--------- pkg/services/sqlstore/stats_test.go | 19 ++-- public/app/features/admin/state/apis.ts | 9 +- scripts/circle-test-postgres.sh | 7 +- 6 files changed, 114 insertions(+), 63 deletions(-) diff --git a/pkg/models/stats.go b/pkg/models/stats.go index 0edd204ec03..994170786b0 100644 --- a/pkg/models/stats.go +++ b/pkg/models/stats.go @@ -51,16 +51,23 @@ type GetAlertNotifierUsageStatsQuery struct { } type AdminStats struct { - Users int `json:"users"` - Orgs int `json:"orgs"` - Dashboards int `json:"dashboards"` - Snapshots int `json:"snapshots"` - Tags int `json:"tags"` - Datasources int `json:"datasources"` - Playlists int `json:"playlists"` - Stars int `json:"stars"` - Alerts int `json:"alerts"` - ActiveUsers int `json:"activeUsers"` + Orgs int `json:"orgs"` + Dashboards int `json:"dashboards"` + Snapshots int `json:"snapshots"` + Tags int `json:"tags"` + Datasources int `json:"datasources"` + Playlists int `json:"playlists"` + Stars int `json:"stars"` + Alerts int `json:"alerts"` + Users int `json:"users"` + Admins int `json:"admins"` + Editors int `json:"editors"` + Viewers int `json:"viewers"` + ActiveUsers int `json:"activeUsers"` + ActiveAdmins int `json:"activeAdmins"` + ActiveEditors int `json:"activeEditors"` + ActiveViewers int `json:"activeViewers"` + ActiveSessions int `json:"activeSessions"` } type GetAdminStatsQuery struct { diff --git a/pkg/services/sqlstore/stars_test.go b/pkg/services/sqlstore/stars_test.go index 4e48dfdbcb3..43a612c1a5b 100644 --- a/pkg/services/sqlstore/stars_test.go +++ b/pkg/services/sqlstore/stars_test.go @@ -36,7 +36,6 @@ func TestUserStarsDataAccess(t *testing.T) { So(query.Result, ShouldBeFalse) }) - }) }) } diff --git a/pkg/services/sqlstore/stats.go b/pkg/services/sqlstore/stats.go index 2b7c35a4b4a..a1191cb21c8 100644 --- a/pkg/services/sqlstore/stats.go +++ b/pkg/services/sqlstore/stats.go @@ -89,52 +89,84 @@ func GetSystemStats(query *m.GetSystemStatsQuery) error { } func GetAdminStats(query *m.GetAdminStatsQuery) error { - var rawSql = `SELECT - ( - SELECT COUNT(*) - FROM ` + dialect.Quote("user") + ` - ) AS users, - ( - SELECT COUNT(*) - FROM ` + dialect.Quote("org") + ` - ) AS orgs, - ( - SELECT COUNT(*) - FROM ` + dialect.Quote("dashboard") + ` - ) AS dashboards, - ( - SELECT COUNT(*) - FROM ` + dialect.Quote("dashboard_snapshot") + ` - ) AS snapshots, - ( - SELECT COUNT( DISTINCT ( ` + dialect.Quote("term") + ` )) - FROM ` + dialect.Quote("dashboard_tag") + ` - ) AS tags, - ( - SELECT COUNT(*) - FROM ` + dialect.Quote("data_source") + ` - ) AS datasources, - ( - SELECT COUNT(*) - FROM ` + dialect.Quote("playlist") + ` - ) AS playlists, - ( - SELECT COUNT(*) FROM ` + dialect.Quote("star") + ` - ) AS stars, - ( - SELECT COUNT(*) - FROM ` + dialect.Quote("alert") + ` - ) AS alerts, + activeEndDate := time.Now().Add(-activeUserTimeLimit) + roleCounter := func(role, alias string) string { + sql := + ` ( SELECT COUNT(*) - from ` + dialect.Quote("user") + ` where last_seen_at > ? - ) as active_users + FROM ` + dialect.Quote("user") + ` as u + WHERE + (SELECT COUNT(*) + FROM org_user + WHERE org_user.user_id=u.id + AND org_user.role='` + role + `')>0 + ) as ` + alias + `, + ( + SELECT COUNT(*) + FROM ` + dialect.Quote("user") + ` as u + WHERE + (SELECT COUNT(*) + FROM org_user + WHERE org_user.user_id=u.id + AND org_user.role='` + role + `')>0 + AND u.last_seen_at>? + ) as active_` + alias + + return sql + } + + var rawSql = `SELECT + ( + SELECT COUNT(*) + FROM ` + dialect.Quote("org") + ` + ) AS orgs, + ( + SELECT COUNT(*) + FROM ` + dialect.Quote("dashboard") + ` + ) AS dashboards, + ( + SELECT COUNT(*) + FROM ` + dialect.Quote("dashboard_snapshot") + ` + ) AS snapshots, + ( + SELECT COUNT( DISTINCT ( ` + dialect.Quote("term") + ` )) + FROM ` + dialect.Quote("dashboard_tag") + ` + ) AS tags, + ( + SELECT COUNT(*) + FROM ` + dialect.Quote("data_source") + ` + ) AS datasources, + ( + SELECT COUNT(*) + FROM ` + dialect.Quote("playlist") + ` + ) AS playlists, + ( + SELECT COUNT(*) FROM ` + dialect.Quote("star") + ` + ) AS stars, + ( + SELECT COUNT(*) + FROM ` + dialect.Quote("alert") + ` + ) AS alerts, + ( + SELECT COUNT(*) + FROM ` + dialect.Quote("user") + ` + ) AS users, + ( + SELECT COUNT(*) + FROM ` + dialect.Quote("user") + ` where last_seen_at > ? + ) as active_users, + ` + roleCounter("Admin", "admins") + `, + ` + roleCounter("Editor", "editors") + `, + ` + roleCounter("Viewer", "viewers") + `, + ( + SELECT COUNT(*) + FROM ` + dialect.Quote("user_auth_token") + ` where rotated_at > ? + ) as active_sessions ` - activeUserDeadlineDate := time.Now().Add(-activeUserTimeLimit) - var stats m.AdminStats - _, err := x.SQL(rawSql, activeUserDeadlineDate).Get(&stats) + _, err := x.SQL(rawSql, activeEndDate, activeEndDate, activeEndDate, activeEndDate, activeEndDate.Unix()).Get(&stats) if err != nil { return err } diff --git a/pkg/services/sqlstore/stats_test.go b/pkg/services/sqlstore/stats_test.go index 6949a0dbda2..38396aef5b0 100644 --- a/pkg/services/sqlstore/stats_test.go +++ b/pkg/services/sqlstore/stats_test.go @@ -4,43 +4,48 @@ import ( "context" "testing" - m "github.com/grafana/grafana/pkg/models" + "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{} + query := models.GetSystemStatsQuery{} err := GetSystemStats(&query) So(err, ShouldBeNil) }) Convey("Get system user count stats should not results in error", func() { - query := m.GetSystemUserCountStatsQuery{} + query := models.GetSystemUserCountStatsQuery{} err := GetSystemUserCountStats(context.Background(), &query) So(err, ShouldBeNil) }) Convey("Get datasource stats should not results in error", func() { - query := m.GetDataSourceStatsQuery{} + query := models.GetDataSourceStatsQuery{} err := GetDataSourceStats(&query) So(err, ShouldBeNil) }) Convey("Get datasource access stats should not results in error", func() { - query := m.GetDataSourceAccessStatsQuery{} + query := models.GetDataSourceAccessStatsQuery{} err := GetDataSourceAccessStats(&query) So(err, ShouldBeNil) }) Convey("Get alert notifier stats should not results in error", func() { - query := m.GetAlertNotifierUsageStatsQuery{} + query := models.GetAlertNotifierUsageStatsQuery{} err := GetAlertNotifiersUsageStats(context.Background(), &query) So(err, ShouldBeNil) }) + + Convey("Get admin stats should not result in error", func() { + query := models.GetAdminStatsQuery{} + err := GetAdminStats(&query) + So(err, ShouldBeNil) + }) }) } diff --git a/public/app/features/admin/state/apis.ts b/public/app/features/admin/state/apis.ts index d81fd299493..05321c6e714 100644 --- a/public/app/features/admin/state/apis.ts +++ b/public/app/features/admin/state/apis.ts @@ -10,8 +10,15 @@ export const getServerStats = async (): Promise => { const res = await getBackendSrv().get('api/admin/stats'); return [ { name: 'Total users', value: res.users }, - { name: 'Total dashboards', value: res.dashboards }, + { name: 'Total admins', value: res.admins }, + { name: 'Total editors', value: res.editors }, + { name: 'Total viewers', value: res.viewers }, { name: 'Active users (seen last 30 days)', value: res.activeUsers }, + { name: 'Active admins (seen last 30 days)', value: res.activeAdmins }, + { name: 'Active editors (seen last 30 days)', value: res.activeEditors }, + { name: 'Active viewers (seen last 30 days)', value: res.activeViewers }, + { name: 'Active sessions', value: res.activeSessions }, + { name: 'Total dashboards', value: res.dashboards }, { name: 'Total orgs', value: res.orgs }, { name: 'Total playlists', value: res.playlists }, { name: 'Total snapshots', value: res.snapshots }, diff --git a/scripts/circle-test-postgres.sh b/scripts/circle-test-postgres.sh index 7ddfe6887d9..df4897484ad 100755 --- a/scripts/circle-test-postgres.sh +++ b/scripts/circle-test-postgres.sh @@ -12,6 +12,7 @@ function exit_if_fail { export GRAFANA_TEST_DB=postgres -time for d in $(go list ./pkg/...); do - exit_if_fail go test -tags=integration $d -done \ No newline at end of file +exit_if_fail go test -v -run="StatsDataAccess" -tags=integration ./pkg/services/sqlstore/... +#time for d in $(go list ./pkg/...); do +# exit_if_fail go test -tags=integration $d +#done \ No newline at end of file