github.com/hanks177/podman/v4@v4.1.3-0.20220613032544-16d90015bc83/pkg/bindings/containers/logs.go (about) 1 package containers 2 3 import ( 4 "context" 5 "fmt" 6 "io" 7 "net/http" 8 "strconv" 9 10 "github.com/hanks177/podman/v4/pkg/bindings" 11 "github.com/pkg/errors" 12 ) 13 14 // Logs obtains a container's logs given the options provided. The logs are then sent to the 15 // stdout|stderr channels as strings. 16 func Logs(ctx context.Context, nameOrID string, options *LogOptions, stdoutChan, stderrChan chan string) error { 17 if options == nil { 18 options = new(LogOptions) 19 } 20 conn, err := bindings.GetClient(ctx) 21 if err != nil { 22 return err 23 } 24 params, err := options.ToParams() 25 if err != nil { 26 return err 27 } 28 // The API requires either stdout|stderr be used. If neither are specified, we specify stdout 29 if options.Stdout == nil && options.Stderr == nil { 30 params.Set("stdout", strconv.FormatBool(true)) 31 } 32 response, err := conn.DoRequest(ctx, nil, http.MethodGet, "/containers/%s/logs", params, nil, nameOrID) 33 if err != nil { 34 return err 35 } 36 defer response.Body.Close() 37 38 buffer := make([]byte, 1024) 39 for { 40 fd, l, err := DemuxHeader(response.Body, buffer) 41 if err != nil { 42 if errors.Is(err, io.EOF) || errors.Is(err, io.ErrUnexpectedEOF) { 43 return nil 44 } 45 return err 46 } 47 frame, err := DemuxFrame(response.Body, buffer, l) 48 if err != nil { 49 return err 50 } 51 52 switch fd { 53 case 0: 54 stdoutChan <- string(frame) 55 case 1: 56 stdoutChan <- string(frame) 57 case 2: 58 stderrChan <- string(frame) 59 case 3: 60 return errors.New("from service in stream: " + string(frame)) 61 default: 62 return fmt.Errorf("unrecognized input header: %d", fd) 63 } 64 } 65 }