Commit b070784b by Carl Bergquist Committed by Torkel Ödegaard

adds usage stats for alert notifiers (#13173)

parent 44cd738d
...@@ -440,6 +440,16 @@ func sendUsageStats() { ...@@ -440,6 +440,16 @@ func sendUsageStats() {
metrics["stats.ds_access.other."+access+".count"] = count 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
}
out, _ := json.MarshalIndent(report, "", " ") out, _ := json.MarshalIndent(report, "", " ")
data := bytes.NewBuffer(out) data := bytes.NewBuffer(out)
......
...@@ -115,6 +115,24 @@ func TestMetrics(t *testing.T) { ...@@ -115,6 +115,24 @@ func TestMetrics(t *testing.T) {
return nil return nil
}) })
var getAlertNotifierUsageStatsQuery *models.GetAlertNotifierUsageStatsQuery
bus.AddHandler("test", func(query *models.GetAlertNotifierUsageStatsQuery) error {
query.Result = []*models.NotifierUsageStats{
{
Type: "slack",
Count: 1,
},
{
Type: "webhook",
Count: 2,
},
}
getAlertNotifierUsageStatsQuery = query
return nil
})
var wg sync.WaitGroup var wg sync.WaitGroup
var responseBuffer *bytes.Buffer var responseBuffer *bytes.Buffer
var req *http.Request var req *http.Request
...@@ -157,6 +175,7 @@ func TestMetrics(t *testing.T) { ...@@ -157,6 +175,7 @@ func TestMetrics(t *testing.T) {
So(getSystemStatsQuery, ShouldNotBeNil) So(getSystemStatsQuery, ShouldNotBeNil)
So(getDataSourceStatsQuery, ShouldNotBeNil) So(getDataSourceStatsQuery, ShouldNotBeNil)
So(getDataSourceAccessStatsQuery, ShouldNotBeNil) So(getDataSourceAccessStatsQuery, ShouldNotBeNil)
So(getAlertNotifierUsageStatsQuery, ShouldNotBeNil)
So(req, ShouldNotBeNil) So(req, ShouldNotBeNil)
So(req.Method, ShouldEqual, http.MethodPost) So(req.Method, ShouldEqual, http.MethodPost)
So(req.Header.Get("Content-Type"), ShouldEqual, "application/json") So(req.Header.Get("Content-Type"), ShouldEqual, "application/json")
...@@ -198,6 +217,9 @@ func TestMetrics(t *testing.T) { ...@@ -198,6 +217,9 @@ func TestMetrics(t *testing.T) {
So(metrics.Get("stats.ds_access."+models.DS_PROMETHEUS+".proxy.count").MustInt(), ShouldEqual, 3) So(metrics.Get("stats.ds_access."+models.DS_PROMETHEUS+".proxy.count").MustInt(), ShouldEqual, 3)
So(metrics.Get("stats.ds_access.other.direct.count").MustInt(), ShouldEqual, 6+7) So(metrics.Get("stats.ds_access.other.direct.count").MustInt(), ShouldEqual, 6+7)
So(metrics.Get("stats.ds_access.other.proxy.count").MustInt(), ShouldEqual, 4+8) So(metrics.Get("stats.ds_access.other.proxy.count").MustInt(), ShouldEqual, 4+8)
So(metrics.Get("stats.alert_notifiers.slack.count").MustInt(), ShouldEqual, 1)
So(metrics.Get("stats.alert_notifiers.webhook.count").MustInt(), ShouldEqual, 2)
}) })
}) })
......
...@@ -40,6 +40,15 @@ type GetDataSourceAccessStatsQuery struct { ...@@ -40,6 +40,15 @@ type GetDataSourceAccessStatsQuery struct {
Result []*DataSourceAccessStats Result []*DataSourceAccessStats
} }
type NotifierUsageStats struct {
Type string
Count int64
}
type GetAlertNotifierUsageStatsQuery struct {
Result []*NotifierUsageStats
}
type AdminStats struct { type AdminStats struct {
Users int `json:"users"` Users int `json:"users"`
Orgs int `json:"orgs"` Orgs int `json:"orgs"`
......
...@@ -13,11 +13,19 @@ func init() { ...@@ -13,11 +13,19 @@ func init() {
bus.AddHandler("sql", GetDataSourceStats) bus.AddHandler("sql", GetDataSourceStats)
bus.AddHandler("sql", GetDataSourceAccessStats) bus.AddHandler("sql", GetDataSourceAccessStats)
bus.AddHandler("sql", GetAdminStats) bus.AddHandler("sql", GetAdminStats)
bus.AddHandlerCtx("sql", GetAlertNotifiersUsageStats)
bus.AddHandlerCtx("sql", GetSystemUserCountStats) bus.AddHandlerCtx("sql", GetSystemUserCountStats)
} }
var activeUserTimeLimit = time.Hour * 24 * 30 var activeUserTimeLimit = time.Hour * 24 * 30
func GetAlertNotifiersUsageStats(ctx context.Context, query *m.GetAlertNotifierUsageStatsQuery) error {
var rawSql = `SELECT COUNT(*) as count, type FROM alert_notification GROUP BY type`
query.Result = make([]*m.NotifierUsageStats, 0)
err := x.SQL(rawSql).Find(&query.Result)
return err
}
func GetDataSourceStats(query *m.GetDataSourceStatsQuery) error { func GetDataSourceStats(query *m.GetDataSourceStatsQuery) error {
var rawSql = `SELECT COUNT(*) as count, type FROM data_source GROUP BY type` var rawSql = `SELECT COUNT(*) as count, type FROM data_source GROUP BY type`
query.Result = make([]*m.DataSourceStats, 0) query.Result = make([]*m.DataSourceStats, 0)
......
...@@ -36,5 +36,11 @@ func TestStatsDataAccess(t *testing.T) { ...@@ -36,5 +36,11 @@ func TestStatsDataAccess(t *testing.T) {
err := GetDataSourceAccessStats(&query) err := GetDataSourceAccessStats(&query)
So(err, ShouldBeNil) So(err, ShouldBeNil)
}) })
Convey("Get alert notifier stats should not results in error", func() {
query := m.GetAlertNotifierUsageStatsQuery{}
err := GetAlertNotifiersUsageStats(context.Background(), &query)
So(err, ShouldBeNil)
})
}) })
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment