// Events returns a stream of events in the daemon in a ReadCloser. // It's up to the caller to close the stream. func (cli *Client) Events(options types.EventsOptions) (io.ReadCloser, error) { query := url.Values{} ref := time.Now() if options.Since != "" { ts, err := timeutils.GetTimestamp(options.Since, ref) if err != nil { return nil, err } query.Set("since", ts) } if options.Until != "" { ts, err := timeutils.GetTimestamp(options.Until, ref) if err != nil { return nil, err } query.Set("until", ts) } if options.Filters.Len() > 0 { filterJSON, err := filters.ToParam(options.Filters) if err != nil { return nil, err } query.Set("filters", filterJSON) } serverResponse, err := cli.get("/events", query, nil) if err != nil { return nil, err } return serverResponse.body, nil }
// CmdEvents prints a live stream of real time events from the server. // // Usage: docker events [OPTIONS] func (cli *DockerCli) CmdEvents(args ...string) error { cmd := Cli.Subcmd("events", nil, Cli.DockerCommands["events"].Description, true) since := cmd.String([]string{"-since"}, "", "Show all events created since timestamp") until := cmd.String([]string{"-until"}, "", "Stream events until this timestamp") flFilter := opts.NewListOpts(nil) cmd.Var(&flFilter, []string{"f", "-filter"}, "Filter output based on conditions provided") cmd.Require(flag.Exact, 0) cmd.ParseFlags(args, true) var ( v = url.Values{} eventFilterArgs = filters.NewArgs() ) // Consolidate all filter flags, and sanity check them early. // They'll get process in the daemon/server. for _, f := range flFilter.GetAll() { var err error eventFilterArgs, err = filters.ParseFlag(f, eventFilterArgs) if err != nil { return err } } ref := time.Now() if *since != "" { ts, err := timeutils.GetTimestamp(*since, ref) if err != nil { return err } v.Set("since", ts) } if *until != "" { ts, err := timeutils.GetTimestamp(*until, ref) if err != nil { return err } v.Set("until", ts) } if eventFilterArgs.Len() > 0 { filterJSON, err := filters.ToParam(eventFilterArgs) if err != nil { return err } v.Set("filters", filterJSON) } sopts := &streamOpts{ rawTerminal: true, out: cli.out, } if _, err := cli.stream("GET", "/events?"+v.Encode(), sopts); err != nil { return err } return nil }
// ContainerLogs returns the logs generated by a container in an io.ReadCloser. // It's up to the caller to close the stream. func (cli *Client) ContainerLogs(options types.ContainerLogsOptions) (io.ReadCloser, error) { query := url.Values{} if options.ShowStdout { query.Set("stdout", "1") } if options.ShowStderr { query.Set("stderr", "1") } if options.Since != "" { ts, err := timeutils.GetTimestamp(options.Since, time.Now()) if err != nil { return nil, err } query.Set("since", ts) } if options.Timestamps { query.Set("timestamps", "1") } if options.Follow { query.Set("follow", "1") } query.Set("tail", options.Tail) resp, err := cli.get("/containers/"+options.ContainerID+"/logs", query, nil) if err != nil { return nil, err } return resp.body, nil }
// CmdLogs fetches the logs of a given container. // // docker logs [OPTIONS] CONTAINER func (cli *DockerCli) CmdLogs(args ...string) error { cmd := Cli.Subcmd("logs", []string{"CONTAINER"}, Cli.DockerCommands["logs"].Description, true) follow := cmd.Bool([]string{"f", "-follow"}, false, "Follow log output") since := cmd.String([]string{"-since"}, "", "Show logs since timestamp") times := cmd.Bool([]string{"t", "-timestamps"}, false, "Show timestamps") tail := cmd.String([]string{"-tail"}, "all", "Number of lines to show from the end of the logs") cmd.Require(flag.Exact, 1) cmd.ParseFlags(args, true) name := cmd.Arg(0) serverResp, err := cli.call("GET", "/containers/"+name+"/json", nil, nil) if err != nil { return err } var c types.ContainerJSON if err := json.NewDecoder(serverResp.body).Decode(&c); err != nil { return err } if !validDrivers[c.HostConfig.LogConfig.Type] { return fmt.Errorf("\"logs\" command is supported only for \"json-file\" and \"journald\" logging drivers (got: %s)", c.HostConfig.LogConfig.Type) } v := url.Values{} v.Set("stdout", "1") v.Set("stderr", "1") if *since != "" { ts, err := timeutils.GetTimestamp(*since, time.Now()) if err != nil { return err } v.Set("since", ts) } if *times { v.Set("timestamps", "1") } if *follow { v.Set("follow", "1") } v.Set("tail", *tail) sopts := &streamOpts{ rawTerminal: c.Config.Tty, out: cli.out, err: cli.err, } _, err = cli.stream("GET", "/containers/"+name+"/logs?"+v.Encode(), sopts) return err }
// CmdLogs fetches the logs of a given container. // // docker logs [OPTIONS] CONTAINER func (cli *DockerCli) CmdLogs(args ...string) error { var ( cmd = cli.Subcmd("logs", "CONTAINER", "Fetch the logs of a container", true) follow = cmd.Bool([]string{"f", "-follow"}, false, "Follow log output") since = cmd.String([]string{"-since"}, "", "Show logs since timestamp") times = cmd.Bool([]string{"t", "-timestamps"}, false, "Show timestamps") tail = cmd.String([]string{"-tail"}, "all", "Number of lines to show from the end of the logs") ) cmd.Require(flag.Exact, 1) cmd.ParseFlags(args, true) name := cmd.Arg(0) stream, _, _, err := cli.call("GET", "/containers/"+name+"/json", nil, nil) if err != nil { return err } var c types.ContainerJSON if err := json.NewDecoder(stream).Decode(&c); err != nil { return err } if logType := c.HostConfig.LogConfig.Type; logType != "json-file" { return fmt.Errorf("\"logs\" command is supported only for \"json-file\" logging driver (got: %s)", logType) } v := url.Values{} v.Set("stdout", "1") v.Set("stderr", "1") if *since != "" { v.Set("since", timeutils.GetTimestamp(*since, time.Now())) } if *times { v.Set("timestamps", "1") } if *follow { v.Set("follow", "1") } v.Set("tail", *tail) sopts := &streamOpts{ rawTerminal: c.Config.Tty, out: cli.out, err: cli.err, } return cli.stream("GET", "/containers/"+name+"/logs?"+v.Encode(), sopts) }
// CmdLogs fetches the logs of a given container. // // docker logs [OPTIONS] CONTAINER func (cli *DockerCli) CmdLogs(args ...string) error { cmd := Cli.Subcmd("logs", []string{"CONTAINER"}, "Fetch the logs of a container", true) follow := cmd.Bool([]string{"f", "-follow"}, false, "Follow log output") since := cmd.String([]string{"-since"}, "", "Show logs since timestamp") times := cmd.Bool([]string{"t", "-timestamps"}, false, "Show timestamps") tail := cmd.String([]string{"-tail"}, "all", "Number of lines to show from the end of the logs") cmd.Require(flag.Exact, 1) cmd.ParseFlags(args, true) name := cmd.Arg(0) serverResp, err := cli.call("GET", "/containers/"+name+"/json", nil, nil) if err != nil { return err } var c types.ContainerJSON if err := json.NewDecoder(serverResp.body).Decode(&c); err != nil { return err } v := url.Values{} v.Set("stdout", "1") v.Set("stderr", "1") if *since != "" { v.Set("since", timeutils.GetTimestamp(*since, time.Now())) } if *times { v.Set("timestamps", "1") } if *follow { v.Set("follow", "1") } v.Set("tail", *tail) sopts := &streamOpts{ rawTerminal: c.Config.Tty, out: cli.out, err: cli.err, } _, err = cli.stream("GET", "/containers/"+name+"/logs?"+v.Encode(), sopts) return err }
func (cli *HyperClient) HyperCmdLogs(args ...string) error { var opts struct { Follow bool `short:"f" long:"follow" default:"false" default-mask:"-" description:"Follow log output"` Since string `long:"since" value-name:"\"\"" description:"Show logs since timestamp"` Times bool `short:"t" long:"timestamps" default:"false" default-mask:"-" description:"Show timestamps"` Tail string `long:"tail" value-name:"\"all\"" description:"Number of lines to show from the end of the logs"` } var parser = gflag.NewParser(&opts, gflag.Default|gflag.IgnoreUnknown) parser.Usage = "logs CONTAINER [OPTIONS...]\n\nFetch the logs of a container" args, err := parser.ParseArgs(args) if err != nil { if !strings.Contains(err.Error(), "Usage") { return err } else { return nil } } if len(args) == 0 { return fmt.Errorf("%s ERROR: Can not accept the 'logs' command without argument!\n", os.Args[0]) } v := url.Values{} v.Set("container", args[0]) v.Set("stdout", "yes") v.Set("stderr", "yes") if opts.Since != "" { v.Set("since", timeutils.GetTimestamp(opts.Since, time.Now())) } if opts.Times { v.Set("timestamps", "yes") } if opts.Follow { v.Set("follow", "yes") } v.Set("tail", opts.Tail) headers := http.Header(make(map[string][]string)) return cli.stream("GET", "/container/logs?"+v.Encode(), nil, cli.out, headers) }