Merge pull request #1765 from ndeloof/log_printer

This commit is contained in:
Nicolas De loof 2021-06-09 14:24:40 +02:00 committed by GitHub
commit 3202ab93bd
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 26 additions and 20 deletions

View File

@ -19,19 +19,21 @@ package compose
import ( import (
"fmt" "fmt"
"github.com/docker/compose-cli/api/compose"
"github.com/sirupsen/logrus" "github.com/sirupsen/logrus"
) )
// LogPrinter watch application containers an collect their logs // logPrinter watch application containers an collect their logs
type LogPrinter interface { type logPrinter interface {
HandleEvent(event ContainerEvent) HandleEvent(event compose.ContainerEvent)
Run(cascadeStop bool, exitCodeFrom string, stopFn func() error) (int, error) Run(cascadeStop bool, exitCodeFrom string, stopFn func() error) (int, error)
Cancel() Cancel()
} }
// NewLogPrinter builds a LogPrinter passing containers logs to LogConsumer // newLogPrinter builds a LogPrinter passing containers logs to LogConsumer
func NewLogPrinter(consumer LogConsumer) LogPrinter { func newLogPrinter(consumer compose.LogConsumer) logPrinter {
queue := make(chan ContainerEvent) queue := make(chan compose.ContainerEvent)
printer := printer{ printer := printer{
consumer: consumer, consumer: consumer,
queue: queue, queue: queue,
@ -40,17 +42,17 @@ func NewLogPrinter(consumer LogConsumer) LogPrinter {
} }
func (p *printer) Cancel() { func (p *printer) Cancel() {
p.queue <- ContainerEvent{ p.queue <- compose.ContainerEvent{
Type: UserCancel, Type: compose.UserCancel,
} }
} }
type printer struct { type printer struct {
queue chan ContainerEvent queue chan compose.ContainerEvent
consumer LogConsumer consumer compose.LogConsumer
} }
func (p *printer) HandleEvent(event ContainerEvent) { func (p *printer) HandleEvent(event compose.ContainerEvent) {
p.queue <- event p.queue <- event
} }
@ -64,15 +66,15 @@ func (p *printer) Run(cascadeStop bool, exitCodeFrom string, stopFn func() error
event := <-p.queue event := <-p.queue
container := event.Container container := event.Container
switch event.Type { switch event.Type {
case UserCancel: case compose.UserCancel:
aborting = true aborting = true
case ContainerEventAttach: case compose.ContainerEventAttach:
if _, ok := containers[container]; ok { if _, ok := containers[container]; ok {
continue continue
} }
containers[container] = struct{}{} containers[container] = struct{}{}
p.consumer.Register(container) p.consumer.Register(container)
case ContainerEventExit: case compose.ContainerEventExit:
if !event.Restarting { if !event.Restarting {
delete(containers, container) delete(containers, container)
} }
@ -100,7 +102,7 @@ func (p *printer) Run(cascadeStop bool, exitCodeFrom string, stopFn func() error
// Last container terminated, done // Last container terminated, done
return exitCode, nil return exitCode, nil
} }
case ContainerEventLog: case compose.ContainerEventLog:
if !aborting { if !aborting {
p.consumer.Log(container, event.Service, event.Line) p.consumer.Log(container, event.Service, event.Line)
} }

View File

@ -34,7 +34,7 @@ func (s *composeService) Start(ctx context.Context, project *types.Project, opti
}) })
} }
func (s *composeService) start(ctx context.Context, project *types.Project, options compose.StartOptions, listener func(event compose.ContainerEvent)) error { func (s *composeService) start(ctx context.Context, project *types.Project, options compose.StartOptions, listener compose.ContainerEventListener) error {
if len(options.AttachTo) == 0 { if len(options.AttachTo) == 0 {
options.AttachTo = project.ServiceNames() options.AttachTo = project.ServiceNames()
} }
@ -47,7 +47,9 @@ func (s *composeService) start(ctx context.Context, project *types.Project, opti
} }
eg.Go(func() error { eg.Go(func() error {
return s.watchContainers(project, options.AttachTo, listener, attached) return s.watchContainers(project, options.AttachTo, listener, attached, func(container moby.Container) error {
return s.attachContainer(ctx, container, listener, project)
})
}) })
} }
@ -60,8 +62,10 @@ func (s *composeService) start(ctx context.Context, project *types.Project, opti
return eg.Wait() return eg.Wait()
} }
type containerWatchFn func(container moby.Container) error
// watchContainers uses engine events to capture container start/die and notify ContainerEventListener // watchContainers uses engine events to capture container start/die and notify ContainerEventListener
func (s *composeService) watchContainers(project *types.Project, services []string, listener compose.ContainerEventListener, containers Containers) error { func (s *composeService) watchContainers(project *types.Project, services []string, listener compose.ContainerEventListener, containers Containers, onStart containerWatchFn) error {
watched := map[string]int{} watched := map[string]int{}
for _, c := range containers { for _, c := range containers {
watched[c.ID] = 0 watched[c.ID] = 0
@ -118,7 +122,7 @@ func (s *composeService) watchContainers(project *types.Project, services []stri
} }
if mustAttach { if mustAttach {
// Container restarted, need to re-attach // Container restarted, need to re-attach
err := s.attachContainer(ctx, container, listener, project) err := onStart(container)
if err != nil { if err != nil {
return err return err
} }

View File

@ -47,7 +47,7 @@ func (s *composeService) Up(ctx context.Context, project *types.Project, options
return err return err
} }
printer := compose.NewLogPrinter(options.Start.Attach) printer := newLogPrinter(options.Start.Attach)
signalChan := make(chan os.Signal, 1) signalChan := make(chan os.Signal, 1)
signal.Notify(signalChan, syscall.SIGINT, syscall.SIGTERM) signal.Notify(signalChan, syscall.SIGINT, syscall.SIGTERM)