github.com/olljanat/moby@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  }