github.com/kunnos/engine@v1.13.1/cli/command/container/logs.go (about) 1 package container 2 3 import ( 4 "fmt" 5 "io" 6 7 "golang.org/x/net/context" 8 9 "github.com/docker/docker/api/types" 10 "github.com/docker/docker/cli" 11 "github.com/docker/docker/cli/command" 12 "github.com/docker/docker/pkg/stdcopy" 13 "github.com/spf13/cobra" 14 ) 15 16 var validDrivers = map[string]bool{ 17 "json-file": true, 18 "journald": true, 19 } 20 21 type logsOptions struct { 22 follow bool 23 since string 24 timestamps bool 25 details bool 26 tail string 27 28 container string 29 } 30 31 // NewLogsCommand creates a new cobra.Command for `docker logs` 32 func NewLogsCommand(dockerCli *command.DockerCli) *cobra.Command { 33 var opts logsOptions 34 35 cmd := &cobra.Command{ 36 Use: "logs [OPTIONS] CONTAINER", 37 Short: "Fetch the logs of a container", 38 Args: cli.ExactArgs(1), 39 RunE: func(cmd *cobra.Command, args []string) error { 40 opts.container = args[0] 41 return runLogs(dockerCli, &opts) 42 }, 43 } 44 45 flags := cmd.Flags() 46 flags.BoolVarP(&opts.follow, "follow", "f", false, "Follow log output") 47 flags.StringVar(&opts.since, "since", "", "Show logs since timestamp") 48 flags.BoolVarP(&opts.timestamps, "timestamps", "t", false, "Show timestamps") 49 flags.BoolVar(&opts.details, "details", false, "Show extra details provided to logs") 50 flags.StringVar(&opts.tail, "tail", "all", "Number of lines to show from the end of the logs") 51 return cmd 52 } 53 54 func runLogs(dockerCli *command.DockerCli, opts *logsOptions) error { 55 ctx := context.Background() 56 57 c, err := dockerCli.Client().ContainerInspect(ctx, opts.container) 58 if err != nil { 59 return err 60 } 61 62 if !validDrivers[c.HostConfig.LogConfig.Type] { 63 return fmt.Errorf("\"logs\" command is supported only for \"json-file\" and \"journald\" logging drivers (got: %s)", c.HostConfig.LogConfig.Type) 64 } 65 66 options := types.ContainerLogsOptions{ 67 ShowStdout: true, 68 ShowStderr: true, 69 Since: opts.since, 70 Timestamps: opts.timestamps, 71 Follow: opts.follow, 72 Tail: opts.tail, 73 Details: opts.details, 74 } 75 responseBody, err := dockerCli.Client().ContainerLogs(ctx, opts.container, options) 76 if err != nil { 77 return err 78 } 79 defer responseBody.Close() 80 81 if c.Config.Tty { 82 _, err = io.Copy(dockerCli.Out(), responseBody) 83 } else { 84 _, err = stdcopy.StdCopy(dockerCli.Out(), dockerCli.Err(), responseBody) 85 } 86 return err 87 }