slideInterval = time.Second * 15
slideWindow = time.Minute * 5
slotNum = slideWindow / slideInterval
type ClientCounters struct {
counters [slotNum]map[string]uint
type ClientTuple struct {
func NewClientCounters() *ClientCounters {
result := &ClientCounters{
for i := range result.counters {
result.counters[i] = make(map[string]uint)
func (c *ClientCounters) put(client string) {
func (c *ClientCounters) generateMetrics() {
m := make(map[string]uint)
for _, counter := range c.counters {
for client, val := range counter {
if _, ok := m[client]; !ok {
result := make([]*ClientTuple, 0, len(m))
for name, val := range m {
result = append(result, tuple)
sort.Slice(result, func(i, j int) bool {
return result[i].val > result[j].val
result := make([]*ClientTuple, 0, len(m))
for name, val := range m {
result = append(result, tuple)
sort.Slice(result, func(i, j int) bool {
return result[i].val > result[j].val
for _, t := range result[:end] {
ClientCount.WithLabelValues(t.name).Set(float64(t.val))
func (c *ClientCounters) run() {
tick := time.Tick(slideInterval)
index = (index 1) % int(slotNum)
c.counters[index] = make(map[string]uint)
if _, ok := c.counters[index][client]; !ok {
c.counters[index][client] = 0
c.counters[index][client]
clientCounters := NewClientCounters()
if clientCounters != nil {