44 "bufio"
55 "io"
66 "runtime"
7+ "strings"
78)
89
910// Writer at INFO level. See WriterLevel for details.
@@ -20,15 +21,18 @@ func (logger *Logger) WriterLevel(level Level) *io.PipeWriter {
2021 return NewEntry (logger ).WriterLevel (level )
2122}
2223
24+ // Writer returns an io.Writer that writes to the logger at the info log level
2325func (entry * Entry ) Writer () * io.PipeWriter {
2426 return entry .WriterLevel (InfoLevel )
2527}
2628
29+ // WriterLevel returns an io.Writer that writes to the logger at the given log level
2730func (entry * Entry ) WriterLevel (level Level ) * io.PipeWriter {
2831 reader , writer := io .Pipe ()
2932
3033 var printFunc func (args ... interface {})
3134
35+ // Determine which log function to use based on the specified log level
3236 switch level {
3337 case TraceLevel :
3438 printFunc = entry .Trace
@@ -48,23 +52,51 @@ func (entry *Entry) WriterLevel(level Level) *io.PipeWriter {
4852 printFunc = entry .Print
4953 }
5054
55+ // Start a new goroutine to scan the input and write it to the logger using the specified print function.
56+ // It splits the input into chunks of up to 64KB to avoid buffer overflows.
5157 go entry .writerScanner (reader , printFunc )
58+
59+ // Set a finalizer function to close the writer when it is garbage collected
5260 runtime .SetFinalizer (writer , writerFinalizer )
5361
5462 return writer
5563}
5664
65+ // writerScanner scans the input from the reader and writes it to the logger
5766func (entry * Entry ) writerScanner (reader * io.PipeReader , printFunc func (args ... interface {})) {
5867 scanner := bufio .NewScanner (reader )
68+
69+ // Set the buffer size to the maximum token size to avoid buffer overflows
70+ scanner .Buffer (make ([]byte , bufio .MaxScanTokenSize ), bufio .MaxScanTokenSize )
71+
72+ // Define a split function to split the input into chunks of up to 64KB
73+ chunkSize := 64 * 1024 // 64KB
74+ splitFunc := func (data []byte , atEOF bool ) (int , []byte , error ) {
75+ if len (data ) > chunkSize {
76+ return chunkSize , data [:chunkSize ], nil
77+ }
78+
79+ return len (data ), data , nil
80+ }
81+
82+ //Use the custom split function to split the input
83+ scanner .Split (splitFunc )
84+
85+ // Scan the input and write it to the logger using the specified print function
5986 for scanner .Scan () {
60- printFunc (scanner .Text ())
87+ printFunc (strings . TrimRight ( scanner .Text (), " \r \n " ))
6188 }
89+
90+ // If there was an error while scanning the input, log an error
6291 if err := scanner .Err (); err != nil {
6392 entry .Errorf ("Error while reading from Writer: %s" , err )
6493 }
94+
95+ // Close the reader when we are done
6596 reader .Close ()
6697}
6798
99+ // WriterFinalizer is a finalizer function that closes then given writer when it is garbage collected
68100func writerFinalizer (writer * io.PipeWriter ) {
69101 writer .Close ()
70102}
0 commit comments