2015-03-22 14:14:00 -05:00
|
|
|
package metrics
|
|
|
|
|
|
|
|
import (
|
|
|
|
"bytes"
|
|
|
|
"encoding/json"
|
|
|
|
"net/http"
|
2015-03-22 15:13:16 -05:00
|
|
|
"strings"
|
2015-03-22 14:14:00 -05:00
|
|
|
"time"
|
|
|
|
|
2015-03-25 03:04:38 -05:00
|
|
|
"github.com/grafana/grafana/pkg/bus"
|
2015-03-22 14:45:13 -05:00
|
|
|
"github.com/grafana/grafana/pkg/log"
|
2015-03-25 03:04:38 -05:00
|
|
|
m "github.com/grafana/grafana/pkg/models"
|
2016-04-10 17:36:54 -05:00
|
|
|
"github.com/grafana/grafana/pkg/plugins"
|
2015-03-22 14:14:00 -05:00
|
|
|
"github.com/grafana/grafana/pkg/setting"
|
|
|
|
)
|
|
|
|
|
2016-06-07 02:29:47 -05:00
|
|
|
var metricsLogger log.Logger = log.New("metrics")
|
|
|
|
|
2016-06-02 07:32:17 -05:00
|
|
|
func Init() {
|
2016-06-03 05:50:51 -05:00
|
|
|
settings := readSettings()
|
|
|
|
initMetricVars(settings)
|
|
|
|
go instrumentationLoop(settings)
|
2016-06-01 06:31:11 -05:00
|
|
|
}
|
|
|
|
|
2016-06-03 05:50:51 -05:00
|
|
|
func instrumentationLoop(settings *MetricSettings) chan struct{} {
|
2015-03-22 14:14:00 -05:00
|
|
|
M_Instance_Start.Inc(1)
|
|
|
|
|
2016-06-02 07:32:17 -05:00
|
|
|
onceEveryDayTick := time.NewTicker(time.Hour * 24)
|
|
|
|
secondTicker := time.NewTicker(time.Second * time.Duration(settings.IntervalSeconds))
|
2016-06-01 06:31:11 -05:00
|
|
|
|
2015-03-22 14:14:00 -05:00
|
|
|
for {
|
|
|
|
select {
|
2016-06-02 07:32:17 -05:00
|
|
|
case <-onceEveryDayTick.C:
|
2015-03-22 14:14:00 -05:00
|
|
|
sendUsageStats()
|
2016-06-01 06:31:11 -05:00
|
|
|
case <-secondTicker.C:
|
2016-06-02 07:32:17 -05:00
|
|
|
if settings.Enabled {
|
|
|
|
sendMetrics(settings)
|
|
|
|
}
|
2015-03-22 14:14:00 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2016-06-02 07:32:17 -05:00
|
|
|
func sendMetrics(settings *MetricSettings) {
|
2016-06-03 11:38:19 -05:00
|
|
|
if len(settings.Publishers) == 0 {
|
|
|
|
return
|
|
|
|
}
|
2016-06-01 06:31:11 -05:00
|
|
|
|
2016-06-03 11:38:19 -05:00
|
|
|
metrics := MetricStats.GetSnapshots()
|
2016-06-02 07:32:17 -05:00
|
|
|
for _, publisher := range settings.Publishers {
|
|
|
|
publisher.Publish(metrics)
|
2016-06-01 06:31:11 -05:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-03-22 14:14:00 -05:00
|
|
|
func sendUsageStats() {
|
2016-06-02 07:32:17 -05:00
|
|
|
if !setting.ReportingEnabled {
|
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2016-06-07 02:29:47 -05:00
|
|
|
metricsLogger.Debug("Sending anonymous usage stats to stats.grafana.org")
|
2015-03-22 14:45:13 -05:00
|
|
|
|
2015-03-22 15:13:16 -05:00
|
|
|
version := strings.Replace(setting.BuildVersion, ".", "_", -1)
|
|
|
|
|
2015-03-22 14:14:00 -05:00
|
|
|
metrics := map[string]interface{}{}
|
|
|
|
report := map[string]interface{}{
|
2015-03-22 15:13:16 -05:00
|
|
|
"version": version,
|
2015-03-22 14:14:00 -05:00
|
|
|
"metrics": metrics,
|
|
|
|
}
|
|
|
|
|
2015-09-29 06:47:56 -05:00
|
|
|
statsQuery := m.GetSystemStatsQuery{}
|
|
|
|
if err := bus.Dispatch(&statsQuery); err != nil {
|
2016-06-07 02:29:47 -05:00
|
|
|
metricsLogger.Error("Failed to get system stats", "error", err)
|
2015-09-29 06:47:56 -05:00
|
|
|
return
|
|
|
|
}
|
|
|
|
|
2015-03-25 03:04:38 -05:00
|
|
|
metrics["stats.dashboards.count"] = statsQuery.Result.DashboardCount
|
|
|
|
metrics["stats.users.count"] = statsQuery.Result.UserCount
|
|
|
|
metrics["stats.orgs.count"] = statsQuery.Result.OrgCount
|
2016-01-25 14:39:04 -06:00
|
|
|
metrics["stats.playlist.count"] = statsQuery.Result.PlaylistCount
|
2016-04-10 17:36:54 -05:00
|
|
|
metrics["stats.plugins.apps.count"] = len(plugins.Apps)
|
|
|
|
metrics["stats.plugins.panels.count"] = len(plugins.Panels)
|
|
|
|
metrics["stats.plugins.datasources.count"] = len(plugins.DataSources)
|
2015-03-22 14:14:00 -05:00
|
|
|
|
2015-09-29 06:47:56 -05:00
|
|
|
dsStats := m.GetDataSourceStatsQuery{}
|
|
|
|
if err := bus.Dispatch(&dsStats); err != nil {
|
2016-06-07 02:29:47 -05:00
|
|
|
metricsLogger.Error("Failed to get datasource stats", "error", err)
|
2015-09-29 06:47:56 -05:00
|
|
|
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 {
|
2015-10-26 10:37:45 -05:00
|
|
|
if m.IsKnownDataSourcePlugin(dsStat.Type) {
|
2015-09-29 06:47:56 -05:00
|
|
|
metrics["stats.ds."+dsStat.Type+".count"] = dsStat.Count
|
|
|
|
} else {
|
|
|
|
dsOtherCount += dsStat.Count
|
|
|
|
}
|
|
|
|
}
|
|
|
|
metrics["stats.ds.other.count"] = dsOtherCount
|
|
|
|
|
|
|
|
out, _ := json.MarshalIndent(report, "", " ")
|
2015-03-22 14:14:00 -05:00
|
|
|
data := bytes.NewBuffer(out)
|
|
|
|
|
|
|
|
client := http.Client{Timeout: time.Duration(5 * time.Second)}
|
2015-03-22 14:24:35 -05:00
|
|
|
go client.Post("https://stats.grafana.org/grafana-usage-report", "application/json", data)
|
2015-03-22 14:14:00 -05:00
|
|
|
}
|