github.com/opencontainers/runc@v1.2.0-rc.1.0.20240520010911-492dc558cdd6/libcontainer/logs/logs.go (about) 1 package logs 2 3 import ( 4 "bufio" 5 "encoding/json" 6 "io" 7 8 "github.com/sirupsen/logrus" 9 ) 10 11 func ForwardLogs(logPipe io.ReadCloser) chan error { 12 done := make(chan error, 1) 13 s := bufio.NewScanner(logPipe) 14 15 logger := logrus.StandardLogger() 16 if logger.ReportCaller { 17 // Need a copy of the standard logger, but with ReportCaller 18 // turned off, as the logs are merely forwarded and their 19 // true source is not this file/line/function. 20 logNoCaller := *logrus.StandardLogger() 21 logNoCaller.ReportCaller = false 22 logger = &logNoCaller 23 } 24 25 go func() { 26 for s.Scan() { 27 processEntry(s.Bytes(), logger) 28 } 29 if err := logPipe.Close(); err != nil { 30 logrus.Errorf("error closing log source: %v", err) 31 } 32 // The only error we want to return is when reading from 33 // logPipe has failed. 34 done <- s.Err() 35 close(done) 36 }() 37 38 return done 39 } 40 41 func processEntry(text []byte, logger *logrus.Logger) { 42 if len(text) == 0 { 43 return 44 } 45 46 var jl struct { 47 Level logrus.Level `json:"level"` 48 Msg string `json:"msg"` 49 } 50 if err := json.Unmarshal(text, &jl); err != nil { 51 logrus.Errorf("failed to decode %q to json: %v", text, err) 52 return 53 } 54 55 logger.Log(jl.Level, jl.Msg) 56 }