logs.go 2.2 KB

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