Live: collect more usage stats – enabled, ha enabled, num nodes, channels, subs (#47378)

This commit is contained in:
Alexander Emelin 2022-04-13 22:27:03 +03:00 committed by GitHub
parent 884c885289
commit e00db6a826
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 110 additions and 35 deletions

View File

@ -9,6 +9,7 @@ import (
"net/http" "net/http"
"net/url" "net/url"
"os" "os"
"strconv"
"strings" "strings"
"sync" "sync"
"time" "time"
@ -1365,6 +1366,11 @@ func handleLog(msg centrifuge.LogEntry) {
func (g *GrafanaLive) sampleLiveStats() { func (g *GrafanaLive) sampleLiveStats() {
numClients := g.node.Hub().NumClients() numClients := g.node.Hub().NumClients()
numUsers := g.node.Hub().NumUsers() 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.sampleCount++
g.usageStats.numClientsSum += numClients g.usageStats.numClientsSum += numClients
@ -1374,16 +1380,16 @@ func (g *GrafanaLive) sampleLiveStats() {
g.usageStats.numClientsMax = numClients g.usageStats.numClientsMax = numClients
} }
if numClients < g.usageStats.numClientsMin {
g.usageStats.numClientsMin = numClients
}
if numUsers > g.usageStats.numUsersMax { if numUsers > g.usageStats.numUsersMax {
g.usageStats.numUsersMax = numUsers g.usageStats.numUsersMax = numUsers
} }
if numUsers < g.usageStats.numUsersMin { if numNodes > g.usageStats.numNodesMax {
g.usageStats.numUsersMin = numUsers g.usageStats.numNodesMax = numNodes
}
if numChannels > g.usageStats.numChannelsMax {
g.usageStats.numChannelsMax = numChannels
} }
} }
@ -1391,38 +1397,65 @@ func (g *GrafanaLive) resetLiveStats() {
g.usageStats = usageStats{} 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() { func (g *GrafanaLive) registerUsageMetrics() {
g.usageStatsService.RegisterSendReportCallback(g.resetLiveStats) g.usageStatsService.RegisterSendReportCallback(g.resetLiveStats)
g.usageStatsService.RegisterMetricsFunc(g.collectLiveStats)
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
})
} }
type usageStats struct { type usageStats struct {
numClientsMax int numClientsMax int
numClientsMin int numClientsSum int
numClientsSum int numUsersMax int
numUsersMax int numUsersSum int
numUsersMin int sampleCount int
numUsersSum int numNodesMax int
sampleCount int numChannelsMax int
} }

View File

@ -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)
}
})
}
}