github.1git.de/docker/cli@v26.1.3+incompatible/cli/command/container/logs.go (about)

     1  package container
     2  
     3  import (
     4  	"context"
     5  	"io"
     6  
     7  	"github.com/docker/cli/cli"
     8  	"github.com/docker/cli/cli/command"
     9  	"github.com/docker/cli/cli/command/completion"
    10  	"github.com/docker/docker/api/types/container"
    11  	"github.com/docker/docker/pkg/stdcopy"
    12  	"github.com/spf13/cobra"
    13  )
    14  
    15  type logsOptions struct {
    16  	follow     bool
    17  	since      string
    18  	until      string
    19  	timestamps bool
    20  	details    bool
    21  	tail       string
    22  
    23  	container string
    24  }
    25  
    26  // NewLogsCommand creates a new cobra.Command for `docker logs`
    27  func NewLogsCommand(dockerCli command.Cli) *cobra.Command {
    28  	var opts logsOptions
    29  
    30  	cmd := &cobra.Command{
    31  		Use:   "logs [OPTIONS] CONTAINER",
    32  		Short: "Fetch the logs of a container",
    33  		Args:  cli.ExactArgs(1),
    34  		RunE: func(cmd *cobra.Command, args []string) error {
    35  			opts.container = args[0]
    36  			return runLogs(cmd.Context(), dockerCli, &opts)
    37  		},
    38  		Annotations: map[string]string{
    39  			"aliases": "docker container logs, docker logs",
    40  		},
    41  		ValidArgsFunction: completion.ContainerNames(dockerCli, true),
    42  	}
    43  
    44  	flags := cmd.Flags()
    45  	flags.BoolVarP(&opts.follow, "follow", "f", false, "Follow log output")
    46  	flags.StringVar(&opts.since, "since", "", `Show logs since timestamp (e.g. "2013-01-02T13:23:37Z") or relative (e.g. "42m" for 42 minutes)`)
    47  	flags.StringVar(&opts.until, "until", "", `Show logs before a timestamp (e.g. "2013-01-02T13:23:37Z") or relative (e.g. "42m" for 42 minutes)`)
    48  	flags.SetAnnotation("until", "version", []string{"1.35"})
    49  	flags.BoolVarP(&opts.timestamps, "timestamps", "t", false, "Show timestamps")
    50  	flags.BoolVar(&opts.details, "details", false, "Show extra details provided to logs")
    51  	flags.StringVarP(&opts.tail, "tail", "n", "all", "Number of lines to show from the end of the logs")
    52  	return cmd
    53  }
    54  
    55  func runLogs(ctx context.Context, dockerCli command.Cli, opts *logsOptions) error {
    56  	c, err := dockerCli.Client().ContainerInspect(ctx, opts.container)
    57  	if err != nil {
    58  		return err
    59  	}
    60  
    61  	responseBody, err := dockerCli.Client().ContainerLogs(ctx, c.ID, container.LogsOptions{
    62  		ShowStdout: true,
    63  		ShowStderr: true,
    64  		Since:      opts.since,
    65  		Until:      opts.until,
    66  		Timestamps: opts.timestamps,
    67  		Follow:     opts.follow,
    68  		Tail:       opts.tail,
    69  		Details:    opts.details,
    70  	})
    71  	if err != nil {
    72  		return err
    73  	}
    74  	defer responseBody.Close()
    75  
    76  	if c.Config.Tty {
    77  		_, err = io.Copy(dockerCli.Out(), responseBody)
    78  	} else {
    79  		_, err = stdcopy.StdCopy(dockerCli.Out(), dockerCli.Err(), responseBody)
    80  	}
    81  	return err
    82  }