mirror of
https://github.com/grafana/grafana.git
synced 2025-02-25 18:55:37 -06:00
Usage Stats: Split domain & service packages (#39488)
This commit is contained in:
parent
b31316753a
commit
a680162792
@ -22,7 +22,6 @@ import (
|
||||
"github.com/grafana/grafana/pkg/infra/metrics"
|
||||
"github.com/grafana/grafana/pkg/infra/remotecache"
|
||||
"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/middleware"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
@ -68,7 +67,6 @@ type HTTPServer struct {
|
||||
httpSrv *http.Server
|
||||
middlewares []macaron.Handler
|
||||
|
||||
UsageStatsService usagestats.UsageStats
|
||||
PluginContextProvider *plugincontext.Provider
|
||||
RouteRegister routing.RouteRegister
|
||||
Bus bus.Bus
|
||||
@ -118,8 +116,7 @@ type ServerOptions struct {
|
||||
func ProvideHTTPServer(opts ServerOptions, cfg *setting.Cfg, routeRegister routing.RouteRegister, bus bus.Bus,
|
||||
renderService rendering.Service, licensing models.Licensing, hooksService *hooks.HooksService,
|
||||
cacheService *localcache.CacheService, sqlStore *sqlstore.SQLStore,
|
||||
dataService *tsdb.Service, alertEngine *alerting.AlertEngine,
|
||||
usageStatsService *usagestats.UsageStatsService, pluginRequestValidator models.PluginRequestValidator,
|
||||
dataService *tsdb.Service, alertEngine *alerting.AlertEngine, pluginRequestValidator models.PluginRequestValidator,
|
||||
pluginManager plugins.Manager, backendPM backendplugin.Manager, settingsProvider setting.Provider,
|
||||
dataSourceCache datasources.CacheService, userTokenService models.UserTokenService,
|
||||
cleanUpService *cleanup.CleanUpService, shortURLService shorturls.Service,
|
||||
@ -148,7 +145,6 @@ func ProvideHTTPServer(opts ServerOptions, cfg *setting.Cfg, routeRegister routi
|
||||
SQLStore: sqlStore,
|
||||
DataService: dataService,
|
||||
AlertEngine: alertEngine,
|
||||
UsageStatsService: usageStatsService,
|
||||
PluginRequestValidator: pluginRequestValidator,
|
||||
PluginManager: pluginManager,
|
||||
BackendPluginManager: backendPM,
|
||||
|
@ -2,168 +2,23 @@ package usagestats
|
||||
|
||||
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/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 {
|
||||
GetUsageReport(context.Context) (UsageReport, error)
|
||||
RegisterMetricsFunc(MetricsFunc)
|
||||
ShouldBeReported(string) bool
|
||||
type Report struct {
|
||||
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"`
|
||||
}
|
||||
|
||||
type MetricsFunc func() (map[string]interface{}, error)
|
||||
|
||||
type UsageStatsService 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 []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
|
||||
type Service interface {
|
||||
GetUsageReport(context.Context) (Report, error)
|
||||
RegisterMetricsFunc(MetricsFunc)
|
||||
ShouldBeReported(string) bool
|
||||
}
|
||||
|
163
pkg/infra/usagestats/service/service.go
Normal file
163
pkg/infra/usagestats/service/service.go
Normal file
@ -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 {
|
||||
BucketLE3 int32 `xorm:"bucket_le_3"`
|
@ -1,4 +1,4 @@
|
||||
package usagestats
|
||||
package service
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
@ -12,23 +12,13 @@ import (
|
||||
|
||||
"github.com/google/uuid"
|
||||
"github.com/grafana/grafana/pkg/infra/metrics"
|
||||
"github.com/grafana/grafana/pkg/infra/usagestats"
|
||||
"github.com/grafana/grafana/pkg/models"
|
||||
)
|
||||
|
||||
var usageStatsURL = "https://stats.grafana.org/grafana-usage-report"
|
||||
|
||||
type UsageReport struct {
|
||||
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) {
|
||||
func (uss *UsageStats) GetUsageReport(ctx context.Context) (usagestats.Report, error) {
|
||||
version := strings.ReplaceAll(uss.Cfg.BuildVersion, ".", "_")
|
||||
|
||||
metrics := map[string]interface{}{}
|
||||
@ -37,7 +27,7 @@ func (uss *UsageStatsService) GetUsageReport(ctx context.Context) (UsageReport,
|
||||
if uss.Cfg.IsEnterprise {
|
||||
edition = "enterprise"
|
||||
}
|
||||
report := UsageReport{
|
||||
report := usagestats.Report{
|
||||
Version: version,
|
||||
Metrics: metrics,
|
||||
Os: runtime.GOOS,
|
||||
@ -276,7 +266,7 @@ func (uss *UsageStatsService) GetUsageReport(ctx context.Context) (UsageReport,
|
||||
return report, nil
|
||||
}
|
||||
|
||||
func (uss *UsageStatsService) registerExternalMetrics(metrics map[string]interface{}) {
|
||||
func (uss *UsageStats) registerExternalMetrics(metrics map[string]interface{}) {
|
||||
for _, fn := range uss.externalMetrics {
|
||||
fnMetrics, err := fn()
|
||||
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)
|
||||
}
|
||||
|
||||
func (uss *UsageStatsService) sendUsageStats(ctx context.Context) error {
|
||||
func (uss *UsageStats) sendUsageStats(ctx context.Context) error {
|
||||
if !uss.Cfg.ReportingEnabled {
|
||||
return nil
|
||||
}
|
||||
@ -319,7 +309,7 @@ func (uss *UsageStatsService) sendUsageStats(ctx context.Context) error {
|
||||
// sendUsageStats sends usage statistics.
|
||||
//
|
||||
// Stubbable by tests.
|
||||
var sendUsageStats = func(uss *UsageStatsService, data *bytes.Buffer) {
|
||||
var sendUsageStats = func(uss *UsageStats, data *bytes.Buffer) {
|
||||
go func() {
|
||||
client := http.Client{Timeout: 5 * time.Second}
|
||||
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()
|
||||
|
||||
uss.liveStats.sampleCount++
|
||||
@ -357,11 +347,11 @@ func (uss *UsageStatsService) sampleLiveStats() {
|
||||
}
|
||||
}
|
||||
|
||||
func (uss *UsageStatsService) resetLiveStats() {
|
||||
func (uss *UsageStats) resetLiveStats() {
|
||||
uss.liveStats = liveUsageStats{}
|
||||
}
|
||||
|
||||
func (uss *UsageStatsService) updateTotalStats() {
|
||||
func (uss *UsageStats) updateTotalStats() {
|
||||
if !uss.Cfg.MetricsEndpointEnabled || uss.Cfg.MetricsEndpointDisableTotalStats {
|
||||
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)
|
||||
if ds == nil {
|
||||
return false
|
||||
@ -410,7 +400,7 @@ func (uss *UsageStatsService) ShouldBeReported(dsType string) bool {
|
||||
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")
|
||||
if err != nil {
|
||||
uss.log.Error("Failed to get usage stats id", "error", err)
|
@ -1,4 +1,4 @@
|
||||
package usagestats
|
||||
package service
|
||||
|
||||
import (
|
||||
"context"
|
||||
@ -19,7 +19,7 @@ import (
|
||||
|
||||
func TestUsageStatsService_GetConcurrentUsersStats(t *testing.T) {
|
||||
sqlStore := sqlstore.InitTestDB(t)
|
||||
uss := &UsageStatsService{
|
||||
uss := &UsageStats{
|
||||
Bus: bus.New(),
|
||||
SQLStore: sqlStore,
|
||||
kvStore: kvstore.WithNamespace(kvstore.ProvideService(sqlStore), 0, "infra.usagestats"),
|
@ -1,4 +1,4 @@
|
||||
package usagestats
|
||||
package service
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
@ -16,6 +16,7 @@ import (
|
||||
"github.com/grafana/grafana/pkg/components/simplejson"
|
||||
"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/models"
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
"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
|
||||
func Test_InterfaceContractValidity(t *testing.T) {
|
||||
newUsageStats := func() UsageStats {
|
||||
return &UsageStatsService{}
|
||||
newUsageStats := func() usagestats.Service {
|
||||
return &UsageStats{}
|
||||
}
|
||||
v, ok := newUsageStats().(*UsageStatsService)
|
||||
v, ok := newUsageStats().(*UsageStats)
|
||||
|
||||
assert.NotNil(t, v)
|
||||
assert.True(t, ok)
|
||||
@ -221,7 +222,7 @@ func TestMetrics(t *testing.T) {
|
||||
sendUsageStats = origSendUsageStats
|
||||
})
|
||||
statsSent := false
|
||||
sendUsageStats = func(uss *UsageStatsService, b *bytes.Buffer) {
|
||||
sendUsageStats = func(uss *UsageStats, b *bytes.Buffer) {
|
||||
statsSent = true
|
||||
}
|
||||
|
||||
@ -592,7 +593,7 @@ func (pm *fakePluginManager) PanelCount() int {
|
||||
return len(pm.panels)
|
||||
}
|
||||
|
||||
func setupSomeDataSourcePlugins(t *testing.T, uss *UsageStatsService) {
|
||||
func setupSomeDataSourcePlugins(t *testing.T, uss *UsageStats) {
|
||||
t.Helper()
|
||||
|
||||
uss.PluginManager = &fakePluginManager{
|
||||
@ -635,17 +636,17 @@ type httpResp struct {
|
||||
err error
|
||||
}
|
||||
|
||||
func createService(t *testing.T, cfg setting.Cfg) *UsageStatsService {
|
||||
func createService(t *testing.T, cfg setting.Cfg) *UsageStats {
|
||||
t.Helper()
|
||||
|
||||
sqlStore := sqlstore.InitTestDB(t)
|
||||
|
||||
return &UsageStatsService{
|
||||
return &UsageStats{
|
||||
Bus: bus.New(),
|
||||
Cfg: &cfg,
|
||||
SQLStore: sqlStore,
|
||||
AlertingUsageStats: &alertingUsageMock{},
|
||||
externalMetrics: make([]MetricsFunc, 0),
|
||||
externalMetrics: make([]usagestats.MetricsFunc, 0),
|
||||
PluginManager: &fakePluginManager{},
|
||||
grafanaLive: newTestLive(t),
|
||||
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/remotecache"
|
||||
"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"
|
||||
backendmanager "github.com/grafana/grafana/pkg/plugins/backendplugin/manager"
|
||||
"github.com/grafana/grafana/pkg/plugins/manager"
|
||||
@ -42,7 +42,7 @@ func ProvideBackgroundServiceRegistry(
|
||||
rendering *rendering.RenderingService, tokenService models.UserTokenBackgroundService,
|
||||
provisioning *provisioning.ProvisioningServiceImpl, alerting *alerting.AlertEngine, pm *manager.PluginManager,
|
||||
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?
|
||||
_ *azuremonitor.Service, _ *cloudwatch.CloudWatchService, _ *elasticsearch.Service, _ *graphite.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/tracing"
|
||||
"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/models"
|
||||
"github.com/grafana/grafana/pkg/plugins"
|
||||
@ -87,8 +88,8 @@ var wireBasicSet = wire.NewSet(
|
||||
hooks.ProvideService,
|
||||
kvstore.ProvideService,
|
||||
localcache.ProvideService,
|
||||
usagestats.ProvideService,
|
||||
wire.Bind(new(usagestats.UsageStats), new(*usagestats.UsageStatsService)),
|
||||
uss.ProvideService,
|
||||
wire.Bind(new(usagestats.Service), new(*uss.UsageStats)),
|
||||
manager.ProvideService,
|
||||
wire.Bind(new(plugins.Manager), new(*manager.PluginManager)),
|
||||
backendmanager.ProvideService,
|
||||
|
@ -12,7 +12,7 @@ import (
|
||||
"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{
|
||||
Cfg: cfg,
|
||||
UsageStats: usageStats,
|
||||
@ -25,7 +25,7 @@ func ProvideService(cfg *setting.Cfg, usageStats usagestats.UsageStats) *OSSAcce
|
||||
// OSSAccessControlService is the service implementing role based access control.
|
||||
type OSSAccessControlService struct {
|
||||
Cfg *setting.Cfg
|
||||
UsageStats usagestats.UsageStats
|
||||
UsageStats usagestats.Service
|
||||
Log log.Logger
|
||||
registrations accesscontrol.RegistrationList
|
||||
}
|
||||
|
@ -54,7 +54,7 @@ func (usm *usageStatsMock) RegisterMetricsFunc(fn usagestats.MetricsFunc) {
|
||||
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{})
|
||||
for _, fn := range usm.metricsFuncs {
|
||||
fnMetrics, err := fn()
|
||||
@ -64,7 +64,7 @@ func (usm *usageStatsMock) GetUsageReport(_ context.Context) (usagestats.UsageRe
|
||||
all[name] = value
|
||||
}
|
||||
}
|
||||
return usagestats.UsageReport{Metrics: all}, nil
|
||||
return usagestats.Report{Metrics: all}, nil
|
||||
}
|
||||
|
||||
func (usm *usageStatsMock) ShouldBeReported(_ string) bool {
|
||||
|
Loading…
Reference in New Issue
Block a user