stats.go 5.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194
  1. package sqlstore
  2. import (
  3. "context"
  4. "time"
  5. "github.com/grafana/grafana/pkg/bus"
  6. m "github.com/grafana/grafana/pkg/models"
  7. )
  8. func init() {
  9. bus.AddHandler("sql", GetSystemStats)
  10. bus.AddHandler("sql", GetDataSourceStats)
  11. bus.AddHandler("sql", GetDataSourceAccessStats)
  12. bus.AddHandler("sql", GetAdminStats)
  13. bus.AddHandlerCtx("sql", GetAlertNotifiersUsageStats)
  14. bus.AddHandlerCtx("sql", GetSystemUserCountStats)
  15. }
  16. var activeUserTimeLimit = time.Hour * 24 * 30
  17. func GetAlertNotifiersUsageStats(ctx context.Context, query *m.GetAlertNotifierUsageStatsQuery) error {
  18. var rawSql = `SELECT COUNT(*) as count, type FROM alert_notification GROUP BY type`
  19. query.Result = make([]*m.NotifierUsageStats, 0)
  20. err := x.SQL(rawSql).Find(&query.Result)
  21. return err
  22. }
  23. func GetDataSourceStats(query *m.GetDataSourceStatsQuery) error {
  24. var rawSql = `SELECT COUNT(*) as count, type FROM data_source GROUP BY type`
  25. query.Result = make([]*m.DataSourceStats, 0)
  26. err := x.SQL(rawSql).Find(&query.Result)
  27. return err
  28. }
  29. func GetDataSourceAccessStats(query *m.GetDataSourceAccessStatsQuery) error {
  30. var rawSql = `SELECT COUNT(*) as count, type, access FROM data_source GROUP BY type, access`
  31. query.Result = make([]*m.DataSourceAccessStats, 0)
  32. err := x.SQL(rawSql).Find(&query.Result)
  33. return err
  34. }
  35. func GetSystemStats(query *m.GetSystemStatsQuery) error {
  36. sb := &SqlBuilder{}
  37. sb.Write("SELECT ")
  38. sb.Write(`(SELECT COUNT(*) FROM ` + dialect.Quote("user") + `) AS users,`)
  39. sb.Write(`(SELECT COUNT(*) FROM ` + dialect.Quote("org") + `) AS orgs,`)
  40. sb.Write(`(SELECT COUNT(*) FROM ` + dialect.Quote("dashboard") + `) AS dashboards,`)
  41. sb.Write(`(SELECT COUNT(*) FROM ` + dialect.Quote("data_source") + `) AS datasources,`)
  42. sb.Write(`(SELECT COUNT(*) FROM ` + dialect.Quote("star") + `) AS stars,`)
  43. sb.Write(`(SELECT COUNT(*) FROM ` + dialect.Quote("playlist") + `) AS playlists,`)
  44. sb.Write(`(SELECT COUNT(*) FROM ` + dialect.Quote("alert") + `) AS alerts,`)
  45. activeUserDeadlineDate := time.Now().Add(-activeUserTimeLimit)
  46. sb.Write(`(SELECT COUNT(*) FROM `+dialect.Quote("user")+` where last_seen_at > ?) AS active_users,`, activeUserDeadlineDate)
  47. sb.Write(`(SELECT COUNT(id) FROM `+dialect.Quote("dashboard")+` where is_folder = ?) AS folders,`, dialect.BooleanStr(true))
  48. sb.Write(`(
  49. SELECT COUNT(acl.id)
  50. FROM `+dialect.Quote("dashboard_acl")+` as acl
  51. inner join `+dialect.Quote("dashboard")+` as d
  52. on d.id = acl.dashboard_id
  53. WHERE d.is_folder = ?
  54. ) AS dashboard_permissions,`, dialect.BooleanStr(false))
  55. sb.Write(`(
  56. SELECT COUNT(acl.id)
  57. FROM `+dialect.Quote("dashboard_acl")+` as acl
  58. inner join `+dialect.Quote("dashboard")+` as d
  59. on d.id = acl.dashboard_id
  60. WHERE d.is_folder = ?
  61. ) AS folder_permissions,`, dialect.BooleanStr(true))
  62. sb.Write(`(SELECT COUNT(id) FROM ` + dialect.Quote("dashboard_provisioning") + `) AS provisioned_dashboards,`)
  63. sb.Write(`(SELECT COUNT(id) FROM ` + dialect.Quote("dashboard_snapshot") + `) AS snapshots,`)
  64. sb.Write(`(SELECT COUNT(id) FROM ` + dialect.Quote("team") + `) AS teams,`)
  65. sb.Write(`(SELECT COUNT(id) FROM ` + dialect.Quote("user_auth_token") + `) AS auth_tokens,`)
  66. sb.Write(roleCounterSQL("Viewer", "viewers")+`,`, activeUserDeadlineDate)
  67. sb.Write(roleCounterSQL("Editor", "editors")+`,`, activeUserDeadlineDate)
  68. sb.Write(roleCounterSQL("Admin", "admins")+``, activeUserDeadlineDate)
  69. var stats m.SystemStats
  70. _, err := x.SQL(sb.GetSqlString(), sb.params...).Get(&stats)
  71. if err != nil {
  72. return err
  73. }
  74. query.Result = &stats
  75. return err
  76. }
  77. func roleCounterSQL(role, alias string) string {
  78. return `
  79. (
  80. SELECT COUNT(*)
  81. FROM ` + dialect.Quote("user") + ` as u
  82. WHERE
  83. (SELECT COUNT(*)
  84. FROM org_user
  85. WHERE org_user.user_id=u.id
  86. AND org_user.role='` + role + `')>0
  87. ) as ` + alias + `,
  88. (
  89. SELECT COUNT(*)
  90. FROM ` + dialect.Quote("user") + ` as u
  91. WHERE
  92. (SELECT COUNT(*)
  93. FROM org_user
  94. WHERE org_user.user_id=u.id
  95. AND org_user.role='` + role + `')>0
  96. AND u.last_seen_at>?
  97. ) as active_` + alias
  98. }
  99. func GetAdminStats(query *m.GetAdminStatsQuery) error {
  100. activeEndDate := time.Now().Add(-activeUserTimeLimit)
  101. var rawSql = `SELECT
  102. (
  103. SELECT COUNT(*)
  104. FROM ` + dialect.Quote("org") + `
  105. ) AS orgs,
  106. (
  107. SELECT COUNT(*)
  108. FROM ` + dialect.Quote("dashboard") + `
  109. ) AS dashboards,
  110. (
  111. SELECT COUNT(*)
  112. FROM ` + dialect.Quote("dashboard_snapshot") + `
  113. ) AS snapshots,
  114. (
  115. SELECT COUNT( DISTINCT ( ` + dialect.Quote("term") + ` ))
  116. FROM ` + dialect.Quote("dashboard_tag") + `
  117. ) AS tags,
  118. (
  119. SELECT COUNT(*)
  120. FROM ` + dialect.Quote("data_source") + `
  121. ) AS datasources,
  122. (
  123. SELECT COUNT(*)
  124. FROM ` + dialect.Quote("playlist") + `
  125. ) AS playlists,
  126. (
  127. SELECT COUNT(*) FROM ` + dialect.Quote("star") + `
  128. ) AS stars,
  129. (
  130. SELECT COUNT(*)
  131. FROM ` + dialect.Quote("alert") + `
  132. ) AS alerts,
  133. (
  134. SELECT COUNT(*)
  135. FROM ` + dialect.Quote("user") + `
  136. ) AS users,
  137. (
  138. SELECT COUNT(*)
  139. FROM ` + dialect.Quote("user") + ` where last_seen_at > ?
  140. ) as active_users,
  141. ` + roleCounterSQL("Admin", "admins") + `,
  142. ` + roleCounterSQL("Editor", "editors") + `,
  143. ` + roleCounterSQL("Viewer", "viewers") + `,
  144. (
  145. SELECT COUNT(*)
  146. FROM ` + dialect.Quote("user_auth_token") + ` where rotated_at > ?
  147. ) as active_sessions
  148. `
  149. var stats m.AdminStats
  150. _, err := x.SQL(rawSql, activeEndDate, activeEndDate, activeEndDate, activeEndDate, activeEndDate.Unix()).Get(&stats)
  151. if err != nil {
  152. return err
  153. }
  154. query.Result = &stats
  155. return err
  156. }
  157. func GetSystemUserCountStats(ctx context.Context, query *m.GetSystemUserCountStatsQuery) error {
  158. return withDbSession(ctx, func(sess *DBSession) error {
  159. var rawSql = `SELECT COUNT(id) AS Count FROM ` + dialect.Quote("user")
  160. var stats m.SystemUserCountStats
  161. _, err := sess.SQL(rawSql).Get(&stats)
  162. if err != nil {
  163. return err
  164. }
  165. query.Result = &stats
  166. return err
  167. })
  168. }