forked from adjust/redismq
/
observer.go
113 lines (97 loc) · 3.02 KB
/
observer.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
package redismq
import (
"encoding/json"
"github.com/adeven/redis"
"log"
"time"
)
type observer struct {
redisClient *redis.Client `json:"-"`
RedisURL string `json:"-"`
RedisPassword string `json:"-"`
RedisDb int64 `json:"-"`
Stats map[string]*queueStat
}
type queueStat struct {
InputRate int64
WorkRate int64
AckRate int64
FailRate int64
InputSize int64
UnAckSize int64
FailSize int64
consumerStats map[string]*consumerStat
}
type consumerStat struct {
WorkRate int64
AckRate int64
UnAckSize int64
}
func newObserver(redisURL, redisPassword string, redisDb int64) *observer {
q := &observer{
RedisURL: redisURL,
RedisPassword: redisPassword,
RedisDb: redisDb,
Stats: make(map[string]*queueStat),
}
q.redisClient = redis.NewTCPClient(redisURL, redisPassword, redisDb)
return q
}
func (observer *observer) Start() {
go func() {
for {
for _, queue := range observer.GetAllQueues() {
if observer.Stats[queue.Name] == nil {
observer.WatchQueue(queue)
}
}
time.Sleep(2 * time.Second)
}
}()
}
func (observer *observer) GetAllQueues() (queues []*Queue) {
answer := observer.redisClient.SMembers(masterQueueKey())
if answer.Err() != nil {
return
}
for _, name := range answer.Val() {
queues = append(queues, NewQueue(observer.RedisURL, observer.RedisPassword, observer.RedisDb, name))
}
return
}
func (observer *observer) WatchQueue(queue *Queue) {
observer.Stats[queue.Name] = &queueStat{consumerStats: make(map[string]*consumerStat)}
go observer.Poll(queue)
}
func (observer *observer) Poll(queue *Queue) {
for {
observer.Stats[queue.Name].InputRate = queue.getInputRate()
observer.Stats[queue.Name].FailRate = queue.getFailedRate()
observer.Stats[queue.Name].InputSize = queue.GetInputLength()
observer.Stats[queue.Name].FailSize = queue.GetFailedLength()
observer.Stats[queue.Name].WorkRate = 0
observer.Stats[queue.Name].AckRate = 0
observer.Stats[queue.Name].UnAckSize = 0
brokers, err := queue.getBrokers()
if err != nil {
continue //TODO handle this
}
for _, broker := range brokers {
observer.Stats[queue.Name].consumerStats[broker.Name] = &consumerStat{}
observer.Stats[queue.Name].consumerStats[broker.Name].AckRate = broker.GetAckRate()
observer.Stats[queue.Name].consumerStats[broker.Name].WorkRate = broker.GetWorkRate()
observer.Stats[queue.Name].consumerStats[broker.Name].UnAckSize = broker.GetUnackedLength()
observer.Stats[queue.Name].AckRate += observer.Stats[queue.Name].consumerStats[broker.Name].AckRate
observer.Stats[queue.Name].WorkRate += observer.Stats[queue.Name].consumerStats[broker.Name].WorkRate
observer.Stats[queue.Name].UnAckSize += observer.Stats[queue.Name].consumerStats[broker.Name].UnAckSize
}
time.Sleep(1 * time.Second)
}
}
func (observer *observer) OutputToString() string {
json, err := json.Marshal(observer)
if err != nil {
log.Fatalf("ERROR MARSHALLING OVERSEER %s", err.Error())
}
return string(json)
}