@@ -3,6 +3,8 @@ package sumoCFFirehose
33import (
44 "bytes"
55 "compress/gzip"
6+ "errors"
7+ "fmt"
68 "net/http"
79 "runtime"
810 "time"
@@ -134,40 +136,88 @@ func (s *SumoLogicAppender) SendToSumo(logStringToSend string) {
134136 //request.SetBasicAuth("admin", "admin")
135137 response , err := s .httpClient .Do (request )
136138
137- if err != nil {
138- logging .Error .Printf ("http.Do() error: %v\n " , err )
139- return
140- } else if response .StatusCode != 200 && response .StatusCode != 302 && response .StatusCode < 500 {
139+ if (err != nil ) || (response .StatusCode != 200 && response .StatusCode != 302 && response .StatusCode < 500 ) {
141140 logging .Info .Println ("Endpoint dropped the post send" )
142141 logging .Info .Println ("Waiting for 300 ms to retry" )
143142 time .Sleep (300 * time .Millisecond )
144- responseRetry , errRetry := s .httpClient .Do (request )
145- if errRetry != nil {
146- logging .Error .Printf ("http.Do() error: %v\n " , errRetry )
147- return
148- } else {
149- maxAttempts := 5
150- for i := 0 ; i <= maxAttempts ; i ++ {
151- if responseRetry .StatusCode != 200 && response .StatusCode != 302 && response .StatusCode < 500 {
152- logging .Info .Println ("Waiting for 300 ms to retry..." )
153- time .Sleep (300 * time .Millisecond )
154- responseRetry , errRetry = s .httpClient .Do (request )
155- if errRetry != nil {
156- logging .Error .Printf ("http.Do() error: %v\n " , errRetry )
157- return
158- } else {
159- logging .Info .Println ("Post of logs successful (after retry)" )
160- }
161- }
143+ statusCode := 0
144+ err := Retry (func (attempt int ) (bool , error ) {
145+ var errRetry error
146+ //create again request
147+ request , err := http .NewRequest ("POST" , s .url , & buf )
148+ if err != nil {
149+ logging .Error .Printf ("http.NewRequest() error: %v\n " , err )
150+ }
151+ request .Header .Add ("Content-Encoding" , "gzip" )
152+ response , errRetry = s .httpClient .Do (request )
153+ if errRetry != nil {
154+ logging .Error .Printf ("http.Do() error: %v\n " , errRetry )
155+ logging .Info .Println ("Waiting for 300 ms to retry after error" )
156+ fmt .Println (attempt )
157+ time .Sleep (300 * time .Millisecond )
158+ return attempt < 5 , errRetry
159+ } else if response .StatusCode != 200 && response .StatusCode != 302 && response .StatusCode < 500 {
160+ logging .Info .Println ("Endpoint dropped the post send again" )
161+ logging .Info .Println ("Waiting for 300 ms to retry after a retry ..." )
162+ fmt .Println (attempt )
163+ statusCode = response .StatusCode
164+ time .Sleep (300 * time .Millisecond )
165+ return attempt < 5 , errRetry
166+ } else if response .StatusCode == 200 {
167+ logging .Info . /*Trace*/ Println ("Post of logs successful after retry..." )
162168 s .timerBetweenPost = time .Now ()
169+ statusCode = response .StatusCode
170+ return true , err
163171 }
164- logging .Info . /*Trace*/ Println ("Not possible to send the logs after the maximum number of possible attempts" )
172+ return attempt < 5 , errRetry
173+ })
174+ if err != nil {
175+ logging .Error .Println ("Error, Not able to post after retry" )
176+ logging .Error .Printf ("http.Do() error: %v\n " , err )
177+ return
178+ } else if statusCode != 200 {
179+ logging .Error .Printf ("Not able to post after retry, with status code: %d" , statusCode )
165180 }
166-
167181 } else if response .StatusCode == 200 {
168182 logging .Info . /*Trace*/ Println ("Post of logs successful" )
169183 s .timerBetweenPost = time .Now ()
170184 }
185+ if response != nil {
186+ defer response .Body .Close ()
187+ }
188+
189+ }
190+
191+ //-------------------------------------------------
192+
193+ // MaxRetries is the maximum number of retries before bailing.
194+ var MaxRetries = 10
195+ var errMaxRetriesReached = errors .New ("exceeded retry limit" )
196+
197+ // Func represents functions that can be retried.
198+ type Func func (attempt int ) (retry bool , err error )
199+
200+ // Do keeps trying the function until the second argument
201+ // returns false, or no error is returned.
202+ func Retry (fn Func ) error {
203+ var err error
204+ var cont bool
205+ attempt := 1
206+ for {
207+ cont , err = fn (attempt )
208+ if ! cont || err == nil {
209+ break
210+ }
211+ attempt ++
212+ if attempt > MaxRetries {
213+ return errMaxRetriesReached
214+ }
215+ }
216+ return err
217+ }
171218
172- defer response .Body .Close ()
219+ // IsMaxRetries checks whether the error is due to hitting the
220+ // maximum number of retries or not.
221+ func IsMaxRetries (err error ) bool {
222+ return err == errMaxRetriesReached
173223}
0 commit comments