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
1516type 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
2827type SumoBuffer struct {
@@ -32,15 +31,13 @@ type SumoBuffer struct {
3231
3332func 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
5148func (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
9192func 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