|
|
@@ -1,17 +1,8 @@
|
|
|
package metrics
|
|
|
|
|
|
import (
|
|
|
- "bytes"
|
|
|
- "encoding/json"
|
|
|
- "net/http"
|
|
|
"runtime"
|
|
|
- "strings"
|
|
|
- "time"
|
|
|
|
|
|
- "github.com/grafana/grafana/pkg/bus"
|
|
|
- "github.com/grafana/grafana/pkg/models"
|
|
|
- "github.com/grafana/grafana/pkg/plugins"
|
|
|
- "github.com/grafana/grafana/pkg/setting"
|
|
|
"github.com/prometheus/client_golang/prometheus"
|
|
|
)
|
|
|
|
|
|
@@ -68,23 +59,6 @@ var (
|
|
|
grafanaBuildVersion *prometheus.GaugeVec
|
|
|
)
|
|
|
|
|
|
-func newCounterVecStartingAtZero(opts prometheus.CounterOpts, labels []string, labelValues ...string) *prometheus.CounterVec {
|
|
|
- counter := prometheus.NewCounterVec(opts, labels)
|
|
|
-
|
|
|
- for _, label := range labelValues {
|
|
|
- counter.WithLabelValues(label).Add(0)
|
|
|
- }
|
|
|
-
|
|
|
- return counter
|
|
|
-}
|
|
|
-
|
|
|
-func newCounterStartingAtZero(opts prometheus.CounterOpts, labelValues ...string) prometheus.Counter {
|
|
|
- counter := prometheus.NewCounter(opts)
|
|
|
- counter.Add(0)
|
|
|
-
|
|
|
- return counter
|
|
|
-}
|
|
|
-
|
|
|
func init() {
|
|
|
M_Instance_Start = prometheus.NewCounter(prometheus.CounterOpts{
|
|
|
Name: "instance_start_total",
|
|
|
@@ -362,154 +336,19 @@ func initMetricVars() {
|
|
|
|
|
|
}
|
|
|
|
|
|
-func updateTotalStats() {
|
|
|
- statsQuery := models.GetSystemStatsQuery{}
|
|
|
- if err := bus.Dispatch(&statsQuery); err != nil {
|
|
|
- metricsLogger.Error("Failed to get system stats", "error", err)
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- M_StatTotal_Dashboards.Set(float64(statsQuery.Result.Dashboards))
|
|
|
- M_StatTotal_Users.Set(float64(statsQuery.Result.Users))
|
|
|
- M_StatActive_Users.Set(float64(statsQuery.Result.ActiveUsers))
|
|
|
- M_StatTotal_Playlists.Set(float64(statsQuery.Result.Playlists))
|
|
|
- M_StatTotal_Orgs.Set(float64(statsQuery.Result.Orgs))
|
|
|
-}
|
|
|
-
|
|
|
-var usageStatsURL = "https://stats.grafana.org/grafana-usage-report"
|
|
|
-
|
|
|
-func getEdition() string {
|
|
|
- if setting.IsEnterprise {
|
|
|
- return "enterprise"
|
|
|
- } else {
|
|
|
- return "oss"
|
|
|
- }
|
|
|
-}
|
|
|
-
|
|
|
-func sendUsageStats(oauthProviders map[string]bool) {
|
|
|
- if !setting.ReportingEnabled {
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- metricsLogger.Debug("Sending anonymous usage stats to stats.grafana.org")
|
|
|
-
|
|
|
- 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(),
|
|
|
- "packaging": setting.Packaging,
|
|
|
- }
|
|
|
-
|
|
|
- statsQuery := models.GetSystemStatsQuery{}
|
|
|
- if err := bus.Dispatch(&statsQuery); err != nil {
|
|
|
- metricsLogger.Error("Failed to get system stats", "error", err)
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- metrics["stats.dashboards.count"] = statsQuery.Result.Dashboards
|
|
|
- metrics["stats.users.count"] = statsQuery.Result.Users
|
|
|
- metrics["stats.orgs.count"] = statsQuery.Result.Orgs
|
|
|
- metrics["stats.playlist.count"] = statsQuery.Result.Playlists
|
|
|
- metrics["stats.plugins.apps.count"] = len(plugins.Apps)
|
|
|
- metrics["stats.plugins.panels.count"] = len(plugins.Panels)
|
|
|
- metrics["stats.plugins.datasources.count"] = len(plugins.DataSources)
|
|
|
- metrics["stats.alerts.count"] = statsQuery.Result.Alerts
|
|
|
- metrics["stats.active_users.count"] = statsQuery.Result.ActiveUsers
|
|
|
- metrics["stats.datasources.count"] = statsQuery.Result.Datasources
|
|
|
- metrics["stats.stars.count"] = statsQuery.Result.Stars
|
|
|
- metrics["stats.folders.count"] = statsQuery.Result.Folders
|
|
|
- metrics["stats.dashboard_permissions.count"] = statsQuery.Result.DashboardPermissions
|
|
|
- metrics["stats.folder_permissions.count"] = statsQuery.Result.FolderPermissions
|
|
|
- metrics["stats.provisioned_dashboards.count"] = statsQuery.Result.ProvisionedDashboards
|
|
|
- metrics["stats.snapshots.count"] = statsQuery.Result.Snapshots
|
|
|
- metrics["stats.teams.count"] = statsQuery.Result.Teams
|
|
|
-
|
|
|
- dsStats := models.GetDataSourceStatsQuery{}
|
|
|
- if err := bus.Dispatch(&dsStats); err != nil {
|
|
|
- metricsLogger.Error("Failed to get datasource stats", "error", 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 models.IsKnownDataSourcePlugin(dsStat.Type) {
|
|
|
- metrics["stats.ds."+dsStat.Type+".count"] = dsStat.Count
|
|
|
- } else {
|
|
|
- dsOtherCount += dsStat.Count
|
|
|
- }
|
|
|
- }
|
|
|
- metrics["stats.ds.other.count"] = dsOtherCount
|
|
|
-
|
|
|
- metrics["stats.packaging."+setting.Packaging+".count"] = 1
|
|
|
-
|
|
|
- dsAccessStats := models.GetDataSourceAccessStatsQuery{}
|
|
|
- if err := bus.Dispatch(&dsAccessStats); err != nil {
|
|
|
- metricsLogger.Error("Failed to get datasource access stats", "error", err)
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- // send access counters for each data source
|
|
|
- // but ignore any custom data sources
|
|
|
- // as sending that name could be sensitive information
|
|
|
- dsAccessOtherCount := make(map[string]int64)
|
|
|
- for _, dsAccessStat := range dsAccessStats.Result {
|
|
|
- if dsAccessStat.Access == "" {
|
|
|
- continue
|
|
|
- }
|
|
|
-
|
|
|
- access := strings.ToLower(dsAccessStat.Access)
|
|
|
-
|
|
|
- if models.IsKnownDataSourcePlugin(dsAccessStat.Type) {
|
|
|
- metrics["stats.ds_access."+dsAccessStat.Type+"."+access+".count"] = dsAccessStat.Count
|
|
|
- } else {
|
|
|
- old := dsAccessOtherCount[access]
|
|
|
- dsAccessOtherCount[access] = old + dsAccessStat.Count
|
|
|
- }
|
|
|
- }
|
|
|
-
|
|
|
- for access, count := range dsAccessOtherCount {
|
|
|
- metrics["stats.ds_access.other."+access+".count"] = count
|
|
|
- }
|
|
|
-
|
|
|
- anStats := models.GetAlertNotifierUsageStatsQuery{}
|
|
|
- if err := bus.Dispatch(&anStats); err != nil {
|
|
|
- metricsLogger.Error("Failed to get alert notification stats", "error", err)
|
|
|
- return
|
|
|
- }
|
|
|
-
|
|
|
- for _, stats := range anStats.Result {
|
|
|
- metrics["stats.alert_notifiers."+stats.Type+".count"] = stats.Count
|
|
|
- }
|
|
|
-
|
|
|
- authTypes := map[string]bool{}
|
|
|
- authTypes["anonymous"] = setting.AnonymousEnabled
|
|
|
- authTypes["basic_auth"] = setting.BasicAuthEnabled
|
|
|
- authTypes["ldap"] = setting.LdapEnabled
|
|
|
- authTypes["auth_proxy"] = setting.AuthProxyEnabled
|
|
|
+func newCounterVecStartingAtZero(opts prometheus.CounterOpts, labels []string, labelValues ...string) *prometheus.CounterVec {
|
|
|
+ counter := prometheus.NewCounterVec(opts, labels)
|
|
|
|
|
|
- for provider, enabled := range oauthProviders {
|
|
|
- authTypes["oauth_"+provider] = enabled
|
|
|
+ for _, label := range labelValues {
|
|
|
+ counter.WithLabelValues(label).Add(0)
|
|
|
}
|
|
|
|
|
|
- for authType, enabled := range authTypes {
|
|
|
- enabledValue := 0
|
|
|
- if enabled {
|
|
|
- enabledValue = 1
|
|
|
- }
|
|
|
- metrics["stats.auth_enabled."+authType+".count"] = enabledValue
|
|
|
- }
|
|
|
+ return counter
|
|
|
+}
|
|
|
|
|
|
- out, _ := json.MarshalIndent(report, "", " ")
|
|
|
- data := bytes.NewBuffer(out)
|
|
|
+func newCounterStartingAtZero(opts prometheus.CounterOpts, labelValues ...string) prometheus.Counter {
|
|
|
+ counter := prometheus.NewCounter(opts)
|
|
|
+ counter.Add(0)
|
|
|
|
|
|
- client := http.Client{Timeout: 5 * time.Second}
|
|
|
- go client.Post(usageStatsURL, "application/json", data)
|
|
|
+ return counter
|
|
|
}
|