report_usage.go 2.3 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788
  1. package metrics
  2. import (
  3. "bytes"
  4. "encoding/json"
  5. "net/http"
  6. "strings"
  7. "time"
  8. "github.com/grafana/grafana/pkg/bus"
  9. "github.com/grafana/grafana/pkg/log"
  10. m "github.com/grafana/grafana/pkg/models"
  11. "github.com/grafana/grafana/pkg/plugins"
  12. "github.com/grafana/grafana/pkg/setting"
  13. )
  14. func StartUsageReportLoop() chan struct{} {
  15. M_Instance_Start.Inc(1)
  16. ticker := time.NewTicker(time.Hour * 24)
  17. for {
  18. select {
  19. case <-ticker.C:
  20. sendUsageStats()
  21. }
  22. }
  23. }
  24. func sendUsageStats() {
  25. log.Trace("Sending anonymous usage stats to stats.grafana.org")
  26. version := strings.Replace(setting.BuildVersion, ".", "_", -1)
  27. metrics := map[string]interface{}{}
  28. report := map[string]interface{}{
  29. "version": version,
  30. "metrics": metrics,
  31. }
  32. UsageStats.Each(func(name string, i interface{}) {
  33. switch metric := i.(type) {
  34. case Counter:
  35. if metric.Count() > 0 {
  36. metrics[name+".count"] = metric.Count()
  37. metric.Clear()
  38. }
  39. }
  40. })
  41. statsQuery := m.GetSystemStatsQuery{}
  42. if err := bus.Dispatch(&statsQuery); err != nil {
  43. log.Error(3, "Failed to get system stats", err)
  44. return
  45. }
  46. metrics["stats.dashboards.count"] = statsQuery.Result.DashboardCount
  47. metrics["stats.users.count"] = statsQuery.Result.UserCount
  48. metrics["stats.orgs.count"] = statsQuery.Result.OrgCount
  49. metrics["stats.playlist.count"] = statsQuery.Result.PlaylistCount
  50. metrics["stats.plugins.apps.count"] = len(plugins.Apps)
  51. metrics["stats.plugins.panels.count"] = len(plugins.Panels)
  52. metrics["stats.plugins.datasources.count"] = len(plugins.DataSources)
  53. dsStats := m.GetDataSourceStatsQuery{}
  54. if err := bus.Dispatch(&dsStats); err != nil {
  55. log.Error(3, "Failed to get datasource stats", err)
  56. return
  57. }
  58. // send counters for each data source
  59. // but ignore any custom data sources
  60. // as sending that name could be sensitive information
  61. dsOtherCount := 0
  62. for _, dsStat := range dsStats.Result {
  63. if m.IsKnownDataSourcePlugin(dsStat.Type) {
  64. metrics["stats.ds."+dsStat.Type+".count"] = dsStat.Count
  65. } else {
  66. dsOtherCount += dsStat.Count
  67. }
  68. }
  69. metrics["stats.ds.other.count"] = dsOtherCount
  70. out, _ := json.MarshalIndent(report, "", " ")
  71. data := bytes.NewBuffer(out)
  72. client := http.Client{Timeout: time.Duration(5 * time.Second)}
  73. go client.Post("https://stats.grafana.org/grafana-usage-report", "application/json", data)
  74. }