@@ -20,6 +20,8 @@ import (
2020 "bytes"
2121 "encoding/binary"
2222 "io"
23+ "os"
24+ "strings"
2325 "time"
2426 "unicode/utf8"
2527
@@ -30,6 +32,7 @@ import (
3032)
3133
3234type messageProcessor struct {
35+ retryNumber int
3336}
3437
3538func (mg messageProcessor ) process (lf * logPair ) {
@@ -49,21 +52,32 @@ func (mg messageProcessor) consumeLog(lf *logPair) {
4952 // create a protobuf reader for the log stream
5053 dec := protoio .NewUint32DelimitedReader (lf .stream , binary .BigEndian , 1e6 )
5154 defer dec .Close ()
55+ defer lf .Close ()
5256 // a temp buffer for each log entry
5357 var buf logdriver.LogEntry
58+ curRetryNumber := 0
5459 for {
55- // reads a message from the log stream and put it in a buffer until the EOF
56- // if there is any other error, recreate the stream reader
60+ // reads a message from the log stream and put it in a buffer
5761 if err := dec .ReadMsg (& buf ); err != nil {
58- if err == io . EOF {
59- logrus . WithField ( "id" , lf . info . ContainerID ). WithError (err ). Debug ( "shutting down log logger" )
60- lf .stream . Close ( )
62+ // exit the loop if reader reaches EOF or the fifo is closed by the writer
63+ if err == io . EOF || err == os . ErrClosed || strings . Contains (err . Error (), "file already closed" ) {
64+ logrus . WithField ( "id" , lf .info . ContainerID ). WithError ( err ). Info ( "shutting down loggers" )
6165 return
6266 }
6367
64- logrus .WithField ("id" , lf .info .ContainerID ).WithError (err ).Debug ("Ignoring error" )
68+ // exit the loop if retry number reaches the specified number
69+ if mg .retryNumber != - 1 && curRetryNumber > mg .retryNumber {
70+ logrus .WithField ("id" , lf .info .ContainerID ).WithField ("curRetryNumber" , curRetryNumber ).WithField ("retryNumber" , mg .retryNumber ).WithError (err ).Error ("Stop retrying. Shutting down loggers" )
71+ return
72+ }
73+
74+ // if there is any other error, retry for robustness. If retryNumber is -1, retry forever
75+ curRetryNumber ++
76+ logrus .WithField ("id" , lf .info .ContainerID ).WithField ("curRetryNumber" , curRetryNumber ).WithField ("retryNumber" , mg .retryNumber ).WithError (err ).Error ("Encountered error and retrying" )
77+ time .Sleep (500 * time .Millisecond )
6578 dec = protoio .NewUint32DelimitedReader (lf .stream , binary .BigEndian , 1e6 )
6679 }
80+ curRetryNumber = 0
6781
6882 if mg .shouldSendMessage (buf .Line ) {
6983 // Append to temp buffer
@@ -85,8 +99,6 @@ func (mg messageProcessor) sendMessage(l logger.Logger, buf *logdriver.LogEntry,
8599 // Only send if partial bit is not set or temp buffer size reached max or temp buffer timer expired
86100 // Check for temp buffer timer expiration
87101 if ! buf .Partial || t .shouldFlush (time .Now ()) {
88- logrus .WithField ("id" , containerid ).WithField ("Buffer partial flag should be false:" ,
89- buf .Partial ).WithField ("Temp buffer Length:" , t .tBuf .Len ()).Debug ("Buffer details" )
90102 msg .Line = t .tBuf .Bytes ()
91103 msg .Source = buf .Source
92104 msg .Partial = buf .Partial
0 commit comments