Skip to content
This repository was archived by the owner on Nov 27, 2023. It is now read-only.

Commit fd906c6

Browse files
authored
Merge pull request #1178 from docker/tail_logs
introduce compose logs --tail and --follow options
2 parents 166db3f + 9d9dbf3 commit fd906c6

File tree

11 files changed

+39
-45
lines changed

11 files changed

+39
-45
lines changed

api/compose/api.go

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -122,6 +122,8 @@ type ServiceStatus struct {
122122
// LogOptions defines optional parameters for the `Log` API
123123
type LogOptions struct {
124124
Services []string
125+
Tail string
126+
Follow bool
125127
}
126128

127129
const (

cli/cmd/compose/compose.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -97,7 +97,7 @@ func Command(contextType string) *cobra.Command {
9797
stopCommand(&opts),
9898
psCommand(&opts),
9999
listCommand(),
100-
logsCommand(&opts),
100+
logsCommand(&opts, contextType),
101101
convertCommand(&opts),
102102
runCommand(&opts),
103103
)

cli/cmd/compose/logs.go

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,15 +24,18 @@ import (
2424

2525
"github.com/docker/compose-cli/api/client"
2626
"github.com/docker/compose-cli/api/compose"
27+
"github.com/docker/compose-cli/api/context/store"
2728
"github.com/docker/compose-cli/cli/formatter"
2829
)
2930

3031
type logsOptions struct {
3132
*projectOptions
3233
composeOptions
34+
follow bool
35+
tail string
3336
}
3437

35-
func logsCommand(p *projectOptions) *cobra.Command {
38+
func logsCommand(p *projectOptions, contextType string) *cobra.Command {
3639
opts := logsOptions{
3740
projectOptions: p,
3841
}
@@ -43,6 +46,10 @@ func logsCommand(p *projectOptions) *cobra.Command {
4346
return runLogs(cmd.Context(), opts, args)
4447
},
4548
}
49+
logsCmd.Flags().BoolVar(&opts.follow, "follow", false, "Follow log output.")
50+
if contextType == store.DefaultContextType {
51+
logsCmd.Flags().StringVar(&opts.tail, "tail", "all", "Number of lines to show from the end of the logs for each container.")
52+
}
4653
return logsCmd
4754
}
4855

@@ -59,5 +66,7 @@ func runLogs(ctx context.Context, opts logsOptions, services []string) error {
5966
consumer := formatter.NewLogConsumer(ctx, os.Stdout)
6067
return c.ComposeService().Logs(ctx, projectName, consumer, compose.LogOptions{
6168
Services: services,
69+
Follow: opts.follow,
70+
Tail: opts.tail,
6271
})
6372
}

ecs/aws.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ type API interface {
6363
InspectSecret(ctx context.Context, id string) (secrets.Secret, error)
6464
ListSecrets(ctx context.Context) ([]secrets.Secret, error)
6565
DeleteSecret(ctx context.Context, id string, recover bool) error
66-
GetLogs(ctx context.Context, name string, consumer func(service, container, message string)) error
66+
GetLogs(ctx context.Context, name string, consumer func(service string, container string, message string), follow bool) error
6767
DescribeService(ctx context.Context, cluster string, arn string) (compose.ServiceStatus, error)
6868
DescribeServiceTasks(ctx context.Context, cluster string, project string, service string) ([]compose.ContainerSummary, error)
6969
getURLWithPortMapping(ctx context.Context, targetGroupArns []string) ([]compose.PortPublisher, error)

ecs/aws_mock.go

Lines changed: 4 additions & 4 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

ecs/logs.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -26,7 +26,7 @@ func (b *ecsAPIService) Logs(ctx context.Context, projectName string, consumer c
2626
if len(options.Services) > 0 {
2727
consumer = filteredLogConsumer(consumer, options.Services)
2828
}
29-
err := b.aws.GetLogs(ctx, projectName, consumer.Log)
29+
err := b.aws.GetLogs(ctx, projectName, consumer.Log, options.Follow)
3030
return err
3131
}
3232

ecs/sdk.go

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -805,7 +805,7 @@ func (s sdk) DeleteSecret(ctx context.Context, id string, recover bool) error {
805805
return err
806806
}
807807

808-
func (s sdk) GetLogs(ctx context.Context, name string, consumer func(service, container, message string)) error {
808+
func (s sdk) GetLogs(ctx context.Context, name string, consumer func(service string, container string, message string), follow bool) error {
809809
logGroup := fmt.Sprintf("/docker-compose/%s", name)
810810
var startTime int64
811811
for {
@@ -837,6 +837,9 @@ func (s sdk) GetLogs(ctx context.Context, name string, consumer func(service, co
837837
}
838838
}
839839
}
840+
if !follow {
841+
return nil
842+
}
840843
time.Sleep(500 * time.Millisecond)
841844
}
842845
}

local/compose/create.go

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -35,7 +35,6 @@ import (
3535
"github.com/docker/go-connections/nat"
3636
"github.com/pkg/errors"
3737
"github.com/sirupsen/logrus"
38-
"golang.org/x/sync/errgroup"
3938

4039
"github.com/docker/compose-cli/api/compose"
4140
"github.com/docker/compose-cli/api/progress"
@@ -77,15 +76,11 @@ func (s *composeService) Create(ctx context.Context, project *types.Project, opt
7776
orphans := observedState.filter(isNotService(project.ServiceNames()...))
7877
if len(orphans) > 0 {
7978
if opts.RemoveOrphans {
80-
eg, _ := errgroup.WithContext(ctx)
8179
w := progress.ContextWriter(ctx)
82-
err := s.removeContainers(ctx, w, eg, orphans)
80+
err := s.removeContainers(ctx, w, orphans)
8381
if err != nil {
8482
return err
8583
}
86-
if eg.Wait() != nil {
87-
return err
88-
}
8984
} else {
9085
logrus.Warnf("Found orphan containers (%s) for this project. If "+
9186
"you removed or renamed this service in your compose "+

local/compose/down.go

Lines changed: 10 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -33,7 +33,6 @@ import (
3333
)
3434

3535
func (s *composeService) Down(ctx context.Context, projectName string, options compose.DownOptions) error {
36-
eg, _ := errgroup.WithContext(ctx)
3736
w := progress.ContextWriter(ctx)
3837

3938
if options.Project == nil {
@@ -55,25 +54,21 @@ func (s *composeService) Down(ctx context.Context, projectName string, options c
5554

5655
err = InReverseDependencyOrder(ctx, options.Project, func(c context.Context, service types.ServiceConfig) error {
5756
serviceContainers, others := containers.split(isService(service.Name))
58-
err := s.removeContainers(ctx, w, eg, serviceContainers)
57+
err := s.removeContainers(ctx, w, serviceContainers)
5958
containers = others
6059
return err
6160
})
61+
if err != nil {
62+
return err
63+
}
6264

63-
if options.RemoveOrphans {
64-
err := s.removeContainers(ctx, w, eg, containers)
65+
if options.RemoveOrphans && len(containers) > 0 {
66+
err := s.removeContainers(ctx, w, containers)
6567
if err != nil {
6668
return err
6769
}
6870
}
6971

70-
if err != nil {
71-
return err
72-
}
73-
err = eg.Wait()
74-
if err != nil {
75-
return err
76-
}
7772
networks, err := s.apiClient.NetworkList(ctx, moby.NetworkListOptions{
7873
Filters: filters.NewArgs(
7974
projectFilter(projectName),
@@ -82,14 +77,15 @@ func (s *composeService) Down(ctx context.Context, projectName string, options c
8277
if err != nil {
8378
return err
8479
}
80+
81+
eg, _ := errgroup.WithContext(ctx)
8582
for _, n := range networks {
8683
networkID := n.ID
8784
networkName := n.Name
8885
eg.Go(func() error {
8986
return s.ensureNetworkDown(ctx, networkID, networkName)
9087
})
9188
}
92-
9389
return eg.Wait()
9490
}
9591

@@ -108,15 +104,14 @@ func (s *composeService) stopContainers(ctx context.Context, w progress.Writer,
108104
return nil
109105
}
110106

111-
func (s *composeService) removeContainers(ctx context.Context, w progress.Writer, eg *errgroup.Group, containers []moby.Container) error {
107+
func (s *composeService) removeContainers(ctx context.Context, w progress.Writer, containers []moby.Container) error {
108+
eg, _ := errgroup.WithContext(ctx)
112109
for _, container := range containers {
113110
toDelete := container
114111
eg.Go(func() error {
115112
eventName := "Container " + getCanonicalContainerName(toDelete)
116-
w.Event(progress.StoppingEvent(eventName))
117113
err := s.stopContainers(ctx, w, []moby.Container{container})
118114
if err != nil {
119-
w.Event(progress.ErrorMessageEvent(eventName, "Error while Stopping"))
120115
return err
121116
}
122117
w.Event(progress.RemovingEvent(eventName))

local/compose/logs.go

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -64,7 +64,8 @@ func (s *composeService) Logs(ctx context.Context, projectName string, consumer
6464
r, err := s.apiClient.ContainerLogs(ctx, container.ID, types.ContainerLogsOptions{
6565
ShowStdout: true,
6666
ShowStderr: true,
67-
Follow: true,
67+
Follow: options.Follow,
68+
Tail: options.Tail,
6869
})
6970
defer r.Close() // nolint errcheck
7071

0 commit comments

Comments
 (0)