introduce compose logs --index to select a replica container

Signed-off-by: Amit Saha <asaha@atlassian.com>
Signed-off-by: Nicolas De Loof <nicolas.deloof@gmail.com>
This commit is contained in:
Amit Saha 2023-02-06 21:21:29 +11:00 committed by Nicolas De loof
parent 8c964f5ad3
commit 750553c866
5 changed files with 27 additions and 10 deletions

View File

@ -18,6 +18,7 @@ package compose
import ( import (
"context" "context"
"errors"
"github.com/docker/cli/cli/command" "github.com/docker/cli/cli/command"
"github.com/spf13/cobra" "github.com/spf13/cobra"
@ -49,11 +50,17 @@ func logsCommand(p *ProjectOptions, dockerCli command.Cli, backend api.Service)
RunE: Adapt(func(ctx context.Context, args []string) error { RunE: Adapt(func(ctx context.Context, args []string) error {
return runLogs(ctx, dockerCli, backend, opts, args) return runLogs(ctx, dockerCli, backend, opts, args)
}), }),
PreRunE: func(cmd *cobra.Command, args []string) error {
if opts.index > 0 && len(args) != 1 {
return errors.New("--index requires one service to be selected")
}
return nil
},
ValidArgsFunction: completeServiceNames(dockerCli, p), ValidArgsFunction: completeServiceNames(dockerCli, p),
} }
flags := logsCmd.Flags() flags := logsCmd.Flags()
flags.BoolVarP(&opts.follow, "follow", "f", false, "Follow log output.") flags.BoolVarP(&opts.follow, "follow", "f", false, "Follow log output.")
flags.IntVar(&opts.index, "index", 1, "index of the container if there are multiple instances of a service [default: 1].") flags.IntVar(&opts.index, "index", 0, "index of the container if service has multiple replicas")
flags.StringVar(&opts.since, "since", "", "Show logs since timestamp (e.g. 2013-01-02T13:23:37Z) or relative (e.g. 42m for 42 minutes)") flags.StringVar(&opts.since, "since", "", "Show logs since timestamp (e.g. 2013-01-02T13:23:37Z) or relative (e.g. 42m for 42 minutes)")
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)") 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)")
flags.BoolVar(&opts.noColor, "no-color", false, "Produce monochrome output.") flags.BoolVar(&opts.noColor, "no-color", false, "Produce monochrome output.")
@ -73,6 +80,7 @@ func runLogs(ctx context.Context, dockerCli command.Cli, backend api.Service, op
Project: project, Project: project,
Services: services, Services: services,
Follow: opts.follow, Follow: opts.follow,
Index: opts.index,
Tail: opts.tail, Tail: opts.tail,
Since: opts.since, Since: opts.since,
Until: opts.until, Until: opts.until,

View File

@ -9,7 +9,7 @@ View output from containers
|:---------------------|:---------|:--------|:-----------------------------------------------------------------------------------------------| |:---------------------|:---------|:--------|:-----------------------------------------------------------------------------------------------|
| `--dry-run` | | | Execute command in dry run mode | | `--dry-run` | | | Execute command in dry run mode |
| `-f`, `--follow` | | | Follow log output. | | `-f`, `--follow` | | | Follow log output. |
| `--index` | `int` | `1` | index of the container if there are multiple instances of a service [default: 1]. | | `--index` | `int` | `0` | index of the container if service has multiple replicas |
| `--no-color` | | | Produce monochrome output. | | `--no-color` | | | Produce monochrome output. |
| `--no-log-prefix` | | | Don't print prefix in logs. | | `--no-log-prefix` | | | Don't print prefix in logs. |
| `--since` | `string` | | Show logs since timestamp (e.g. 2013-01-02T13:23:37Z) or relative (e.g. 42m for 42 minutes) | | `--since` | `string` | | Show logs since timestamp (e.g. 2013-01-02T13:23:37Z) or relative (e.g. 42m for 42 minutes) |

View File

@ -18,9 +18,8 @@ options:
swarm: false swarm: false
- option: index - option: index
value_type: int value_type: int
default_value: "1" default_value: "0"
description: | description: index of the container if service has multiple replicas
index of the container if there are multiple instances of a service [default: 1].
deprecated: false deprecated: false
hidden: false hidden: false
experimental: false experimental: false

View File

@ -488,6 +488,7 @@ type ServiceStatus struct {
// LogOptions defines optional parameters for the `Log` API // LogOptions defines optional parameters for the `Log` API
type LogOptions struct { type LogOptions struct {
Project *types.Project Project *types.Project
Index int
Services []string Services []string
Tail string Tail string
Since string Since string

View File

@ -20,7 +20,6 @@ import (
"context" "context"
"errors" "errors"
"io" "io"
"strings"
"time" "time"
"github.com/docker/docker/api/types" "github.com/docker/docker/api/types"
@ -39,11 +38,21 @@ func (s *composeService) Logs(
consumer api.LogConsumer, consumer api.LogConsumer,
options api.LogOptions, options api.LogOptions,
) error { ) error {
projectName = strings.ToLower(projectName)
containers, err := s.getContainers(ctx, projectName, oneOffExclude, true, options.Services...) var containers Containers
if err != nil { var err error
return err
if options.Index > 0 {
container, err := s.getSpecifiedContainer(ctx, projectName, oneOffExclude, true, options.Services[0], options.Index)
if err != nil {
return err
}
containers = append(containers, container)
} else {
containers, err = s.getContainers(ctx, projectName, oneOffExclude, true, options.Services...)
if err != nil {
return err
}
} }
if options.Project != nil && len(options.Services) == 0 { if options.Project != nil && len(options.Services) == 0 {