-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathlog_module.go
More file actions
165 lines (137 loc) · 3.72 KB
/
Copy pathlog_module.go
File metadata and controls
165 lines (137 loc) · 3.72 KB
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
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
package main
import (
"encoding/json"
"fmt"
"regexp"
"sync"
"time"
"github.com/Shopify/sarama"
"github.com/fatih/color"
"github.com/larskluge/babl-server/kafka"
. "github.com/larskluge/babl-server/utils"
)
const TIME_INTERVAL = 30 //value in seconds to warn about queueing
const TIMEOUT = 60 // timeout for queuing error message
//Warning log level
type responses struct {
channels map[string]chan string
mux sync.Mutex
}
var (
SupervisorSent = regexp.MustCompile(".*message sent.*IO")
ModuleReceived = regexp.MustCompile(".*New Group Message Received.*")
resp responses
)
func ParseModule() {
client := *kafka.NewClient([]string{Broker}, "babl-admin", true)
defer client.Close()
consumer, err := sarama.NewConsumerFromClient(client)
Check(err)
defer consumer.Close()
offsetNewest, err := client.GetOffset(Topic, Partition, sarama.OffsetNewest)
Check(err)
offsetOldest, err := client.GetOffset(Topic, Partition, sarama.OffsetOldest)
Check(err)
offset := offsetNewest - LastN
if offset < 0 || offset < offsetOldest {
offset = offsetOldest
}
cp, err := consumer.ConsumePartition(Topic, Partition, offset)
Check(err)
defer cp.Close()
resp = responses{channels: make(map[string]chan string)}
for msg := range cp.Messages() {
parseFilterMessage(msg)
}
}
func parseFilterMessage(msg *sarama.ConsumerMessage) {
var m Msg
err := json.Unmarshal(msg.Value, &m)
Check(err)
// MESSAGE can be a string or []byte which represents a string; bug in journald/kafka-manager somehow
var s string
err = json.Unmarshal(m.MessageRaw, &s)
if err == nil {
m.Message = s
} else {
var n []byte
err = json.Unmarshal(m.MessageRaw, &n)
Check(err)
m.Message = string(n)
}
rid := getAttr("rid", m.Message)
if rid != "" && SupervisorSent.MatchString(m.Message) {
topic := getAttr("topic", m.Message)
partition := getAttr("partition", m.Message)
offset := getAttr("offset", m.Message)
// fmt.Println(topic, " -> track message ->", m.Message)
go trackMessage(rid, topic, partition, offset)
}
if rid != "" && ModuleReceived.MatchString(m.Message) {
go replyMessage(rid, m.Message, AppName(m))
}
}
func getAttr(atr string, msg string) string {
var res string
re := fmt.Sprintf(`"%s":([".a-zA-Z\d]+)`, atr)
r := regexp.MustCompile(re)
matches := r.FindStringSubmatch(msg)
if matches != nil {
res = matches[1]
} else {
res = ""
}
return res
}
func trackMessage(rid, topic, partition, offset string) error {
timeCheck := TIME_INTERVAL
channel := getRidChannel(rid)
// fmt.Println("TRACKING:", channel, rid)
issues := false
for {
select {
case data := <-channel:
if issues {
color.Set(color.FgGreen)
}
fmt.Println(rid, "->", data)
color.Unset()
return nil
case <-time.After(time.Duration(timeCheck) * time.Second):
if timeCheck >= TIMEOUT {
color.Set(color.FgRed)
fmt.Println(rid, "XXXXXXX->", "MESSAGE ENQUEUED FOR 1 MIN @ ->", topic, partition, offset)
color.Unset()
return nil
}
color.Set(color.FgYellow)
fmt.Println(rid, "X->", topic, timeCheck, "seconds in queue!!!", partition, offset)
color.Unset()
timeCheck = timeCheck + TIME_INTERVAL
issues = true
continue
}
}
}
func getRidChannel(rid string) chan string {
resp.mux.Lock()
channel, ok := resp.channels[rid]
resp.mux.Unlock()
if ok {
return channel
} else {
resp.mux.Lock()
resp.channels[rid] = make(chan string, 1)
resp.mux.Unlock()
return resp.channels[rid]
}
}
func replyMessage(rid string, msg string, app string) {
channel := getRidChannel(rid)
partition := getAttr("partition", msg)
offset := getAttr("offset", msg)
reply := fmt.Sprintf("%s, [%s,%s]", app, partition, offset)
//#todo, fix double messaging on rebalacing
channel <- reply
// close(channel)
}