From 53153c82fc36329135b70e95ffda0e88f5822dbf Mon Sep 17 00:00:00 2001 From: Dan Cech Date: Tue, 15 Sep 2020 09:01:15 -0400 Subject: [PATCH] add method to get usage report (#27555) --- pkg/infra/usagestats/service.go | 2 +- pkg/infra/usagestats/usage_stats.go | 60 ++++++++++++++++-------- pkg/infra/usagestats/usage_stats_test.go | 8 ++-- 3 files changed, 45 insertions(+), 25 deletions(-) diff --git a/pkg/infra/usagestats/service.go b/pkg/infra/usagestats/service.go index 69001fe09f9..3f46358dcbc 100644 --- a/pkg/infra/usagestats/service.go +++ b/pkg/infra/usagestats/service.go @@ -50,7 +50,7 @@ func (uss *UsageStatsService) Run(ctx context.Context) error { for { select { case <-onceEveryDayTick.C: - uss.sendUsageStats(uss.oauthProviders) + uss.sendUsageStats() case <-everyMinuteTicker.C: uss.updateTotalStats() case <-ctx.Done(): diff --git a/pkg/infra/usagestats/usage_stats.go b/pkg/infra/usagestats/usage_stats.go index 57a4fe021db..2f9b759ec61 100644 --- a/pkg/infra/usagestats/usage_stats.go +++ b/pkg/infra/usagestats/usage_stats.go @@ -17,30 +17,35 @@ import ( var usageStatsURL = "https://stats.grafana.org/grafana-usage-report" -func (uss *UsageStatsService) sendUsageStats(oauthProviders map[string]bool) { - if !setting.ReportingEnabled { - return - } - - metricsLogger.Debug(fmt.Sprintf("Sending anonymous usage stats to %s", usageStatsURL)) +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"` +} +func (uss *UsageStatsService) GetUsageReport() (UsageReport, error) { version := strings.Replace(setting.BuildVersion, ".", "_", -1) metrics := map[string]interface{}{} - report := map[string]interface{}{ - "version": version, - "metrics": metrics, - "os": runtime.GOOS, - "arch": runtime.GOARCH, - "edition": getEdition(), - "hasValidLicense": uss.License.HasValidLicense(), - "packaging": setting.Packaging, + + report := UsageReport{ + Version: version, + Metrics: metrics, + Os: runtime.GOOS, + Arch: runtime.GOARCH, + Edition: getEdition(), + HasValidLicense: uss.License.HasValidLicense(), + Packaging: setting.Packaging, } statsQuery := models.GetSystemStatsQuery{} if err := uss.Bus.Dispatch(&statsQuery); err != nil { metricsLogger.Error("Failed to get system stats", "error", err) - return + return report, err } metrics["stats.dashboards.count"] = statsQuery.Result.Dashboards @@ -78,7 +83,7 @@ func (uss *UsageStatsService) sendUsageStats(oauthProviders map[string]bool) { dsStats := models.GetDataSourceStatsQuery{} if err := uss.Bus.Dispatch(&dsStats); err != nil { metricsLogger.Error("Failed to get datasource stats", "error", err) - return + return report, err } // send counters for each data source @@ -100,7 +105,7 @@ func (uss *UsageStatsService) sendUsageStats(oauthProviders map[string]bool) { alertingUsageStats, err := uss.AlertingUsageStats.QueryUsageStats() if err != nil { uss.log.Error("Failed to get alerting usage stats", "error", err) - return + return report, err } var addAlertingUsageStats = func(dsType string, usageCount int) { @@ -122,7 +127,7 @@ func (uss *UsageStatsService) sendUsageStats(oauthProviders map[string]bool) { dsAccessStats := models.GetDataSourceAccessStatsQuery{} if err := uss.Bus.Dispatch(&dsAccessStats); err != nil { metricsLogger.Error("Failed to get datasource access stats", "error", err) - return + return report, err } // send access counters for each data source @@ -152,7 +157,7 @@ func (uss *UsageStatsService) sendUsageStats(oauthProviders map[string]bool) { anStats := models.GetAlertNotifierUsageStatsQuery{} if err := uss.Bus.Dispatch(&anStats); err != nil { metricsLogger.Error("Failed to get alert notification stats", "error", err) - return + return report, err } for _, stats := range anStats.Result { @@ -166,7 +171,7 @@ func (uss *UsageStatsService) sendUsageStats(oauthProviders map[string]bool) { authTypes["ldap"] = setting.LDAPEnabled authTypes["auth_proxy"] = setting.AuthProxyEnabled - for provider, enabled := range oauthProviders { + for provider, enabled := range uss.oauthProviders { authTypes["oauth_"+provider] = enabled } @@ -178,6 +183,21 @@ func (uss *UsageStatsService) sendUsageStats(oauthProviders map[string]bool) { metrics["stats.auth_enabled."+authType+".count"] = enabledValue } + return report, nil +} + +func (uss *UsageStatsService) sendUsageStats() { + if !setting.ReportingEnabled { + return + } + + metricsLogger.Debug(fmt.Sprintf("Sending anonymous usage stats to %s", usageStatsURL)) + + report, err := uss.GetUsageReport() + if err != nil { + return + } + out, _ := json.MarshalIndent(report, "", " ") data := bytes.NewBuffer(out) diff --git a/pkg/infra/usagestats/usage_stats_test.go b/pkg/infra/usagestats/usage_stats_test.go index e47ae223980..f1e92e62ef7 100644 --- a/pkg/infra/usagestats/usage_stats_test.go +++ b/pkg/infra/usagestats/usage_stats_test.go @@ -162,7 +162,7 @@ func TestMetrics(t *testing.T) { })) usageStatsURL = ts.URL - oauthProviders := map[string]bool{ + uss.oauthProviders = map[string]bool{ "github": true, "gitlab": true, "azuread": true, @@ -171,11 +171,11 @@ func TestMetrics(t *testing.T) { "grafana_com": true, } - uss.sendUsageStats(oauthProviders) + uss.sendUsageStats() Convey("Given reporting not enabled and sending usage stats", func() { setting.ReportingEnabled = false - uss.sendUsageStats(oauthProviders) + uss.sendUsageStats() Convey("Should not gather stats or call http endpoint", func() { So(getSystemStatsQuery, ShouldBeNil) @@ -195,7 +195,7 @@ func TestMetrics(t *testing.T) { setting.Packaging = "deb" wg.Add(1) - uss.sendUsageStats(oauthProviders) + uss.sendUsageStats() Convey("Should gather stats and call http endpoint", func() { if waitTimeout(&wg, 2*time.Second) {