github.com/ssdev-go/moby@v17.12.1-ce-rc2+incompatible/client/container_logs.go (about) 1 package client 2 3 import ( 4 "io" 5 "net/url" 6 "time" 7 8 "golang.org/x/net/context" 9 10 "github.com/docker/docker/api/types" 11 timetypes "github.com/docker/docker/api/types/time" 12 ) 13 14 // ContainerLogs returns the logs generated by a container in an io.ReadCloser. 15 // It's up to the caller to close the stream. 16 // 17 // The stream format on the response will be in one of two formats: 18 // 19 // If the container is using a TTY, there is only a single stream (stdout), and 20 // data is copied directly from the container output stream, no extra 21 // multiplexing or headers. 22 // 23 // If the container is *not* using a TTY, streams for stdout and stderr are 24 // multiplexed. 25 // The format of the multiplexed stream is as follows: 26 // 27 // [8]byte{STREAM_TYPE, 0, 0, 0, SIZE1, SIZE2, SIZE3, SIZE4}[]byte{OUTPUT} 28 // 29 // STREAM_TYPE can be 1 for stdout and 2 for stderr 30 // 31 // SIZE1, SIZE2, SIZE3, and SIZE4 are four bytes of uint32 encoded as big endian. 32 // This is the size of OUTPUT. 33 // 34 // You can use github.com/docker/docker/pkg/stdcopy.StdCopy to demultiplex this 35 // stream. 36 func (cli *Client) ContainerLogs(ctx context.Context, container string, options types.ContainerLogsOptions) (io.ReadCloser, error) { 37 query := url.Values{} 38 if options.ShowStdout { 39 query.Set("stdout", "1") 40 } 41 42 if options.ShowStderr { 43 query.Set("stderr", "1") 44 } 45 46 if options.Since != "" { 47 ts, err := timetypes.GetTimestamp(options.Since, time.Now()) 48 if err != nil { 49 return nil, err 50 } 51 query.Set("since", ts) 52 } 53 54 if options.Until != "" { 55 ts, err := timetypes.GetTimestamp(options.Until, time.Now()) 56 if err != nil { 57 return nil, err 58 } 59 query.Set("until", ts) 60 } 61 62 if options.Timestamps { 63 query.Set("timestamps", "1") 64 } 65 66 if options.Details { 67 query.Set("details", "1") 68 } 69 70 if options.Follow { 71 query.Set("follow", "1") 72 } 73 query.Set("tail", options.Tail) 74 75 resp, err := cli.get(ctx, "/containers/"+container+"/logs", query, nil) 76 if err != nil { 77 return nil, err 78 } 79 return resp.body, nil 80 }