From e00db6a826428d0480f0ea704f55346af2cbec9b Mon Sep 17 00:00:00 2001 From: Alexander Emelin Date: Wed, 13 Apr 2022 22:27:03 +0300 Subject: [PATCH] =?UTF-8?q?Live:=20collect=20more=20usage=20stats=20?= =?UTF-8?q?=E2=80=93=20enabled,=20ha=20enabled,=20num=20nodes,=20channels,?= =?UTF-8?q?=20subs=20(#47378)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- pkg/services/live/live.go | 103 ++++++++++++++++++++++----------- pkg/services/live/live_test.go | 42 ++++++++++++++ 2 files changed, 110 insertions(+), 35 deletions(-) diff --git a/pkg/services/live/live.go b/pkg/services/live/live.go index ea144b3f391..3924d6f810e 100644 --- a/pkg/services/live/live.go +++ b/pkg/services/live/live.go @@ -9,6 +9,7 @@ import ( "net/http" "net/url" "os" + "strconv" "strings" "sync" "time" @@ -1365,6 +1366,11 @@ func handleLog(msg centrifuge.LogEntry) { func (g *GrafanaLive) sampleLiveStats() { numClients := g.node.Hub().NumClients() numUsers := g.node.Hub().NumUsers() + numChannels := g.node.Hub().NumChannels() + var numNodes int + if info, err := g.node.Info(); err == nil { + numNodes = len(info.Nodes) + } g.usageStats.sampleCount++ g.usageStats.numClientsSum += numClients @@ -1374,16 +1380,16 @@ func (g *GrafanaLive) sampleLiveStats() { g.usageStats.numClientsMax = numClients } - if numClients < g.usageStats.numClientsMin { - g.usageStats.numClientsMin = numClients - } - if numUsers > g.usageStats.numUsersMax { g.usageStats.numUsersMax = numUsers } - if numUsers < g.usageStats.numUsersMin { - g.usageStats.numUsersMin = numUsers + if numNodes > g.usageStats.numNodesMax { + g.usageStats.numNodesMax = numNodes + } + + if numChannels > g.usageStats.numChannelsMax { + g.usageStats.numChannelsMax = numChannels } } @@ -1391,38 +1397,65 @@ func (g *GrafanaLive) resetLiveStats() { g.usageStats = usageStats{} } +func getHistogramMetric(val int, bounds []int, metricPrefix string) string { + for _, bound := range bounds { + if val <= bound { + return metricPrefix + "le_" + strconv.Itoa(bound) + } + } + return metricPrefix + "le_inf" +} + +func (g *GrafanaLive) collectLiveStats(_ context.Context) (map[string]interface{}, error) { + liveUsersAvg := 0 + liveClientsAvg := 0 + + if g.usageStats.sampleCount > 0 { + liveUsersAvg = g.usageStats.numUsersSum / g.usageStats.sampleCount + liveClientsAvg = g.usageStats.numClientsSum / g.usageStats.sampleCount + } + + var liveEnabled int + if g.Cfg.LiveMaxConnections != 0 { + liveEnabled = 1 + } + + var liveHAEnabled int + if g.Cfg.LiveHAEngine != "" { + liveHAEnabled = 1 + } + + metrics := map[string]interface{}{ + "stats.live_enabled.count": liveEnabled, + "stats.live_ha_enabled.count": liveHAEnabled, + "stats.live_samples.count": g.usageStats.sampleCount, + "stats.live_users_max.count": g.usageStats.numUsersMax, + "stats.live_users_avg.count": liveUsersAvg, + "stats.live_clients_max.count": g.usageStats.numClientsMax, + "stats.live_clients_avg.count": liveClientsAvg, + "stats.live_channels_max.count": g.usageStats.numChannelsMax, + "stats.live_nodes_max.count": g.usageStats.numNodesMax, + } + + metrics[getHistogramMetric(g.usageStats.numClientsMax, []int{0, 10, 100, 1000, 10000, 100000}, "stats.live_clients_")] = 1 + metrics[getHistogramMetric(g.usageStats.numUsersMax, []int{0, 10, 100, 1000, 10000, 100000}, "stats.live_users_")] = 1 + metrics[getHistogramMetric(g.usageStats.numChannelsMax, []int{0, 10, 100, 1000, 10000, 100000}, "stats.live_channels_")] = 1 + metrics[getHistogramMetric(g.usageStats.numNodesMax, []int{1, 3, 9}, "stats.live_nodes_")] = 1 + + return metrics, nil +} + func (g *GrafanaLive) registerUsageMetrics() { g.usageStatsService.RegisterSendReportCallback(g.resetLiveStats) - - g.usageStatsService.RegisterMetricsFunc(func(context.Context) (map[string]interface{}, error) { - liveUsersAvg := 0 - liveClientsAvg := 0 - - if g.usageStats.sampleCount > 0 { - liveUsersAvg = g.usageStats.numUsersSum / g.usageStats.sampleCount - liveClientsAvg = g.usageStats.numClientsSum / g.usageStats.sampleCount - } - - metrics := map[string]interface{}{ - "stats.live_samples.count": g.usageStats.sampleCount, - "stats.live_users_max.count": g.usageStats.numUsersMax, - "stats.live_users_min.count": g.usageStats.numUsersMin, - "stats.live_users_avg.count": liveUsersAvg, - "stats.live_clients_max.count": g.usageStats.numClientsMax, - "stats.live_clients_min.count": g.usageStats.numClientsMin, - "stats.live_clients_avg.count": liveClientsAvg, - } - - return metrics, nil - }) + g.usageStatsService.RegisterMetricsFunc(g.collectLiveStats) } type usageStats struct { - numClientsMax int - numClientsMin int - numClientsSum int - numUsersMax int - numUsersMin int - numUsersSum int - sampleCount int + numClientsMax int + numClientsSum int + numUsersMax int + numUsersSum int + sampleCount int + numNodesMax int + numChannelsMax int } diff --git a/pkg/services/live/live_test.go b/pkg/services/live/live_test.go index 9c738c0aa30..d4dff995fcd 100644 --- a/pkg/services/live/live_test.go +++ b/pkg/services/live/live_test.go @@ -157,3 +157,45 @@ func TestCheckOrigin(t *testing.T) { }) } } + +func Test_getHistogramMetric(t *testing.T) { + type args struct { + val int + bounds []int + metricPrefix string + } + + tests := []struct { + name string + args args + want string + }{ + { + "zero", + args{0, []int{0, 10, 100, 1000, 10000, 100000}, "live_users_"}, + "live_users_le_0", + }, + { + "equal_to_bound", + args{10, []int{0, 10, 100, 1000, 10000, 100000}, "live_users_"}, + "live_users_le_10", + }, + { + "in_the_middle", + args{30000, []int{0, 10, 100, 1000, 10000, 100000}, "live_users_"}, + "live_users_le_100000", + }, + { + "more_than_upper_bound", + args{300000, []int{0, 10, 100, 1000, 10000, 100000}, "live_users_"}, + "live_users_le_inf", + }, + } + for _, tt := range tests { + t.Run(tt.name, func(t *testing.T) { + if got := getHistogramMetric(tt.args.val, tt.args.bounds, tt.args.metricPrefix); got != tt.want { + t.Errorf("getHistogramMetric() = %v, want %v", got, tt.want) + } + }) + } +}