mirror of
https://github.com/mxpv/podsync.git
synced 2024-05-11 05:55:04 +00:00
Track top metrics
This commit is contained in:
pkg/stats
@ -12,24 +12,63 @@ type RedisStats struct {
|
||||
}
|
||||
|
||||
func (r RedisStats) Inc(metric, hashID string) (int64, error) {
|
||||
key := r.makeKey(hashID)
|
||||
return r.client.HIncrBy(key, metric, 1).Result()
|
||||
now := time.Now().UTC()
|
||||
|
||||
key := r.makeKey(now, hashID)
|
||||
top := r.makeTop(now, metric)
|
||||
|
||||
var cmd *redis.IntCmd
|
||||
_, err := r.client.TxPipelined(func(p redis.Pipeliner) error {
|
||||
cmd = p.HIncrBy(key, metric, 1)
|
||||
p.ZIncrBy(top, 1, hashID)
|
||||
return nil
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return cmd.Result()
|
||||
}
|
||||
|
||||
func (r RedisStats) Get(metric, hashID string) (int64, error) {
|
||||
key := r.makeKey(hashID)
|
||||
now := time.Now().UTC()
|
||||
key := r.makeKey(now, hashID)
|
||||
return r.client.HGet(key, metric).Int64()
|
||||
}
|
||||
|
||||
func (r RedisStats) Top(metric string) (map[string]int64, error) {
|
||||
now := time.Now().UTC()
|
||||
top := r.makeTop(now, metric)
|
||||
|
||||
zrange, err := r.client.ZRevRangeWithScores(top, 0, 10).Result()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
ret := make(map[string]int64)
|
||||
for _, x := range zrange {
|
||||
key := x.Member.(string)
|
||||
val := int64(x.Score)
|
||||
|
||||
ret[key] = val
|
||||
}
|
||||
|
||||
return ret, nil
|
||||
}
|
||||
|
||||
func (r RedisStats) makeKey(now time.Time, hashID string) string {
|
||||
return fmt.Sprintf("stats/%d/%d/%s", now.Year(), now.Month(), hashID)
|
||||
}
|
||||
|
||||
func (r RedisStats) makeTop(now time.Time, metric string) string {
|
||||
return fmt.Sprintf("stats/top/%d/%d/%s", now.Year(), now.Month(), metric)
|
||||
}
|
||||
|
||||
func (r RedisStats) Close() error {
|
||||
return r.client.Close()
|
||||
}
|
||||
|
||||
func (r RedisStats) makeKey(hashID string) string {
|
||||
now := time.Now().UTC()
|
||||
return fmt.Sprintf("stats/%d/%d/%s", now.Year(), now.Month(), hashID)
|
||||
}
|
||||
|
||||
func NewRedisStats(redisUrl string) (*RedisStats, error) {
|
||||
opts, err := redis.ParseURL(redisUrl)
|
||||
if err != nil {
|
||||
|
@ -27,6 +27,43 @@ func TestRedisStats_IncAndGet(t *testing.T) {
|
||||
require.Equal(t, int64(2), v)
|
||||
}
|
||||
|
||||
func TestRedisStats_Top(t *testing.T) {
|
||||
t.Skip("run redis tests manually")
|
||||
|
||||
s := createRedisClient(t)
|
||||
|
||||
// 3
|
||||
s.Inc(metric, "123")
|
||||
s.Inc(metric, "123")
|
||||
s.Inc(metric, "123")
|
||||
|
||||
// 2
|
||||
s.Inc(metric, "321")
|
||||
s.Inc(metric, "321")
|
||||
|
||||
// 1
|
||||
s.Inc(metric, "213")
|
||||
|
||||
top, err := s.Top(metric)
|
||||
require.NoError(t, err)
|
||||
require.Len(t, top, 3)
|
||||
|
||||
// 3
|
||||
h3, ok := top["123"]
|
||||
require.True(t, ok)
|
||||
require.Equal(t, int64(3), h3)
|
||||
|
||||
// 2
|
||||
h2, ok := top["321"]
|
||||
require.True(t, ok)
|
||||
require.Equal(t, int64(2), h2)
|
||||
|
||||
// 1
|
||||
h1, ok := top["213"]
|
||||
require.True(t, ok)
|
||||
require.Equal(t, int64(1), h1)
|
||||
}
|
||||
|
||||
func createRedisClient(t *testing.T) *RedisStats {
|
||||
client, err := NewRedisStats("redis://localhost")
|
||||
require.NoError(t, err)
|
||||
|
Reference in New Issue
Block a user