diff --git a/pkg/metrics/report_usage.go b/pkg/metrics/report_usage.go index c8848fb5371..065c83d3b8f 100644 --- a/pkg/metrics/report_usage.go +++ b/pkg/metrics/report_usage.go @@ -36,12 +36,6 @@ func sendUsageStats() { "metrics": metrics, } - statsQuery := m.GetSystemStatsQuery{} - if err := bus.Dispatch(&statsQuery); err != nil { - log.Error(3, "Failed to get system stats", err) - return - } - UsageStats.Each(func(name string, i interface{}) { switch metric := i.(type) { case Counter: @@ -52,11 +46,36 @@ func sendUsageStats() { } }) + statsQuery := m.GetSystemStatsQuery{} + if err := bus.Dispatch(&statsQuery); err != nil { + log.Error(3, "Failed to get system stats", err) + return + } + metrics["stats.dashboards.count"] = statsQuery.Result.DashboardCount metrics["stats.users.count"] = statsQuery.Result.UserCount metrics["stats.orgs.count"] = statsQuery.Result.OrgCount - out, _ := json.Marshal(report) + dsStats := m.GetDataSourceStatsQuery{} + if err := bus.Dispatch(&dsStats); err != nil { + log.Error(3, "Failed to get datasource stats", err) + return + } + + // send counters for each data source + // but ignore any custom data sources + // as sending that name could be sensitive information + dsOtherCount := 0 + for _, dsStat := range dsStats.Result { + if m.IsStandardDataSource(dsStat.Type) { + metrics["stats.ds."+dsStat.Type+".count"] = dsStat.Count + } else { + dsOtherCount += dsStat.Count + } + } + metrics["stats.ds.other.count"] = dsOtherCount + + out, _ := json.MarshalIndent(report, "", " ") data := bytes.NewBuffer(out) client := http.Client{Timeout: time.Duration(5 * time.Second)} diff --git a/pkg/models/datasource.go b/pkg/models/datasource.go index 75e2134c09f..35b623ce30a 100644 --- a/pkg/models/datasource.go +++ b/pkg/models/datasource.go @@ -12,6 +12,8 @@ const ( DS_ES = "elasticsearch" DS_OPENTSDB = "opentsdb" DS_CLOUDWATCH = "cloudwatch" + DS_KAIROSDB = "kairosdb" + DS_PROMETHEUS = "prometheus" DS_ACCESS_DIRECT = "direct" DS_ACCESS_PROXY = "proxy" ) @@ -45,6 +47,25 @@ type DataSource struct { Updated time.Time } +func IsStandardDataSource(dsType string) bool { + switch dsType { + case DS_ES: + return true + case DS_INFLUXDB: + return true + case DS_OPENTSDB: + return true + case DS_CLOUDWATCH: + return true + case DS_PROMETHEUS: + return true + case DS_GRAPHITE: + return true + default: + return false + } +} + // ---------------------- // COMMANDS diff --git a/pkg/models/stats.go b/pkg/models/stats.go index 0d83882e666..6a060137ac7 100644 --- a/pkg/models/stats.go +++ b/pkg/models/stats.go @@ -6,6 +6,15 @@ type SystemStats struct { OrgCount int } +type DataSourceStats struct { + Count int + Type string +} + type GetSystemStatsQuery struct { Result *SystemStats } + +type GetDataSourceStatsQuery struct { + Result []*DataSourceStats +} diff --git a/pkg/services/sqlstore/stats.go b/pkg/services/sqlstore/stats.go index 7995dd43f38..044aa185f19 100644 --- a/pkg/services/sqlstore/stats.go +++ b/pkg/services/sqlstore/stats.go @@ -7,6 +7,18 @@ import ( func init() { bus.AddHandler("sql", GetSystemStats) + bus.AddHandler("sql", GetDataSourceStats) +} + +func GetDataSourceStats(query *m.GetDataSourceStatsQuery) error { + var rawSql = `SELECT COUNT(*) as count, type FROM data_source GROUP BY type` + query.Result = make([]*m.DataSourceStats, 0) + err := x.Sql(rawSql).Find(&query.Result) + if err != nil { + return err + } + + return err } func GetSystemStats(query *m.GetSystemStatsQuery) error {