mirror of
https://github.com/grafana/grafana.git
synced 2025-02-16 18:34:52 -06:00
Usage Stats Updates (#39235)
* add randomly-generated anonymous id to usage reports * include uptime in stats * add last_sent tracking, remove metricsLogger
This commit is contained in:
parent
74beb9a64c
commit
f8ae71af5b
@ -6,6 +6,7 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/bus"
|
"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/log"
|
||||||
"github.com/grafana/grafana/pkg/login/social"
|
"github.com/grafana/grafana/pkg/login/social"
|
||||||
"github.com/grafana/grafana/pkg/plugins"
|
"github.com/grafana/grafana/pkg/plugins"
|
||||||
@ -15,8 +16,6 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/setting"
|
"github.com/grafana/grafana/pkg/setting"
|
||||||
)
|
)
|
||||||
|
|
||||||
var metricsLogger log.Logger = log.New("metrics")
|
|
||||||
|
|
||||||
type UsageStats interface {
|
type UsageStats interface {
|
||||||
GetUsageReport(context.Context) (UsageReport, error)
|
GetUsageReport(context.Context) (UsageReport, error)
|
||||||
RegisterMetricsFunc(MetricsFunc)
|
RegisterMetricsFunc(MetricsFunc)
|
||||||
@ -33,6 +32,7 @@ type UsageStatsService struct {
|
|||||||
PluginManager plugins.Manager
|
PluginManager plugins.Manager
|
||||||
SocialService social.Service
|
SocialService social.Service
|
||||||
grafanaLive *live.GrafanaLive
|
grafanaLive *live.GrafanaLive
|
||||||
|
kvStore *kvstore.NamespacedKVStore
|
||||||
|
|
||||||
log log.Logger
|
log log.Logger
|
||||||
|
|
||||||
@ -40,6 +40,7 @@ type UsageStatsService struct {
|
|||||||
externalMetrics []MetricsFunc
|
externalMetrics []MetricsFunc
|
||||||
concurrentUserStatsCache memoConcurrentUserStats
|
concurrentUserStatsCache memoConcurrentUserStats
|
||||||
liveStats liveUsageStats
|
liveStats liveUsageStats
|
||||||
|
startTime time.Time
|
||||||
}
|
}
|
||||||
|
|
||||||
type liveUsageStats struct {
|
type liveUsageStats struct {
|
||||||
@ -54,7 +55,8 @@ type liveUsageStats struct {
|
|||||||
|
|
||||||
func ProvideService(cfg *setting.Cfg, bus bus.Bus, sqlStore *sqlstore.SQLStore,
|
func ProvideService(cfg *setting.Cfg, bus bus.Bus, sqlStore *sqlstore.SQLStore,
|
||||||
alertingStats alerting.UsageStatsQuerier, pluginManager plugins.Manager,
|
alertingStats alerting.UsageStatsQuerier, pluginManager plugins.Manager,
|
||||||
socialService social.Service, grafanaLive *live.GrafanaLive) *UsageStatsService {
|
socialService social.Service, grafanaLive *live.GrafanaLive,
|
||||||
|
kvStore kvstore.KVStore) *UsageStatsService {
|
||||||
s := &UsageStatsService{
|
s := &UsageStatsService{
|
||||||
Cfg: cfg,
|
Cfg: cfg,
|
||||||
Bus: bus,
|
Bus: bus,
|
||||||
@ -63,7 +65,9 @@ func ProvideService(cfg *setting.Cfg, bus bus.Bus, sqlStore *sqlstore.SQLStore,
|
|||||||
oauthProviders: socialService.GetOAuthProviders(),
|
oauthProviders: socialService.GetOAuthProviders(),
|
||||||
PluginManager: pluginManager,
|
PluginManager: pluginManager,
|
||||||
grafanaLive: grafanaLive,
|
grafanaLive: grafanaLive,
|
||||||
|
kvStore: kvstore.WithNamespace(kvStore, 0, "infra.usagestats"),
|
||||||
log: log.New("infra.usagestats"),
|
log: log.New("infra.usagestats"),
|
||||||
|
startTime: time.Now(),
|
||||||
}
|
}
|
||||||
return s
|
return s
|
||||||
}
|
}
|
||||||
@ -71,7 +75,26 @@ func ProvideService(cfg *setting.Cfg, bus bus.Bus, sqlStore *sqlstore.SQLStore,
|
|||||||
func (uss *UsageStatsService) Run(ctx context.Context) error {
|
func (uss *UsageStatsService) Run(ctx context.Context) error {
|
||||||
uss.updateTotalStats()
|
uss.updateTotalStats()
|
||||||
|
|
||||||
sendReportTicker := time.NewTicker(time.Hour * 24)
|
// 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)
|
updateStatsTicker := time.NewTicker(time.Minute * 30)
|
||||||
|
|
||||||
defer sendReportTicker.Stop()
|
defer sendReportTicker.Stop()
|
||||||
@ -81,8 +104,19 @@ func (uss *UsageStatsService) Run(ctx context.Context) error {
|
|||||||
select {
|
select {
|
||||||
case <-sendReportTicker.C:
|
case <-sendReportTicker.C:
|
||||||
if err := uss.sendUsageStats(ctx); err != nil {
|
if err := uss.sendUsageStats(ctx); err != nil {
|
||||||
metricsLogger.Warn("Failed to send usage stats", "err", err)
|
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
|
// always reset live stats every report tick
|
||||||
uss.resetLiveStats()
|
uss.resetLiveStats()
|
||||||
case <-updateStatsTicker.C:
|
case <-updateStatsTicker.C:
|
||||||
|
@ -10,6 +10,7 @@ import (
|
|||||||
"strings"
|
"strings"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/google/uuid"
|
||||||
"github.com/grafana/grafana/pkg/infra/metrics"
|
"github.com/grafana/grafana/pkg/infra/metrics"
|
||||||
"github.com/grafana/grafana/pkg/models"
|
"github.com/grafana/grafana/pkg/models"
|
||||||
)
|
)
|
||||||
@ -24,6 +25,7 @@ type UsageReport struct {
|
|||||||
Edition string `json:"edition"`
|
Edition string `json:"edition"`
|
||||||
HasValidLicense bool `json:"hasValidLicense"`
|
HasValidLicense bool `json:"hasValidLicense"`
|
||||||
Packaging string `json:"packaging"`
|
Packaging string `json:"packaging"`
|
||||||
|
UsageStatsId string `json:"usageStatsId"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (uss *UsageStatsService) GetUsageReport(ctx context.Context) (UsageReport, error) {
|
func (uss *UsageStatsService) GetUsageReport(ctx context.Context) (UsageReport, error) {
|
||||||
@ -42,11 +44,12 @@ func (uss *UsageStatsService) GetUsageReport(ctx context.Context) (UsageReport,
|
|||||||
Arch: runtime.GOARCH,
|
Arch: runtime.GOARCH,
|
||||||
Edition: edition,
|
Edition: edition,
|
||||||
Packaging: uss.Cfg.Packaging,
|
Packaging: uss.Cfg.Packaging,
|
||||||
|
UsageStatsId: uss.GetUsageStatsId(ctx),
|
||||||
}
|
}
|
||||||
|
|
||||||
statsQuery := models.GetSystemStatsQuery{}
|
statsQuery := models.GetSystemStatsQuery{}
|
||||||
if err := uss.Bus.Dispatch(&statsQuery); err != nil {
|
if err := uss.Bus.Dispatch(&statsQuery); err != nil {
|
||||||
metricsLogger.Error("Failed to get system stats", "error", err)
|
uss.log.Error("Failed to get system stats", "error", err)
|
||||||
return report, err
|
return report, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -132,7 +135,7 @@ func (uss *UsageStatsService) GetUsageReport(ctx context.Context) (UsageReport,
|
|||||||
|
|
||||||
dsStats := models.GetDataSourceStatsQuery{}
|
dsStats := models.GetDataSourceStatsQuery{}
|
||||||
if err := uss.Bus.Dispatch(&dsStats); err != nil {
|
if err := uss.Bus.Dispatch(&dsStats); err != nil {
|
||||||
metricsLogger.Error("Failed to get datasource stats", "error", err)
|
uss.log.Error("Failed to get datasource stats", "error", err)
|
||||||
return report, err
|
return report, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,7 +154,7 @@ func (uss *UsageStatsService) GetUsageReport(ctx context.Context) (UsageReport,
|
|||||||
|
|
||||||
esDataSourcesQuery := models.GetDataSourcesByTypeQuery{Type: models.DS_ES}
|
esDataSourcesQuery := models.GetDataSourcesByTypeQuery{Type: models.DS_ES}
|
||||||
if err := uss.Bus.Dispatch(&esDataSourcesQuery); err != nil {
|
if err := uss.Bus.Dispatch(&esDataSourcesQuery); err != nil {
|
||||||
metricsLogger.Error("Failed to get elasticsearch json data", "error", err)
|
uss.log.Error("Failed to get elasticsearch json data", "error", err)
|
||||||
return report, err
|
return report, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -196,7 +199,7 @@ func (uss *UsageStatsService) GetUsageReport(ctx context.Context) (UsageReport,
|
|||||||
// fetch datasource access stats
|
// fetch datasource access stats
|
||||||
dsAccessStats := models.GetDataSourceAccessStatsQuery{}
|
dsAccessStats := models.GetDataSourceAccessStatsQuery{}
|
||||||
if err := uss.Bus.Dispatch(&dsAccessStats); err != nil {
|
if err := uss.Bus.Dispatch(&dsAccessStats); err != nil {
|
||||||
metricsLogger.Error("Failed to get datasource access stats", "error", err)
|
uss.log.Error("Failed to get datasource access stats", "error", err)
|
||||||
return report, err
|
return report, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -225,8 +228,8 @@ func (uss *UsageStatsService) GetUsageReport(ctx context.Context) (UsageReport,
|
|||||||
|
|
||||||
// get stats about alert notifier usage
|
// get stats about alert notifier usage
|
||||||
anStats := models.GetAlertNotifierUsageStatsQuery{}
|
anStats := models.GetAlertNotifierUsageStatsQuery{}
|
||||||
if err := uss.Bus.Dispatch(&anStats); err != nil {
|
if err := uss.Bus.DispatchCtx(ctx, &anStats); err != nil {
|
||||||
metricsLogger.Error("Failed to get alert notification stats", "error", err)
|
uss.log.Error("Failed to get alert notification stats", "error", err)
|
||||||
return report, err
|
return report, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -256,7 +259,7 @@ func (uss *UsageStatsService) GetUsageReport(ctx context.Context) (UsageReport,
|
|||||||
// Get concurrent users stats as histogram
|
// Get concurrent users stats as histogram
|
||||||
concurrentUsersStats, err := uss.GetConcurrentUsersStats(ctx)
|
concurrentUsersStats, err := uss.GetConcurrentUsersStats(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
metricsLogger.Error("Failed to get concurrent users stats", "error", err)
|
uss.log.Error("Failed to get concurrent users stats", "error", err)
|
||||||
return report, err
|
return report, err
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -268,6 +271,8 @@ func (uss *UsageStatsService) GetUsageReport(ctx context.Context) (UsageReport,
|
|||||||
metrics["stats.auth_token_per_user_le_15"] = concurrentUsersStats.BucketLE15
|
metrics["stats.auth_token_per_user_le_15"] = concurrentUsersStats.BucketLE15
|
||||||
metrics["stats.auth_token_per_user_le_inf"] = concurrentUsersStats.BucketLEInf
|
metrics["stats.auth_token_per_user_le_inf"] = concurrentUsersStats.BucketLEInf
|
||||||
|
|
||||||
|
metrics["stats.uptime"] = int64(time.Since(uss.startTime).Seconds())
|
||||||
|
|
||||||
return report, nil
|
return report, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -275,7 +280,7 @@ func (uss *UsageStatsService) registerExternalMetrics(metrics map[string]interfa
|
|||||||
for _, fn := range uss.externalMetrics {
|
for _, fn := range uss.externalMetrics {
|
||||||
fnMetrics, err := fn()
|
fnMetrics, err := fn()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
metricsLogger.Error("Failed to fetch external metrics", "error", err)
|
uss.log.Error("Failed to fetch external metrics", "error", err)
|
||||||
continue
|
continue
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -294,7 +299,7 @@ func (uss *UsageStatsService) sendUsageStats(ctx context.Context) error {
|
|||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
metricsLogger.Debug(fmt.Sprintf("Sending anonymous usage stats to %s", usageStatsURL))
|
uss.log.Debug(fmt.Sprintf("Sending anonymous usage stats to %s", usageStatsURL))
|
||||||
|
|
||||||
report, err := uss.GetUsageReport(ctx)
|
report, err := uss.GetUsageReport(ctx)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
@ -307,23 +312,23 @@ func (uss *UsageStatsService) sendUsageStats(ctx context.Context) error {
|
|||||||
}
|
}
|
||||||
|
|
||||||
data := bytes.NewBuffer(out)
|
data := bytes.NewBuffer(out)
|
||||||
sendUsageStats(data)
|
sendUsageStats(uss, data)
|
||||||
return nil
|
return nil
|
||||||
}
|
}
|
||||||
|
|
||||||
// sendUsageStats sends usage statistics.
|
// sendUsageStats sends usage statistics.
|
||||||
//
|
//
|
||||||
// Stubbable by tests.
|
// Stubbable by tests.
|
||||||
var sendUsageStats = func(data *bytes.Buffer) {
|
var sendUsageStats = func(uss *UsageStatsService, 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)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
metricsLogger.Error("Failed to send usage stats", "err", err)
|
uss.log.Error("Failed to send usage stats", "err", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
if err := resp.Body.Close(); err != nil {
|
if err := resp.Body.Close(); err != nil {
|
||||||
metricsLogger.Warn("Failed to close response body", "err", err)
|
uss.log.Warn("Failed to close response body", "err", err)
|
||||||
}
|
}
|
||||||
}()
|
}()
|
||||||
}
|
}
|
||||||
@ -363,7 +368,7 @@ func (uss *UsageStatsService) updateTotalStats() {
|
|||||||
|
|
||||||
statsQuery := models.GetSystemStatsQuery{}
|
statsQuery := models.GetSystemStatsQuery{}
|
||||||
if err := uss.Bus.Dispatch(&statsQuery); err != nil {
|
if err := uss.Bus.Dispatch(&statsQuery); err != nil {
|
||||||
metricsLogger.Error("Failed to get system stats", "error", err)
|
uss.log.Error("Failed to get system stats", "error", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -387,7 +392,7 @@ func (uss *UsageStatsService) updateTotalStats() {
|
|||||||
|
|
||||||
dsStats := models.GetDataSourceStatsQuery{}
|
dsStats := models.GetDataSourceStatsQuery{}
|
||||||
if err := uss.Bus.Dispatch(&dsStats); err != nil {
|
if err := uss.Bus.Dispatch(&dsStats); err != nil {
|
||||||
metricsLogger.Error("Failed to get datasource stats", "error", err)
|
uss.log.Error("Failed to get datasource stats", "error", err)
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -404,3 +409,31 @@ 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 {
|
||||||
|
anonId, ok, err := uss.kvStore.Get(ctx, "anonymous_id")
|
||||||
|
if err != nil {
|
||||||
|
uss.log.Error("Failed to get usage stats id", "error", err)
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
if ok {
|
||||||
|
return anonId
|
||||||
|
}
|
||||||
|
|
||||||
|
newId, err := uuid.NewRandom()
|
||||||
|
if err != nil {
|
||||||
|
uss.log.Error("Failed to generate usage stats id", "error", err)
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
anonId = newId.String()
|
||||||
|
|
||||||
|
err = uss.kvStore.Set(ctx, "anonymous_id", anonId)
|
||||||
|
if err != nil {
|
||||||
|
uss.log.Error("Failed to store usage stats id", "error", err)
|
||||||
|
return ""
|
||||||
|
}
|
||||||
|
|
||||||
|
return anonId
|
||||||
|
}
|
||||||
|
@ -9,6 +9,8 @@ import (
|
|||||||
"time"
|
"time"
|
||||||
|
|
||||||
"github.com/grafana/grafana/pkg/bus"
|
"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/services/sqlstore"
|
"github.com/grafana/grafana/pkg/services/sqlstore"
|
||||||
"github.com/grafana/grafana/pkg/util"
|
"github.com/grafana/grafana/pkg/util"
|
||||||
"github.com/stretchr/testify/assert"
|
"github.com/stretchr/testify/assert"
|
||||||
@ -20,6 +22,8 @@ func TestUsageStatsService_GetConcurrentUsersStats(t *testing.T) {
|
|||||||
uss := &UsageStatsService{
|
uss := &UsageStatsService{
|
||||||
Bus: bus.New(),
|
Bus: bus.New(),
|
||||||
SQLStore: sqlStore,
|
SQLStore: sqlStore,
|
||||||
|
kvStore: kvstore.WithNamespace(kvstore.ProvideService(sqlStore), 0, "infra.usagestats"),
|
||||||
|
log: log.New("infra.usagestats"),
|
||||||
}
|
}
|
||||||
|
|
||||||
createConcurrentTokens(t, sqlStore)
|
createConcurrentTokens(t, sqlStore)
|
||||||
|
@ -14,6 +14,8 @@ import (
|
|||||||
"github.com/grafana/grafana/pkg/api/routing"
|
"github.com/grafana/grafana/pkg/api/routing"
|
||||||
"github.com/grafana/grafana/pkg/bus"
|
"github.com/grafana/grafana/pkg/bus"
|
||||||
"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/log"
|
||||||
"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"
|
||||||
@ -219,7 +221,7 @@ func TestMetrics(t *testing.T) {
|
|||||||
sendUsageStats = origSendUsageStats
|
sendUsageStats = origSendUsageStats
|
||||||
})
|
})
|
||||||
statsSent := false
|
statsSent := false
|
||||||
sendUsageStats = func(*bytes.Buffer) {
|
sendUsageStats = func(uss *UsageStatsService, b *bytes.Buffer) {
|
||||||
statsSent = true
|
statsSent = true
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -307,6 +309,10 @@ func TestMetrics(t *testing.T) {
|
|||||||
assert.Equal(t, runtime.GOOS, j.Get("os").MustString())
|
assert.Equal(t, runtime.GOOS, j.Get("os").MustString())
|
||||||
assert.Equal(t, runtime.GOARCH, j.Get("arch").MustString())
|
assert.Equal(t, runtime.GOARCH, j.Get("arch").MustString())
|
||||||
|
|
||||||
|
usageId := uss.GetUsageStatsId(context.Background())
|
||||||
|
assert.NotEmpty(t, usageId)
|
||||||
|
assert.Equal(t, usageId, j.Get("usageStatsId").MustString())
|
||||||
|
|
||||||
metrics := j.Get("metrics")
|
metrics := j.Get("metrics")
|
||||||
assert.Equal(t, getSystemStatsQuery.Result.Dashboards, metrics.Get("stats.dashboards.count").MustInt64())
|
assert.Equal(t, getSystemStatsQuery.Result.Dashboards, metrics.Get("stats.dashboards.count").MustInt64())
|
||||||
assert.Equal(t, getSystemStatsQuery.Result.Users, metrics.Get("stats.users.count").MustInt64())
|
assert.Equal(t, getSystemStatsQuery.Result.Users, metrics.Get("stats.users.count").MustInt64())
|
||||||
@ -393,6 +399,9 @@ func TestMetrics(t *testing.T) {
|
|||||||
assert.Equal(t, 4, metrics.Get("stats.auth_token_per_user_le_12").MustInt())
|
assert.Equal(t, 4, metrics.Get("stats.auth_token_per_user_le_12").MustInt())
|
||||||
assert.Equal(t, 5, metrics.Get("stats.auth_token_per_user_le_15").MustInt())
|
assert.Equal(t, 5, metrics.Get("stats.auth_token_per_user_le_15").MustInt())
|
||||||
assert.Equal(t, 6, metrics.Get("stats.auth_token_per_user_le_inf").MustInt())
|
assert.Equal(t, 6, metrics.Get("stats.auth_token_per_user_le_inf").MustInt())
|
||||||
|
|
||||||
|
assert.LessOrEqual(t, 60, metrics.Get("stats.uptime").MustInt())
|
||||||
|
assert.Greater(t, 70, metrics.Get("stats.uptime").MustInt())
|
||||||
})
|
})
|
||||||
})
|
})
|
||||||
|
|
||||||
@ -629,14 +638,19 @@ type httpResp struct {
|
|||||||
func createService(t *testing.T, cfg setting.Cfg) *UsageStatsService {
|
func createService(t *testing.T, cfg setting.Cfg) *UsageStatsService {
|
||||||
t.Helper()
|
t.Helper()
|
||||||
|
|
||||||
|
sqlStore := sqlstore.InitTestDB(t)
|
||||||
|
|
||||||
return &UsageStatsService{
|
return &UsageStatsService{
|
||||||
Bus: bus.New(),
|
Bus: bus.New(),
|
||||||
Cfg: &cfg,
|
Cfg: &cfg,
|
||||||
SQLStore: sqlstore.InitTestDB(t),
|
SQLStore: sqlStore,
|
||||||
AlertingUsageStats: &alertingUsageMock{},
|
AlertingUsageStats: &alertingUsageMock{},
|
||||||
externalMetrics: make([]MetricsFunc, 0),
|
externalMetrics: make([]MetricsFunc, 0),
|
||||||
PluginManager: &fakePluginManager{},
|
PluginManager: &fakePluginManager{},
|
||||||
grafanaLive: newTestLive(t),
|
grafanaLive: newTestLive(t),
|
||||||
|
kvStore: kvstore.WithNamespace(kvstore.ProvideService(sqlStore), 0, "infra.usagestats"),
|
||||||
|
log: log.New("infra.usagestats"),
|
||||||
|
startTime: time.Now().Add(-1 * time.Minute),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user