aboutsummaryrefslogtreecommitdiff
path: root/cmd/podman/logs.go
blob: 0a86fa128be8650b516052591bfc57e664ed2d59 (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
package main

import (
	"time"

	"github.com/containers/libpod/cmd/podman/cliconfig"
	"github.com/containers/libpod/libpod/logs"
	"github.com/containers/libpod/pkg/adapter"
	"github.com/containers/libpod/pkg/util"
	"github.com/pkg/errors"
	"github.com/spf13/cobra"
)

var (
	logsCommand     cliconfig.LogsValues
	logsDescription = `Retrieves logs for one or more containers.

  This does not guarantee execution order when combined with podman run (i.e. your run may not have generated any logs at the time you execute podman logs).
`
	_logsCommand = &cobra.Command{
		Use:   "logs [flags] CONTAINER [CONTAINER...]",
		Short: "Fetch the logs of a container",
		Long:  logsDescription,
		RunE: func(cmd *cobra.Command, args []string) error {
			logsCommand.InputArgs = args
			logsCommand.GlobalFlags = MainGlobalOpts
			logsCommand.Remote = remoteclient
			return logsCmd(&logsCommand)
		},
		Args: func(cmd *cobra.Command, args []string) error {
			if len(args) > 0 && logsCommand.Latest {
				return errors.New("no containers can be specified when using 'latest'")
			}
			if !logsCommand.Latest && len(args) < 1 {
				return errors.New("specify at least one container name or ID to log")
			}
			return nil
		},
		Example: `podman logs ctrID
  podman logs --names ctrID1 ctrID2
  podman logs --tail 2 mywebserver
  podman logs --follow=true --since 10m ctrID
  podman logs mywebserver mydbserver`,
	}
)

func init() {
	logsCommand.Command = _logsCommand
	logsCommand.SetHelpTemplate(HelpTemplate())
	logsCommand.SetUsageTemplate(UsageTemplate())
	flags := logsCommand.Flags()
	flags.BoolVar(&logsCommand.Details, "details", false, "Show extra details provided to the logs")
	flags.BoolVarP(&logsCommand.Follow, "follow", "f", false, "Follow log output.  The default is false")
	flags.BoolVarP(&logsCommand.Latest, "latest", "l", false, "Act on the latest container podman is aware of")
	flags.StringVar(&logsCommand.Since, "since", "", "Show logs since TIMESTAMP")
	flags.Int64Var(&logsCommand.Tail, "tail", -1, "Output the specified number of LINES at the end of the logs.  Defaults to -1, which prints all lines")
	flags.BoolVarP(&logsCommand.Timestamps, "timestamps", "t", false, "Output the timestamps in the log")
	flags.BoolVarP(&logsCommand.UseName, "names", "n", false, "Output the container name in the log")
	markFlagHidden(flags, "details")
	flags.SetInterspersed(false)

	markFlagHiddenForRemoteClient("latest", flags)
}

func logsCmd(c *cliconfig.LogsValues) error {
	var err error

	runtime, err := adapter.GetRuntime(getContext(), &c.PodmanCommand)
	if err != nil {
		return errors.Wrapf(err, "could not get runtime")
	}
	defer runtime.DeferredShutdown(false)

	sinceTime := time.Time{}
	if c.Flag("since").Changed {
		// parse time, error out if something is wrong
		since, err := util.ParseInputTime(c.Since)
		if err != nil {
			return errors.Wrapf(err, "could not parse time: %q", c.Since)
		}
		sinceTime = since
	}

	options := &logs.LogOptions{
		Details:    c.Details,
		Follow:     c.Follow,
		Since:      sinceTime,
		Tail:       c.Tail,
		Timestamps: c.Timestamps,
		UseName:    c.UseName,
	}
	return runtime.Log(c, options)
}