Usage Stats: Split domain & service packages (#39488)

pull/39490/head
Joan López de la Franca Beltran 4 years ago committed by GitHub
parent b31316753a
commit a680162792
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
  1. 6
      pkg/api/http_server.go
  2. 171
      pkg/infra/usagestats/service.go
  3. 163
      pkg/infra/usagestats/service/service.go
  4. 2
      pkg/infra/usagestats/service/types.go
  5. 36
      pkg/infra/usagestats/service/usage_stats.go
  6. 4
      pkg/infra/usagestats/service/usage_stats_service_test.go
  7. 19
      pkg/infra/usagestats/service/usage_stats_test.go
  8. 4
      pkg/server/backgroundsvcs/background_services.go
  9. 5
      pkg/server/wire.go
  10. 4
      pkg/services/accesscontrol/ossaccesscontrol/ossaccesscontrol.go
  11. 4
      pkg/services/accesscontrol/ossaccesscontrol/ossaccesscontrol_test.go

@ -22,7 +22,6 @@ import (
"github.com/grafana/grafana/pkg/infra/metrics" "github.com/grafana/grafana/pkg/infra/metrics"
"github.com/grafana/grafana/pkg/infra/remotecache" "github.com/grafana/grafana/pkg/infra/remotecache"
"github.com/grafana/grafana/pkg/infra/tracing" "github.com/grafana/grafana/pkg/infra/tracing"
"github.com/grafana/grafana/pkg/infra/usagestats"
"github.com/grafana/grafana/pkg/login/social" "github.com/grafana/grafana/pkg/login/social"
"github.com/grafana/grafana/pkg/middleware" "github.com/grafana/grafana/pkg/middleware"
"github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/models"
@ -68,7 +67,6 @@ type HTTPServer struct {
httpSrv *http.Server httpSrv *http.Server
middlewares []macaron.Handler middlewares []macaron.Handler
UsageStatsService usagestats.UsageStats
PluginContextProvider *plugincontext.Provider PluginContextProvider *plugincontext.Provider
RouteRegister routing.RouteRegister RouteRegister routing.RouteRegister
Bus bus.Bus Bus bus.Bus
@ -118,8 +116,7 @@ type ServerOptions struct {
func ProvideHTTPServer(opts ServerOptions, cfg *setting.Cfg, routeRegister routing.RouteRegister, bus bus.Bus, func ProvideHTTPServer(opts ServerOptions, cfg *setting.Cfg, routeRegister routing.RouteRegister, bus bus.Bus,
renderService rendering.Service, licensing models.Licensing, hooksService *hooks.HooksService, renderService rendering.Service, licensing models.Licensing, hooksService *hooks.HooksService,
cacheService *localcache.CacheService, sqlStore *sqlstore.SQLStore, cacheService *localcache.CacheService, sqlStore *sqlstore.SQLStore,
dataService *tsdb.Service, alertEngine *alerting.AlertEngine, dataService *tsdb.Service, alertEngine *alerting.AlertEngine, pluginRequestValidator models.PluginRequestValidator,
usageStatsService *usagestats.UsageStatsService, pluginRequestValidator models.PluginRequestValidator,
pluginManager plugins.Manager, backendPM backendplugin.Manager, settingsProvider setting.Provider, pluginManager plugins.Manager, backendPM backendplugin.Manager, settingsProvider setting.Provider,
dataSourceCache datasources.CacheService, userTokenService models.UserTokenService, dataSourceCache datasources.CacheService, userTokenService models.UserTokenService,
cleanUpService *cleanup.CleanUpService, shortURLService shorturls.Service, cleanUpService *cleanup.CleanUpService, shortURLService shorturls.Service,
@ -148,7 +145,6 @@ func ProvideHTTPServer(opts ServerOptions, cfg *setting.Cfg, routeRegister routi
SQLStore: sqlStore, SQLStore: sqlStore,
DataService: dataService, DataService: dataService,
AlertEngine: alertEngine, AlertEngine: alertEngine,
UsageStatsService: usageStatsService,
PluginRequestValidator: pluginRequestValidator, PluginRequestValidator: pluginRequestValidator,
PluginManager: pluginManager, PluginManager: pluginManager,
BackendPluginManager: backendPM, BackendPluginManager: backendPM,

@ -2,168 +2,23 @@ package usagestats
import ( import (
"context" "context"
"fmt"
"time"
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/infra/kvstore"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/login/social"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/services/alerting"
"github.com/grafana/grafana/pkg/services/live"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/setting"
) )
type UsageStats interface { type Report struct {
GetUsageReport(context.Context) (UsageReport, error) Version string `json:"version"`
RegisterMetricsFunc(MetricsFunc) Metrics map[string]interface{} `json:"metrics"`
ShouldBeReported(string) bool Os string `json:"os"`
Arch string `json:"arch"`
Edition string `json:"edition"`
HasValidLicense bool `json:"hasValidLicense"`
Packaging string `json:"packaging"`
UsageStatsId string `json:"usageStatsId"`
} }
type MetricsFunc func() (map[string]interface{}, error) type MetricsFunc func() (map[string]interface{}, error)
type UsageStatsService struct { type Service interface {
Cfg *setting.Cfg GetUsageReport(context.Context) (Report, error)
Bus bus.Bus RegisterMetricsFunc(MetricsFunc)
SQLStore *sqlstore.SQLStore ShouldBeReported(string) bool
AlertingUsageStats alerting.UsageStatsQuerier
PluginManager plugins.Manager
SocialService social.Service
grafanaLive *live.GrafanaLive
kvStore *kvstore.NamespacedKVStore
log log.Logger
oauthProviders map[string]bool
externalMetrics []MetricsFunc
concurrentUserStatsCache memoConcurrentUserStats
liveStats liveUsageStats
startTime time.Time
}
type liveUsageStats struct {
numClientsMax int
numClientsMin int
numClientsSum int
numUsersMax int
numUsersMin int
numUsersSum int
sampleCount int
}
func ProvideService(cfg *setting.Cfg, bus bus.Bus, sqlStore *sqlstore.SQLStore,
alertingStats alerting.UsageStatsQuerier, pluginManager plugins.Manager,
socialService social.Service, grafanaLive *live.GrafanaLive,
kvStore kvstore.KVStore) *UsageStatsService {
s := &UsageStatsService{
Cfg: cfg,
Bus: bus,
SQLStore: sqlStore,
AlertingUsageStats: alertingStats,
oauthProviders: socialService.GetOAuthProviders(),
PluginManager: pluginManager,
grafanaLive: grafanaLive,
kvStore: kvstore.WithNamespace(kvStore, 0, "infra.usagestats"),
log: log.New("infra.usagestats"),
startTime: time.Now(),
}
return s
}
func (uss *UsageStatsService) Run(ctx context.Context) error {
uss.updateTotalStats()
// try to load last sent time from kv store
lastSent := time.Now()
if val, ok, err := uss.kvStore.Get(ctx, "last_sent"); err != nil {
uss.log.Error("Failed to get last sent time", "error", err)
} else if ok {
if parsed, err := time.Parse(time.RFC3339, val); err != nil {
uss.log.Error("Failed to parse last sent time", "error", err)
} else {
lastSent = parsed
}
}
// calculate initial send delay
sendInterval := time.Hour * 24
nextSendInterval := time.Until(lastSent.Add(sendInterval))
if nextSendInterval < time.Minute {
nextSendInterval = time.Minute
}
sendReportTicker := time.NewTicker(nextSendInterval)
updateStatsTicker := time.NewTicker(time.Minute * 30)
defer sendReportTicker.Stop()
defer updateStatsTicker.Stop()
for {
select {
case <-sendReportTicker.C:
if err := uss.sendUsageStats(ctx); err != nil {
uss.log.Warn("Failed to send usage stats", "error", err)
}
lastSent = time.Now()
if err := uss.kvStore.Set(ctx, "last_sent", lastSent.Format(time.RFC3339)); err != nil {
uss.log.Warn("Failed to update last sent time", "error", err)
}
if nextSendInterval != sendInterval {
nextSendInterval = sendInterval
sendReportTicker.Reset(nextSendInterval)
}
// always reset live stats every report tick
uss.resetLiveStats()
case <-updateStatsTicker.C:
uss.updateTotalStats()
uss.sampleLiveStats()
case <-ctx.Done():
return ctx.Err()
}
}
}
type memoConcurrentUserStats struct {
stats *concurrentUsersStats
memoized time.Time
}
const concurrentUserStatsCacheLifetime = time.Hour
func (uss *UsageStatsService) GetConcurrentUsersStats(ctx context.Context) (*concurrentUsersStats, error) {
memoizationPeriod := time.Now().Add(-concurrentUserStatsCacheLifetime)
if !uss.concurrentUserStatsCache.memoized.Before(memoizationPeriod) {
return uss.concurrentUserStatsCache.stats, nil
}
uss.concurrentUserStatsCache.stats = &concurrentUsersStats{}
err := uss.SQLStore.WithDbSession(ctx, func(sess *sqlstore.DBSession) error {
// Retrieves concurrent users stats as a histogram. Buckets are accumulative and upper bound is inclusive.
rawSQL := `
SELECT
COUNT(CASE WHEN tokens <= 3 THEN 1 END) AS bucket_le_3,
COUNT(CASE WHEN tokens <= 6 THEN 1 END) AS bucket_le_6,
COUNT(CASE WHEN tokens <= 9 THEN 1 END) AS bucket_le_9,
COUNT(CASE WHEN tokens <= 12 THEN 1 END) AS bucket_le_12,
COUNT(CASE WHEN tokens <= 15 THEN 1 END) AS bucket_le_15,
COUNT(1) AS bucket_le_inf
FROM (select count(1) as tokens from user_auth_token group by user_id) uat;`
_, err := sess.SQL(rawSQL).Get(uss.concurrentUserStatsCache.stats)
if err != nil {
return err
}
return nil
})
if err != nil {
return nil, fmt.Errorf("failed to get concurrent users stats from database: %w", err)
}
uss.concurrentUserStatsCache.memoized = time.Now()
return uss.concurrentUserStatsCache.stats, nil
} }

@ -0,0 +1,163 @@
package service
import (
"context"
"fmt"
"time"
"github.com/grafana/grafana/pkg/bus"
"github.com/grafana/grafana/pkg/infra/kvstore"
"github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/infra/usagestats"
"github.com/grafana/grafana/pkg/login/social"
"github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/services/alerting"
"github.com/grafana/grafana/pkg/services/live"
"github.com/grafana/grafana/pkg/services/sqlstore"
"github.com/grafana/grafana/pkg/setting"
)
type UsageStats struct {
Cfg *setting.Cfg
Bus bus.Bus
SQLStore *sqlstore.SQLStore
AlertingUsageStats alerting.UsageStatsQuerier
PluginManager plugins.Manager
SocialService social.Service
grafanaLive *live.GrafanaLive
kvStore *kvstore.NamespacedKVStore
log log.Logger
oauthProviders map[string]bool
externalMetrics []usagestats.MetricsFunc
concurrentUserStatsCache memoConcurrentUserStats
liveStats liveUsageStats
startTime time.Time
}
type liveUsageStats struct {
numClientsMax int
numClientsMin int
numClientsSum int
numUsersMax int
numUsersMin int
numUsersSum int
sampleCount int
}
func ProvideService(cfg *setting.Cfg, bus bus.Bus, sqlStore *sqlstore.SQLStore,
alertingStats alerting.UsageStatsQuerier, pluginManager plugins.Manager,
socialService social.Service, grafanaLive *live.GrafanaLive,
kvStore kvstore.KVStore) *UsageStats {
s := &UsageStats{
Cfg: cfg,
Bus: bus,
SQLStore: sqlStore,
AlertingUsageStats: alertingStats,
oauthProviders: socialService.GetOAuthProviders(),
PluginManager: pluginManager,
grafanaLive: grafanaLive,
kvStore: kvstore.WithNamespace(kvStore, 0, "infra.usagestats"),
log: log.New("infra.usagestats"),
startTime: time.Now(),
}
return s
}
func (uss *UsageStats) Run(ctx context.Context) error {
uss.updateTotalStats()
// try to load last sent time from kv store
lastSent := time.Now()
if val, ok, err := uss.kvStore.Get(ctx, "last_sent"); err != nil {
uss.log.Error("Failed to get last sent time", "error", err)
} else if ok {
if parsed, err := time.Parse(time.RFC3339, val); err != nil {
uss.log.Error("Failed to parse last sent time", "error", err)
} else {
lastSent = parsed
}
}
// calculate initial send delay
sendInterval := time.Hour * 24
nextSendInterval := time.Until(lastSent.Add(sendInterval))
if nextSendInterval < time.Minute {
nextSendInterval = time.Minute
}
sendReportTicker := time.NewTicker(nextSendInterval)
updateStatsTicker := time.NewTicker(time.Minute * 30)
defer sendReportTicker.Stop()
defer updateStatsTicker.Stop()
for {
select {
case <-sendReportTicker.C:
if err := uss.sendUsageStats(ctx); err != nil {
uss.log.Warn("Failed to send usage stats", "error", err)
}
lastSent = time.Now()
if err := uss.kvStore.Set(ctx, "last_sent", lastSent.Format(time.RFC3339)); err != nil {
uss.log.Warn("Failed to update last sent time", "error", err)
}
if nextSendInterval != sendInterval {
nextSendInterval = sendInterval
sendReportTicker.Reset(nextSendInterval)
}
// always reset live stats every report tick
uss.resetLiveStats()
case <-updateStatsTicker.C:
uss.updateTotalStats()
uss.sampleLiveStats()
case <-ctx.Done():
return ctx.Err()
}
}
}
type memoConcurrentUserStats struct {
stats *concurrentUsersStats
memoized time.Time
}
const concurrentUserStatsCacheLifetime = time.Hour
func (uss *UsageStats) GetConcurrentUsersStats(ctx context.Context) (*concurrentUsersStats, error) {
memoizationPeriod := time.Now().Add(-concurrentUserStatsCacheLifetime)
if !uss.concurrentUserStatsCache.memoized.Before(memoizationPeriod) {
return uss.concurrentUserStatsCache.stats, nil
}
uss.concurrentUserStatsCache.stats = &concurrentUsersStats{}
err := uss.SQLStore.WithDbSession(ctx, func(sess *sqlstore.DBSession) error {
// Retrieves concurrent users stats as a histogram. Buckets are accumulative and upper bound is inclusive.
rawSQL := `
SELECT
COUNT(CASE WHEN tokens <= 3 THEN 1 END) AS bucket_le_3,
COUNT(CASE WHEN tokens <= 6 THEN 1 END) AS bucket_le_6,
COUNT(CASE WHEN tokens <= 9 THEN 1 END) AS bucket_le_9,
COUNT(CASE WHEN tokens <= 12 THEN 1 END) AS bucket_le_12,
COUNT(CASE WHEN tokens <= 15 THEN 1 END) AS bucket_le_15,
COUNT(1) AS bucket_le_inf
FROM (select count(1) as tokens from user_auth_token group by user_id) uat;`
_, err := sess.SQL(rawSQL).Get(uss.concurrentUserStatsCache.stats)
if err != nil {
return err
}
return nil
})
if err != nil {
return nil, fmt.Errorf("failed to get concurrent users stats from database: %w", err)
}
uss.concurrentUserStatsCache.memoized = time.Now()
return uss.concurrentUserStatsCache.stats, nil
}

@ -1,4 +1,4 @@
package usagestats package service
type concurrentUsersStats struct { type concurrentUsersStats struct {
BucketLE3 int32 `xorm:"bucket_le_3"` BucketLE3 int32 `xorm:"bucket_le_3"`

@ -1,4 +1,4 @@
package usagestats package service
import ( import (
"bytes" "bytes"
@ -12,23 +12,13 @@ import (
"github.com/google/uuid" "github.com/google/uuid"
"github.com/grafana/grafana/pkg/infra/metrics" "github.com/grafana/grafana/pkg/infra/metrics"
"github.com/grafana/grafana/pkg/infra/usagestats"
"github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/models"
) )
var usageStatsURL = "https://stats.grafana.org/grafana-usage-report" var usageStatsURL = "https://stats.grafana.org/grafana-usage-report"
type UsageReport struct { func (uss *UsageStats) GetUsageReport(ctx context.Context) (usagestats.Report, error) {
Version string `json:"version"`
Metrics map[string]interface{} `json:"metrics"`
Os string `json:"os"`
Arch string `json:"arch"`
Edition string `json:"edition"`
HasValidLicense bool `json:"hasValidLicense"`
Packaging string `json:"packaging"`
UsageStatsId string `json:"usageStatsId"`
}
func (uss *UsageStatsService) GetUsageReport(ctx context.Context) (UsageReport, error) {
version := strings.ReplaceAll(uss.Cfg.BuildVersion, ".", "_") version := strings.ReplaceAll(uss.Cfg.BuildVersion, ".", "_")
metrics := map[string]interface{}{} metrics := map[string]interface{}{}
@ -37,7 +27,7 @@ func (uss *UsageStatsService) GetUsageReport(ctx context.Context) (UsageReport,
if uss.Cfg.IsEnterprise { if uss.Cfg.IsEnterprise {
edition = "enterprise" edition = "enterprise"
} }
report := UsageReport{ report := usagestats.Report{
Version: version, Version: version,
Metrics: metrics, Metrics: metrics,
Os: runtime.GOOS, Os: runtime.GOOS,
@ -276,7 +266,7 @@ func (uss *UsageStatsService) GetUsageReport(ctx context.Context) (UsageReport,
return report, nil return report, nil
} }
func (uss *UsageStatsService) registerExternalMetrics(metrics map[string]interface{}) { func (uss *UsageStats) registerExternalMetrics(metrics map[string]interface{}) {
for _, fn := range uss.externalMetrics { for _, fn := range uss.externalMetrics {
fnMetrics, err := fn() fnMetrics, err := fn()
if err != nil { if err != nil {
@ -290,11 +280,11 @@ func (uss *UsageStatsService) registerExternalMetrics(metrics map[string]interfa
} }
} }
func (uss *UsageStatsService) RegisterMetricsFunc(fn MetricsFunc) { func (uss *UsageStats) RegisterMetricsFunc(fn usagestats.MetricsFunc) {
uss.externalMetrics = append(uss.externalMetrics, fn) uss.externalMetrics = append(uss.externalMetrics, fn)
} }
func (uss *UsageStatsService) sendUsageStats(ctx context.Context) error { func (uss *UsageStats) sendUsageStats(ctx context.Context) error {
if !uss.Cfg.ReportingEnabled { if !uss.Cfg.ReportingEnabled {
return nil return nil
} }
@ -319,7 +309,7 @@ func (uss *UsageStatsService) sendUsageStats(ctx context.Context) error {
// sendUsageStats sends usage statistics. // sendUsageStats sends usage statistics.
// //
// Stubbable by tests. // Stubbable by tests.
var sendUsageStats = func(uss *UsageStatsService, data *bytes.Buffer) { var sendUsageStats = func(uss *UsageStats, data *bytes.Buffer) {
go func() { go func() {
client := http.Client{Timeout: 5 * time.Second} client := http.Client{Timeout: 5 * time.Second}
resp, err := client.Post(usageStatsURL, "application/json", data) resp, err := client.Post(usageStatsURL, "application/json", data)
@ -333,7 +323,7 @@ var sendUsageStats = func(uss *UsageStatsService, data *bytes.Buffer) {
}() }()
} }
func (uss *UsageStatsService) sampleLiveStats() { func (uss *UsageStats) sampleLiveStats() {
current := uss.grafanaLive.UsageStats() current := uss.grafanaLive.UsageStats()
uss.liveStats.sampleCount++ uss.liveStats.sampleCount++
@ -357,11 +347,11 @@ func (uss *UsageStatsService) sampleLiveStats() {
} }
} }
func (uss *UsageStatsService) resetLiveStats() { func (uss *UsageStats) resetLiveStats() {
uss.liveStats = liveUsageStats{} uss.liveStats = liveUsageStats{}
} }
func (uss *UsageStatsService) updateTotalStats() { func (uss *UsageStats) updateTotalStats() {
if !uss.Cfg.MetricsEndpointEnabled || uss.Cfg.MetricsEndpointDisableTotalStats { if !uss.Cfg.MetricsEndpointEnabled || uss.Cfg.MetricsEndpointDisableTotalStats {
return return
} }
@ -401,7 +391,7 @@ func (uss *UsageStatsService) updateTotalStats() {
} }
} }
func (uss *UsageStatsService) ShouldBeReported(dsType string) bool { func (uss *UsageStats) ShouldBeReported(dsType string) bool {
ds := uss.PluginManager.GetDataSource(dsType) ds := uss.PluginManager.GetDataSource(dsType)
if ds == nil { if ds == nil {
return false return false
@ -410,7 +400,7 @@ func (uss *UsageStatsService) ShouldBeReported(dsType string) bool {
return ds.Signature.IsValid() || ds.Signature.IsInternal() return ds.Signature.IsValid() || ds.Signature.IsInternal()
} }
func (uss *UsageStatsService) GetUsageStatsId(ctx context.Context) string { func (uss *UsageStats) GetUsageStatsId(ctx context.Context) string {
anonId, ok, err := uss.kvStore.Get(ctx, "anonymous_id") anonId, ok, err := uss.kvStore.Get(ctx, "anonymous_id")
if err != nil { if err != nil {
uss.log.Error("Failed to get usage stats id", "error", err) uss.log.Error("Failed to get usage stats id", "error", err)

@ -1,4 +1,4 @@
package usagestats package service
import ( import (
"context" "context"
@ -19,7 +19,7 @@ import (
func TestUsageStatsService_GetConcurrentUsersStats(t *testing.T) { func TestUsageStatsService_GetConcurrentUsersStats(t *testing.T) {
sqlStore := sqlstore.InitTestDB(t) sqlStore := sqlstore.InitTestDB(t)
uss := &UsageStatsService{ uss := &UsageStats{
Bus: bus.New(), Bus: bus.New(),
SQLStore: sqlStore, SQLStore: sqlStore,
kvStore: kvstore.WithNamespace(kvstore.ProvideService(sqlStore), 0, "infra.usagestats"), kvStore: kvstore.WithNamespace(kvstore.ProvideService(sqlStore), 0, "infra.usagestats"),

@ -1,4 +1,4 @@
package usagestats package service
import ( import (
"bytes" "bytes"
@ -16,6 +16,7 @@ import (
"github.com/grafana/grafana/pkg/components/simplejson" "github.com/grafana/grafana/pkg/components/simplejson"
"github.com/grafana/grafana/pkg/infra/kvstore" "github.com/grafana/grafana/pkg/infra/kvstore"
"github.com/grafana/grafana/pkg/infra/log" "github.com/grafana/grafana/pkg/infra/log"
"github.com/grafana/grafana/pkg/infra/usagestats"
"github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/plugins" "github.com/grafana/grafana/pkg/plugins"
"github.com/grafana/grafana/pkg/plugins/manager" "github.com/grafana/grafana/pkg/plugins/manager"
@ -29,10 +30,10 @@ import (
// This is to ensure that the interface contract is held by the implementation // This is to ensure that the interface contract is held by the implementation
func Test_InterfaceContractValidity(t *testing.T) { func Test_InterfaceContractValidity(t *testing.T) {
newUsageStats := func() UsageStats { newUsageStats := func() usagestats.Service {
return &UsageStatsService{} return &UsageStats{}
} }
v, ok := newUsageStats().(*UsageStatsService) v, ok := newUsageStats().(*UsageStats)
assert.NotNil(t, v) assert.NotNil(t, v)
assert.True(t, ok) assert.True(t, ok)
@ -221,7 +222,7 @@ func TestMetrics(t *testing.T) {
sendUsageStats = origSendUsageStats sendUsageStats = origSendUsageStats
}) })
statsSent := false statsSent := false
sendUsageStats = func(uss *UsageStatsService, b *bytes.Buffer) { sendUsageStats = func(uss *UsageStats, b *bytes.Buffer) {
statsSent = true statsSent = true
} }
@ -592,7 +593,7 @@ func (pm *fakePluginManager) PanelCount() int {
return len(pm.panels) return len(pm.panels)
} }
func setupSomeDataSourcePlugins(t *testing.T, uss *UsageStatsService) { func setupSomeDataSourcePlugins(t *testing.T, uss *UsageStats) {
t.Helper() t.Helper()
uss.PluginManager = &fakePluginManager{ uss.PluginManager = &fakePluginManager{
@ -635,17 +636,17 @@ type httpResp struct {
err error err error
} }
func createService(t *testing.T, cfg setting.Cfg) *UsageStatsService { func createService(t *testing.T, cfg setting.Cfg) *UsageStats {
t.Helper() t.Helper()
sqlStore := sqlstore.InitTestDB(t) sqlStore := sqlstore.InitTestDB(t)
return &UsageStatsService{ return &UsageStats{
Bus: bus.New(), Bus: bus.New(),
Cfg: &cfg, Cfg: &cfg,
SQLStore: sqlStore, SQLStore: sqlStore,
AlertingUsageStats: &alertingUsageMock{}, AlertingUsageStats: &alertingUsageMock{},
externalMetrics: make([]MetricsFunc, 0), externalMetrics: make([]usagestats.MetricsFunc, 0),
PluginManager: &fakePluginManager{}, PluginManager: &fakePluginManager{},
grafanaLive: newTestLive(t), grafanaLive: newTestLive(t),
kvStore: kvstore.WithNamespace(kvstore.ProvideService(sqlStore), 0, "infra.usagestats"), kvStore: kvstore.WithNamespace(kvstore.ProvideService(sqlStore), 0, "infra.usagestats"),

@ -5,7 +5,7 @@ import (
"github.com/grafana/grafana/pkg/infra/metrics" "github.com/grafana/grafana/pkg/infra/metrics"
"github.com/grafana/grafana/pkg/infra/remotecache" "github.com/grafana/grafana/pkg/infra/remotecache"
"github.com/grafana/grafana/pkg/infra/tracing" "github.com/grafana/grafana/pkg/infra/tracing"
"github.com/grafana/grafana/pkg/infra/usagestats" uss "github.com/grafana/grafana/pkg/infra/usagestats/service"
"github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/models"
backendmanager "github.com/grafana/grafana/pkg/plugins/backendplugin/manager" backendmanager "github.com/grafana/grafana/pkg/plugins/backendplugin/manager"
"github.com/grafana/grafana/pkg/plugins/manager" "github.com/grafana/grafana/pkg/plugins/manager"
@ -42,7 +42,7 @@ func ProvideBackgroundServiceRegistry(
rendering *rendering.RenderingService, tokenService models.UserTokenBackgroundService, rendering *rendering.RenderingService, tokenService models.UserTokenBackgroundService,
provisioning *provisioning.ProvisioningServiceImpl, alerting *alerting.AlertEngine, pm *manager.PluginManager, provisioning *provisioning.ProvisioningServiceImpl, alerting *alerting.AlertEngine, pm *manager.PluginManager,
backendPM *backendmanager.Manager, metrics *metrics.InternalMetricsService, backendPM *backendmanager.Manager, metrics *metrics.InternalMetricsService,
usageStats *usagestats.UsageStatsService, tracing *tracing.TracingService, remoteCache *remotecache.RemoteCache, usageStats *uss.UsageStats, tracing *tracing.TracingService, remoteCache *remotecache.RemoteCache,
// Need to make sure these are initialized, is there a better place to put them? // Need to make sure these are initialized, is there a better place to put them?
_ *azuremonitor.Service, _ *cloudwatch.CloudWatchService, _ *elasticsearch.Service, _ *graphite.Service, _ *azuremonitor.Service, _ *cloudwatch.CloudWatchService, _ *elasticsearch.Service, _ *graphite.Service,
_ *influxdb.Service, _ *loki.Service, _ *opentsdb.Service, _ *prometheus.Service, _ *tempo.Service, _ *influxdb.Service, _ *loki.Service, _ *opentsdb.Service, _ *prometheus.Service, _ *tempo.Service,

@ -19,6 +19,7 @@ import (
"github.com/grafana/grafana/pkg/infra/serverlock" "github.com/grafana/grafana/pkg/infra/serverlock"
"github.com/grafana/grafana/pkg/infra/tracing" "github.com/grafana/grafana/pkg/infra/tracing"
"github.com/grafana/grafana/pkg/infra/usagestats" "github.com/grafana/grafana/pkg/infra/usagestats"
uss "github.com/grafana/grafana/pkg/infra/usagestats/service"
"github.com/grafana/grafana/pkg/login/social" "github.com/grafana/grafana/pkg/login/social"
"github.com/grafana/grafana/pkg/models" "github.com/grafana/grafana/pkg/models"
"github.com/grafana/grafana/pkg/plugins" "github.com/grafana/grafana/pkg/plugins"
@ -87,8 +88,8 @@ var wireBasicSet = wire.NewSet(
hooks.ProvideService, hooks.ProvideService,
kvstore.ProvideService, kvstore.ProvideService,
localcache.ProvideService, localcache.ProvideService,
usagestats.ProvideService, uss.ProvideService,
wire.Bind(new(usagestats.UsageStats), new(*usagestats.UsageStatsService)), wire.Bind(new(usagestats.Service), new(*uss.UsageStats)),
manager.ProvideService, manager.ProvideService,
wire.Bind(new(plugins.Manager), new(*manager.PluginManager)), wire.Bind(new(plugins.Manager), new(*manager.PluginManager)),
backendmanager.ProvideService, backendmanager.ProvideService,

@ -12,7 +12,7 @@ import (
"github.com/prometheus/client_golang/prometheus" "github.com/prometheus/client_golang/prometheus"
) )
func ProvideService(cfg *setting.Cfg, usageStats usagestats.UsageStats) *OSSAccessControlService { func ProvideService(cfg *setting.Cfg, usageStats usagestats.Service) *OSSAccessControlService {
s := &OSSAccessControlService{ s := &OSSAccessControlService{
Cfg: cfg, Cfg: cfg,
UsageStats: usageStats, UsageStats: usageStats,
@ -25,7 +25,7 @@ func ProvideService(cfg *setting.Cfg, usageStats usagestats.UsageStats) *OSSAcce
// OSSAccessControlService is the service implementing role based access control. // OSSAccessControlService is the service implementing role based access control.
type OSSAccessControlService struct { type OSSAccessControlService struct {
Cfg *setting.Cfg Cfg *setting.Cfg
UsageStats usagestats.UsageStats UsageStats usagestats.Service
Log log.Logger Log log.Logger
registrations accesscontrol.RegistrationList registrations accesscontrol.RegistrationList
} }

@ -54,7 +54,7 @@ func (usm *usageStatsMock) RegisterMetricsFunc(fn usagestats.MetricsFunc) {
usm.metricsFuncs = append(usm.metricsFuncs, fn) usm.metricsFuncs = append(usm.metricsFuncs, fn)
} }
func (usm *usageStatsMock) GetUsageReport(_ context.Context) (usagestats.UsageReport, error) { func (usm *usageStatsMock) GetUsageReport(_ context.Context) (usagestats.Report, error) {
all := make(map[string]interface{}) all := make(map[string]interface{})
for _, fn := range usm.metricsFuncs { for _, fn := range usm.metricsFuncs {
fnMetrics, err := fn() fnMetrics, err := fn()
@ -64,7 +64,7 @@ func (usm *usageStatsMock) GetUsageReport(_ context.Context) (usagestats.UsageRe
all[name] = value all[name] = value
} }
} }
return usagestats.UsageReport{Metrics: all}, nil return usagestats.Report{Metrics: all}, nil
} }
func (usm *usageStatsMock) ShouldBeReported(_ string) bool { func (usm *usageStatsMock) ShouldBeReported(_ string) bool {

Loading…
Cancel
Save