Skip to content

Commit 7b75451

Browse files
committed
SCFF-35 better handling of the buffer
1 parent 87e94c9 commit 7b75451

1 file changed

Lines changed: 43 additions & 47 deletions

File tree

sumoCFFirehose/sumoLogicAppender.go

Lines changed: 43 additions & 47 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import (
55
"fmt"
66
"net/http"
77
"runtime"
8+
"sync"
89
"time"
910

1011
"bitbucket.org/mcplusa-ondemand/firehose-to-sumologic/eventQueue"
@@ -13,16 +14,14 @@ import (
1314
)
1415

1516
type SumoLogicAppender struct {
16-
url string
17-
connectionTimeout int //10000
18-
httpClient http.Client
19-
nozzleQueue *eventQueue.Queue
20-
eventsBatchSize int
21-
logEventsInCurrentBuffer int
22-
logStringToSend *bytes.Buffer
23-
sumoPostMinimumDelay time.Duration
24-
timerPostMinimum time.Time
25-
bufferToSend SumoBuffer
17+
url string
18+
connectionTimeout int //10000
19+
httpClient http.Client
20+
nozzleQueue *eventQueue.Queue
21+
eventsBatchSize int
22+
sumoPostMinimumDelay time.Duration
23+
timerPostMinimum time.Time
24+
bufferToSend SumoBuffer
2625
}
2726

2827
type SumoBuffer struct {
@@ -32,15 +31,13 @@ type SumoBuffer struct {
3231

3332
func NewSumoLogicAppender(urlValue string, connectionTimeoutValue int, nozzleQueue *eventQueue.Queue, eventsBatchSize int, sumoPostMinimumDelay time.Duration) *SumoLogicAppender {
3433
return &SumoLogicAppender{
35-
url: urlValue,
36-
connectionTimeout: connectionTimeoutValue,
37-
httpClient: http.Client{Timeout: time.Duration(connectionTimeoutValue * int(time.Millisecond))},
38-
nozzleQueue: nozzleQueue,
39-
eventsBatchSize: eventsBatchSize,
40-
logEventsInCurrentBuffer: 0,
41-
logStringToSend: bytes.NewBufferString(""),
42-
sumoPostMinimumDelay: sumoPostMinimumDelay,
43-
timerPostMinimum: time.Now(),
34+
url: urlValue,
35+
connectionTimeout: connectionTimeoutValue,
36+
httpClient: http.Client{Timeout: time.Duration(connectionTimeoutValue * int(time.Millisecond))},
37+
nozzleQueue: nozzleQueue,
38+
eventsBatchSize: eventsBatchSize,
39+
sumoPostMinimumDelay: sumoPostMinimumDelay,
40+
timerPostMinimum: time.Now(),
4441
bufferToSend: SumoBuffer{
4542
logStringToSend: bytes.NewBufferString(""),
4643
logEventsInCurrentBuffer: 0,
@@ -51,41 +48,45 @@ func NewSumoLogicAppender(urlValue string, connectionTimeoutValue int, nozzleQue
5148
func (s *SumoLogicAppender) Start() {
5249
runtime.GOMAXPROCS(1)
5350
timer := time.Now()
54-
tempBuffer := &SumoBuffer{
51+
Buffer := &SumoBuffer{
5552
logStringToSend: bytes.NewBufferString(""),
5653
logEventsInCurrentBuffer: 0,
5754
}
55+
var mutex = &sync.Mutex{} //synchronize access to Buffer
5856

5957
logging.Info.Println("Starting Appender Worker")
6058
for {
6159
time.Sleep(300 * time.Millisecond) //delay
60+
61+
mutex.Lock() //lock mutex to ensure exclusive access to buffer
62+
if Buffer.logEventsInCurrentBuffer >= s.eventsBatchSize { //if buffer is full, create a new one
63+
Buffer = &SumoBuffer{
64+
logStringToSend: bytes.NewBufferString(""),
65+
logEventsInCurrentBuffer: 0,
66+
}
67+
}
68+
mutex.Unlock()
6269
// while queue is not empty && s.eventsBatchSize not completed, queue.POP (appendLogs)
63-
for s.nozzleQueue.GetCount() != 0 && s.bufferToSend.logEventsInCurrentBuffer < s.eventsBatchSize {
64-
s.AppendLogs(&s.bufferToSend) //this method POP an event from queue to Buffer
65-
timer = time.Now() //reset timer
66-
if s.bufferToSend.logEventsInCurrentBuffer == s.eventsBatchSize && tempBuffer.logEventsInCurrentBuffer < s.eventsBatchSize { //if buffer is full, send logs to sumo
67-
logging.Info.Println("Batch Size complete, filling temp buffer")
68-
s.AppendLogs(tempBuffer)
70+
for s.nozzleQueue.GetCount() != 0 && Buffer.logEventsInCurrentBuffer < s.eventsBatchSize {
71+
mutex.Lock() //lock mutex to ensure exclusive access to buffer
72+
s.AppendLogs(Buffer) //this method POP an event from queue to Buffer
73+
mutex.Unlock()
74+
timer = time.Now() //reset timer
75+
if Buffer.logEventsInCurrentBuffer == s.eventsBatchSize { //if buffer is full, send logs to sumo
76+
logging.Info.Println("Batch Size complete")
6977
break
7078
} else if time.Since(timer).Seconds() >= 10 { // else if timer is up, send existing logs to sumo
7179
logging.Info.Println("Sending current batch of logs after timer exceeded limit")
72-
go s.SendToSumo(s.bufferToSend.logStringToSend)
7380
break
7481
}
7582
}
7683
//if batch size is met, send to sumo and reset temp buffer
77-
if s.bufferToSend.logEventsInCurrentBuffer == s.eventsBatchSize {
78-
go s.SendToSumo(s.bufferToSend.logStringToSend)
79-
s.bufferToSend.logStringToSend = tempBuffer.logStringToSend
80-
s.bufferToSend.logEventsInCurrentBuffer = tempBuffer.logEventsInCurrentBuffer
81-
tempBuffer = &SumoBuffer{ //reset temp buffer
82-
logStringToSend: bytes.NewBufferString(""),
83-
logEventsInCurrentBuffer: 0,
84-
}
85-
}
86-
84+
mutex.Lock()
85+
s.SendToSumo(Buffer)
86+
mutex.Unlock()
8787
timer = time.Now() //reset timer
8888
}
89+
8990
}
9091

9192
func StringBuilder(event *events.Event) string {
@@ -107,38 +108,33 @@ func (s *SumoLogicAppender) AppendLogs(buffer *SumoBuffer) {
107108
// then fills a buffer with the message
108109
buffer.logStringToSend.Write([]byte(StringBuilder(s.nozzleQueue.Pop())))
109110
buffer.logEventsInCurrentBuffer++
110-
fmt.Println(s.bufferToSend.logEventsInCurrentBuffer)
111111

112112
}
113113

114-
func (s *SumoLogicAppender) SendToSumo(log *bytes.Buffer) {
114+
func (s *SumoLogicAppender) SendToSumo(buffer *SumoBuffer) {
115115
//wait period between posts to Sumo
116-
fmt.Println(log.String())
117-
fmt.Println(".............")
116+
fmt.Println(buffer.logStringToSend.String())
117+
fmt.Println("......................")
118118
for time.Since(s.timerPostMinimum) < s.sumoPostMinimumDelay {
119119
time.Sleep(30 * time.Millisecond) // wait to retry
120120
}
121121
logging.Trace.Println("Sending logs to Sumologic...")
122-
request, err := http.NewRequest("POST", s.url, log)
122+
request, err := http.NewRequest("POST", s.url, buffer.logStringToSend)
123123
if err != nil {
124124
logging.Error.Printf("http.NewRequest() error: %v\n", err)
125125
return
126126
}
127127
//request.Header.Add("content-type", "application/json")
128128
//request.SetBasicAuth("admin", "admin")
129129
response, err := s.httpClient.Do(request)
130-
131130
if err != nil {
132131
logging.Error.Printf("http.Do() error: %v\n", err)
133132
return
134133
} else {
135134
logging.Trace.Println("Do(Request) successful")
136135
s.timerPostMinimum = time.Now() //reset timer post minimum
137136
}
138-
s.bufferToSend = SumoBuffer{
139-
logStringToSend: bytes.NewBufferString(""), //reset String
140-
logEventsInCurrentBuffer: 0, //reset counter
141-
}
137+
142138
defer response.Body.Close()
143139

144140
}

0 commit comments

Comments
 (0)