mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Chore: Add context to star and stats (#39591)
* Add context to star and stats * Use WithTransactionalDbSession * Add additional ctx * Remove convey * Fix star handler name * Use WithDbSession, use DispatchCtx * Remove xorm from star
This commit is contained in:
parent
580cdc46fc
commit
b255c1b992
@ -22,7 +22,7 @@ func (hs *HTTPServer) AdminGetSettings(c *models.ReqContext) response.Response {
|
||||
func AdminGetStats(c *models.ReqContext) response.Response {
|
||||
statsQuery := models.GetAdminStatsQuery{}
|
||||
|
||||
if err := bus.Dispatch(&statsQuery); err != nil {
|
||||
if err := bus.DispatchCtx(c.Req.Context(), &statsQuery); err != nil {
|
||||
return response.Error(500, "Failed to get admin stats from database", err)
|
||||
}
|
||||
|
||||
|
@ -49,7 +49,7 @@ func ProvideService(cfg *setting.Cfg, bus bus.Bus, sqlStore *sqlstore.SQLStore,
|
||||
}
|
||||
|
||||
func (uss *UsageStats) Run(ctx context.Context) error {
|
||||
uss.updateTotalStats()
|
||||
uss.updateTotalStats(ctx)
|
||||
|
||||
// try to load last sent time from kv store
|
||||
lastSent := time.Now()
|
||||
@ -97,7 +97,7 @@ func (uss *UsageStats) Run(ctx context.Context) error {
|
||||
callback()
|
||||
}
|
||||
case <-updateStatsTicker.C:
|
||||
uss.updateTotalStats()
|
||||
uss.updateTotalStats(ctx)
|
||||
case <-ctx.Done():
|
||||
return ctx.Err()
|
||||
}
|
||||
|
@ -38,7 +38,7 @@ func (uss *UsageStats) GetUsageReport(ctx context.Context) (usagestats.Report, e
|
||||
}
|
||||
|
||||
statsQuery := models.GetSystemStatsQuery{}
|
||||
if err := uss.Bus.Dispatch(&statsQuery); err != nil {
|
||||
if err := uss.Bus.DispatchCtx(ctx, &statsQuery); err != nil {
|
||||
uss.log.Error("Failed to get system stats", "error", err)
|
||||
return report, err
|
||||
}
|
||||
@ -110,7 +110,7 @@ func (uss *UsageStats) GetUsageReport(ctx context.Context) (usagestats.Report, e
|
||||
metrics["stats.avg_auth_token_per_user.count"] = avgAuthTokensPerUser
|
||||
|
||||
dsStats := models.GetDataSourceStatsQuery{}
|
||||
if err := uss.Bus.Dispatch(&dsStats); err != nil {
|
||||
if err := uss.Bus.DispatchCtx(ctx, &dsStats); err != nil {
|
||||
uss.log.Error("Failed to get datasource stats", "error", err)
|
||||
return report, err
|
||||
}
|
||||
@ -129,7 +129,7 @@ func (uss *UsageStats) GetUsageReport(ctx context.Context) (usagestats.Report, e
|
||||
metrics["stats.ds.other.count"] = dsOtherCount
|
||||
|
||||
esDataSourcesQuery := models.GetDataSourcesByTypeQuery{Type: models.DS_ES}
|
||||
if err := uss.Bus.Dispatch(&esDataSourcesQuery); err != nil {
|
||||
if err := uss.Bus.DispatchCtx(ctx, &esDataSourcesQuery); err != nil {
|
||||
uss.log.Error("Failed to get elasticsearch json data", "error", err)
|
||||
return report, err
|
||||
}
|
||||
@ -152,7 +152,7 @@ func (uss *UsageStats) GetUsageReport(ctx context.Context) (usagestats.Report, e
|
||||
|
||||
// fetch datasource access stats
|
||||
dsAccessStats := models.GetDataSourceAccessStatsQuery{}
|
||||
if err := uss.Bus.Dispatch(&dsAccessStats); err != nil {
|
||||
if err := uss.Bus.DispatchCtx(ctx, &dsAccessStats); err != nil {
|
||||
uss.log.Error("Failed to get datasource access stats", "error", err)
|
||||
return report, err
|
||||
}
|
||||
@ -287,13 +287,13 @@ var sendUsageStats = func(uss *UsageStats, data *bytes.Buffer) {
|
||||
}()
|
||||
}
|
||||
|
||||
func (uss *UsageStats) updateTotalStats() {
|
||||
func (uss *UsageStats) updateTotalStats(ctx context.Context) {
|
||||
if !uss.Cfg.MetricsEndpointEnabled || uss.Cfg.MetricsEndpointDisableTotalStats {
|
||||
return
|
||||
}
|
||||
|
||||
statsQuery := models.GetSystemStatsQuery{}
|
||||
if err := uss.Bus.Dispatch(&statsQuery); err != nil {
|
||||
if err := uss.Bus.DispatchCtx(ctx, &statsQuery); err != nil {
|
||||
uss.log.Error("Failed to get system stats", "error", err)
|
||||
return
|
||||
}
|
||||
@ -317,7 +317,7 @@ func (uss *UsageStats) updateTotalStats() {
|
||||
metrics.StatsTotalLibraryVariables.Set(float64(statsQuery.Result.LibraryVariables))
|
||||
|
||||
dsStats := models.GetDataSourceStatsQuery{}
|
||||
if err := uss.Bus.Dispatch(&dsStats); err != nil {
|
||||
if err := uss.Bus.DispatchCtx(ctx, &dsStats); err != nil {
|
||||
uss.log.Error("Failed to get datasource stats", "error", err)
|
||||
return
|
||||
}
|
||||
|
@ -411,7 +411,7 @@ func TestMetrics(t *testing.T) {
|
||||
t.Run("When metrics is disabled and total stats is enabled, stats should not be updated", func(t *testing.T) {
|
||||
uss.Cfg.MetricsEndpointEnabled = false
|
||||
uss.Cfg.MetricsEndpointDisableTotalStats = false
|
||||
uss.updateTotalStats()
|
||||
uss.updateTotalStats(context.Background())
|
||||
|
||||
assert.False(t, getSystemStatsWasCalled)
|
||||
})
|
||||
@ -420,7 +420,7 @@ func TestMetrics(t *testing.T) {
|
||||
uss.Cfg.MetricsEndpointEnabled = true
|
||||
uss.Cfg.MetricsEndpointDisableTotalStats = true
|
||||
|
||||
uss.updateTotalStats()
|
||||
uss.updateTotalStats(context.Background())
|
||||
|
||||
assert.False(t, getSystemStatsWasCalled)
|
||||
})
|
||||
@ -429,7 +429,7 @@ func TestMetrics(t *testing.T) {
|
||||
uss.Cfg.MetricsEndpointEnabled = false
|
||||
uss.Cfg.MetricsEndpointDisableTotalStats = true
|
||||
|
||||
uss.updateTotalStats()
|
||||
uss.updateTotalStats(context.Background())
|
||||
|
||||
assert.False(t, getSystemStatsWasCalled)
|
||||
})
|
||||
@ -438,7 +438,7 @@ func TestMetrics(t *testing.T) {
|
||||
uss.Cfg.MetricsEndpointEnabled = true
|
||||
uss.Cfg.MetricsEndpointDisableTotalStats = false
|
||||
|
||||
uss.updateTotalStats()
|
||||
uss.updateTotalStats(context.Background())
|
||||
|
||||
assert.True(t, getSystemStatsWasCalled)
|
||||
})
|
||||
|
@ -386,13 +386,13 @@ func TestDashboardDataAccess(t *testing.T) {
|
||||
|
||||
Convey("Given two dashboards, one is starred dashboard by user 10, other starred by user 1", func() {
|
||||
starredDash := insertTestDashboard(t, sqlStore, "starred dash", 1, 0, false)
|
||||
err := StarDashboard(&models.StarDashboardCommand{
|
||||
err := sqlStore.StarDashboard(context.Background(), &models.StarDashboardCommand{
|
||||
DashboardId: starredDash.Id,
|
||||
UserId: 10,
|
||||
})
|
||||
So(err, ShouldBeNil)
|
||||
|
||||
err = StarDashboard(&models.StarDashboardCommand{
|
||||
err = sqlStore.StarDashboard(context.Background(), &models.StarDashboardCommand{
|
||||
DashboardId: savedDash.Id,
|
||||
UserId: 1,
|
||||
})
|
||||
|
@ -116,6 +116,7 @@ func newSQLStore(cfg *setting.Cfg, cacheService *localcache.CacheService, bus bu
|
||||
ss.addDashboardACLQueryAndCommandHandlers()
|
||||
ss.addQuotaQueryAndCommandHandlers()
|
||||
ss.addOrgUsersQueryAndCommandHandlers()
|
||||
ss.addStarQueryAndCommandHandlers()
|
||||
|
||||
// if err := ss.Reset(); err != nil {
|
||||
// return nil, err
|
||||
|
@ -7,17 +7,17 @@ import (
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
)
|
||||
|
||||
func init() {
|
||||
bus.AddHandler("sql", StarDashboard)
|
||||
bus.AddHandler("sql", UnstarDashboard)
|
||||
bus.AddHandler("sql", GetUserStars)
|
||||
bus.AddHandlerCtx("sql", IsStarredByUserCtx)
|
||||
func (ss *SQLStore) addStarQueryAndCommandHandlers() {
|
||||
bus.AddHandlerCtx("sql", ss.StarDashboard)
|
||||
bus.AddHandlerCtx("sql", ss.UnstarDashboard)
|
||||
bus.AddHandlerCtx("sql", ss.GetUserStars)
|
||||
bus.AddHandlerCtx("sql", ss.IsStarredByUserCtx)
|
||||
}
|
||||
|
||||
func IsStarredByUserCtx(ctx context.Context, query *models.IsStarredByUserQuery) error {
|
||||
return withDbSession(ctx, x, func(dbSession *DBSession) error {
|
||||
func (ss *SQLStore) IsStarredByUserCtx(ctx context.Context, query *models.IsStarredByUserQuery) error {
|
||||
return ss.WithDbSession(ctx, func(sess *DBSession) error {
|
||||
rawSQL := "SELECT 1 from star where user_id=? and dashboard_id=?"
|
||||
results, err := dbSession.Query(rawSQL, query.UserId, query.DashboardId)
|
||||
results, err := sess.Query(rawSQL, query.UserId, query.DashboardId)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
@ -33,12 +33,12 @@ func IsStarredByUserCtx(ctx context.Context, query *models.IsStarredByUserQuery)
|
||||
})
|
||||
}
|
||||
|
||||
func StarDashboard(cmd *models.StarDashboardCommand) error {
|
||||
func (ss *SQLStore) StarDashboard(ctx context.Context, cmd *models.StarDashboardCommand) error {
|
||||
if cmd.DashboardId == 0 || cmd.UserId == 0 {
|
||||
return models.ErrCommandValidationFailed
|
||||
}
|
||||
|
||||
return inTransaction(func(sess *DBSession) error {
|
||||
return ss.WithTransactionalDbSession(ctx, func(sess *DBSession) error {
|
||||
entity := models.Star{
|
||||
UserId: cmd.UserId,
|
||||
DashboardId: cmd.DashboardId,
|
||||
@ -49,26 +49,28 @@ func StarDashboard(cmd *models.StarDashboardCommand) error {
|
||||
})
|
||||
}
|
||||
|
||||
func UnstarDashboard(cmd *models.UnstarDashboardCommand) error {
|
||||
func (ss *SQLStore) UnstarDashboard(ctx context.Context, cmd *models.UnstarDashboardCommand) error {
|
||||
if cmd.DashboardId == 0 || cmd.UserId == 0 {
|
||||
return models.ErrCommandValidationFailed
|
||||
}
|
||||
|
||||
return inTransaction(func(sess *DBSession) error {
|
||||
return ss.WithTransactionalDbSession(ctx, func(sess *DBSession) error {
|
||||
var rawSQL = "DELETE FROM star WHERE user_id=? and dashboard_id=?"
|
||||
_, err := sess.Exec(rawSQL, cmd.UserId, cmd.DashboardId)
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
||||
func GetUserStars(query *models.GetUserStarsQuery) error {
|
||||
var stars = make([]models.Star, 0)
|
||||
err := x.Where("user_id=?", query.UserId).Find(&stars)
|
||||
func (ss *SQLStore) GetUserStars(ctx context.Context, query *models.GetUserStarsQuery) error {
|
||||
return ss.WithDbSession(ctx, func(dbSession *DBSession) error {
|
||||
var stars = make([]models.Star, 0)
|
||||
err := dbSession.Where("user_id=?", query.UserId).Find(&stars)
|
||||
|
||||
query.Result = make(map[int64]bool)
|
||||
for _, star := range stars {
|
||||
query.Result[star.DashboardId] = true
|
||||
}
|
||||
query.Result = make(map[int64]bool)
|
||||
for _, star := range stars {
|
||||
query.Result[star.DashboardId] = true
|
||||
}
|
||||
|
||||
return err
|
||||
return err
|
||||
})
|
||||
}
|
||||
|
@ -8,36 +8,36 @@ import (
|
||||
"testing"
|
||||
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
. "github.com/smartystreets/goconvey/convey"
|
||||
"github.com/stretchr/testify/require"
|
||||
)
|
||||
|
||||
func TestUserStarsDataAccess(t *testing.T) {
|
||||
Convey("Testing User Stars Data Access", t, func() {
|
||||
InitTestDB(t)
|
||||
t.Run("Testing User Stars Data Access", func(t *testing.T) {
|
||||
sqlStore := InitTestDB(t)
|
||||
|
||||
Convey("Given saved star", func() {
|
||||
t.Run("Given saved star", func(t *testing.T) {
|
||||
cmd := models.StarDashboardCommand{
|
||||
DashboardId: 10,
|
||||
UserId: 12,
|
||||
}
|
||||
|
||||
err := StarDashboard(&cmd)
|
||||
So(err, ShouldBeNil)
|
||||
err := sqlStore.StarDashboard(context.Background(), &cmd)
|
||||
require.NoError(t, err)
|
||||
|
||||
Convey("IsStarredByUser should return true when starred", func() {
|
||||
t.Run("IsStarredByUser should return true when starred", func(t *testing.T) {
|
||||
query := models.IsStarredByUserQuery{UserId: 12, DashboardId: 10}
|
||||
err := IsStarredByUserCtx(context.Background(), &query)
|
||||
So(err, ShouldBeNil)
|
||||
err := sqlStore.IsStarredByUserCtx(context.Background(), &query)
|
||||
require.NoError(t, err)
|
||||
|
||||
So(query.Result, ShouldBeTrue)
|
||||
require.True(t, query.Result)
|
||||
})
|
||||
|
||||
Convey("IsStarredByUser should return false when not starred", func() {
|
||||
t.Run("IsStarredByUser should return false when not starred", func(t *testing.T) {
|
||||
query := models.IsStarredByUserQuery{UserId: 12, DashboardId: 12}
|
||||
err := IsStarredByUserCtx(context.Background(), &query)
|
||||
So(err, ShouldBeNil)
|
||||
err := sqlStore.IsStarredByUserCtx(context.Background(), &query)
|
||||
require.NoError(t, err)
|
||||
|
||||
So(query.Result, ShouldBeFalse)
|
||||
require.False(t, query.Result)
|
||||
})
|
||||
})
|
||||
})
|
||||
|
@ -10,10 +10,10 @@ import (
|
||||
)
|
||||
|
||||
func init() {
|
||||
bus.AddHandler("sql", GetSystemStats)
|
||||
bus.AddHandler("sql", GetDataSourceStats)
|
||||
bus.AddHandler("sql", GetDataSourceAccessStats)
|
||||
bus.AddHandler("sql", GetAdminStats)
|
||||
bus.AddHandlerCtx("sql", GetSystemStats)
|
||||
bus.AddHandlerCtx("sql", GetDataSourceStats)
|
||||
bus.AddHandlerCtx("sql", GetDataSourceAccessStats)
|
||||
bus.AddHandlerCtx("sql", GetAdminStats)
|
||||
bus.AddHandlerCtx("sql", GetAlertNotifiersUsageStats)
|
||||
bus.AddHandlerCtx("sql", GetSystemUserCountStats)
|
||||
}
|
||||
@ -28,21 +28,21 @@ func GetAlertNotifiersUsageStats(ctx context.Context, query *models.GetAlertNoti
|
||||
return err
|
||||
}
|
||||
|
||||
func GetDataSourceStats(query *models.GetDataSourceStatsQuery) error {
|
||||
func GetDataSourceStats(ctx context.Context, query *models.GetDataSourceStatsQuery) error {
|
||||
var rawSQL = `SELECT COUNT(*) AS count, type FROM ` + dialect.Quote("data_source") + ` GROUP BY type`
|
||||
query.Result = make([]*models.DataSourceStats, 0)
|
||||
err := x.SQL(rawSQL).Find(&query.Result)
|
||||
return err
|
||||
}
|
||||
|
||||
func GetDataSourceAccessStats(query *models.GetDataSourceAccessStatsQuery) error {
|
||||
func GetDataSourceAccessStats(ctx context.Context, query *models.GetDataSourceAccessStatsQuery) error {
|
||||
var rawSQL = `SELECT COUNT(*) AS count, type, access FROM ` + dialect.Quote("data_source") + ` GROUP BY type, access`
|
||||
query.Result = make([]*models.DataSourceAccessStats, 0)
|
||||
err := x.SQL(rawSQL).Find(&query.Result)
|
||||
return err
|
||||
}
|
||||
|
||||
func GetSystemStats(query *models.GetSystemStatsQuery) error {
|
||||
func GetSystemStats(ctx context.Context, query *models.GetSystemStatsQuery) error {
|
||||
sb := &SQLBuilder{}
|
||||
sb.Write("SELECT ")
|
||||
sb.Write(`(SELECT COUNT(*) FROM ` + dialect.Quote("user") + `) AS users,`)
|
||||
@ -92,7 +92,7 @@ func GetSystemStats(query *models.GetSystemStatsQuery) error {
|
||||
sb.Write(`(SELECT COUNT(id) FROM `+dialect.Quote("library_element")+` WHERE kind = ?) AS library_panels,`, models.PanelElement)
|
||||
sb.Write(`(SELECT COUNT(id) FROM `+dialect.Quote("library_element")+` WHERE kind = ?) AS library_variables,`, models.VariableElement)
|
||||
|
||||
sb.Write(roleCounterSQL())
|
||||
sb.Write(roleCounterSQL(ctx))
|
||||
|
||||
var stats models.SystemStats
|
||||
_, err := x.SQL(sb.GetSQLString(), sb.params...).Get(&stats)
|
||||
@ -105,9 +105,9 @@ func GetSystemStats(query *models.GetSystemStatsQuery) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func roleCounterSQL() string {
|
||||
func roleCounterSQL(ctx context.Context) string {
|
||||
const roleCounterTimeout = 20 * time.Second
|
||||
ctx, cancel := context.WithTimeout(context.Background(), roleCounterTimeout)
|
||||
ctx, cancel := context.WithTimeout(ctx, roleCounterTimeout)
|
||||
defer cancel()
|
||||
_ = updateUserRoleCountsIfNecessary(ctx, false)
|
||||
sqlQuery :=
|
||||
@ -136,7 +136,7 @@ func viewersPermissionsCounterSQL(statName string, isFolder bool, permission mod
|
||||
) AS ` + statName + `, `
|
||||
}
|
||||
|
||||
func GetAdminStats(query *models.GetAdminStatsQuery) error {
|
||||
func GetAdminStats(ctx context.Context, query *models.GetAdminStatsQuery) error {
|
||||
activeEndDate := time.Now().Add(-activeUserTimeLimit)
|
||||
dailyActiveEndDate := time.Now().Add(-dailyActiveUserTimeLimit)
|
||||
|
||||
@ -185,7 +185,7 @@ func GetAdminStats(query *models.GetAdminStatsQuery) error {
|
||||
SELECT COUNT(*)
|
||||
FROM ` + dialect.Quote("user") + ` WHERE last_seen_at > ?
|
||||
) AS daily_active_users,
|
||||
` + roleCounterSQL() + `,
|
||||
` + roleCounterSQL(ctx) + `,
|
||||
(
|
||||
SELECT COUNT(*)
|
||||
FROM ` + dialect.Quote("user_auth_token") + ` WHERE rotated_at > ?
|
||||
|
@ -4,6 +4,7 @@
|
||||
package sqlstore
|
||||
|
||||
import (
|
||||
"context"
|
||||
"testing"
|
||||
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
@ -14,6 +15,6 @@ func TestIntegration_GetAdminStats(t *testing.T) {
|
||||
InitTestDB(t)
|
||||
|
||||
query := models.GetAdminStatsQuery{}
|
||||
err := GetAdminStats(&query)
|
||||
err := GetAdminStats(context.Background(), &query)
|
||||
require.NoError(t, err)
|
||||
}
|
||||
|
@ -19,7 +19,7 @@ func TestStatsDataAccess(t *testing.T) {
|
||||
|
||||
t.Run("Get system stats should not results in error", func(t *testing.T) {
|
||||
query := models.GetSystemStatsQuery{}
|
||||
err := GetSystemStats(&query)
|
||||
err := GetSystemStats(context.Background(), &query)
|
||||
require.NoError(t, err)
|
||||
assert.Equal(t, int64(3), query.Result.Users)
|
||||
assert.Equal(t, int64(0), query.Result.Editors)
|
||||
@ -37,13 +37,13 @@ func TestStatsDataAccess(t *testing.T) {
|
||||
|
||||
t.Run("Get datasource stats should not results in error", func(t *testing.T) {
|
||||
query := models.GetDataSourceStatsQuery{}
|
||||
err := GetDataSourceStats(&query)
|
||||
err := GetDataSourceStats(context.Background(), &query)
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
|
||||
t.Run("Get datasource access stats should not results in error", func(t *testing.T) {
|
||||
query := models.GetDataSourceAccessStatsQuery{}
|
||||
err := GetDataSourceAccessStats(&query)
|
||||
err := GetDataSourceAccessStats(context.Background(), &query)
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
|
||||
@ -55,7 +55,7 @@ func TestStatsDataAccess(t *testing.T) {
|
||||
|
||||
t.Run("Get admin stats should not result in error", func(t *testing.T) {
|
||||
query := models.GetAdminStatsQuery{}
|
||||
err := GetAdminStats(&query)
|
||||
err := GetAdminStats(context.Background(), &query)
|
||||
assert.NoError(t, err)
|
||||
})
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user