@@ -63,7 +63,7 @@ func (s *composeService) Logs(
6363 eg , ctx := errgroup .WithContext (ctx )
6464 for _ , ctr := range containers {
6565 eg .Go (func () error {
66- err := s .logContainers (ctx , consumer , ctr , options )
66+ err := s .logContainer (ctx , consumer , ctr , options )
6767 var notImplErr errdefs.ErrNotImplemented
6868 if errors .As (err , & notImplErr ) {
6969 logrus .Warnf ("Can't retrieve logs for %q: %s" , getCanonicalContainerName (ctr ), err .Error ())
@@ -74,34 +74,21 @@ func (s *composeService) Logs(
7474 }
7575
7676 if options .Follow {
77- containers = containers .filter (isRunning ())
7877 printer := newLogPrinter (consumer )
79- eg .Go (func () error {
80- _ , err := printer .Run (api .CascadeIgnore , "" , nil )
81- return err
82- })
83-
84- for _ , c := range containers {
85- printer .HandleEvent (api.ContainerEvent {
86- Type : api .ContainerEventAttach ,
87- Container : getContainerNameWithoutProject (c ),
88- ID : c .ID ,
89- Service : c .Labels [api .ServiceLabel ],
90- })
91- }
78+ eg .Go (printer .Run )
9279
93- eg .Go (func () error {
94- err := s .watchContainers (ctx , projectName , options .Services , nil , printer .HandleEvent , containers , func (c container.Summary , t time.Time ) error {
95- printer .HandleEvent (api.ContainerEvent {
96- Type : api .ContainerEventAttach ,
97- Container : getContainerNameWithoutProject (c ),
98- ID : c .ID ,
99- Service : c .Labels [api .ServiceLabel ],
100- })
80+ monitor := newMonitor (s .apiClient (), options .Project )
81+ monitor .withListener (func (event api.ContainerEvent ) {
82+ if event .Type == api .ContainerEventStarted {
10183 eg .Go (func () error {
102- err := s .logContainers (ctx , consumer , c , api.LogOptions {
84+ ctr , err := s .apiClient ().ContainerInspect (ctx , event .ID )
85+ if err != nil {
86+ return err
87+ }
88+
89+ err = s .doLogContainer (ctx , consumer , event .Source , ctr , api.LogOptions {
10390 Follow : options .Follow ,
104- Since : t .Format (time .RFC3339Nano ),
91+ Since : time . Unix ( 0 , event . Time ) .Format (time .RFC3339Nano ),
10592 Until : options .Until ,
10693 Tail : options .Tail ,
10794 Timestamps : options .Timestamps ,
@@ -113,31 +100,28 @@ func (s *composeService) Logs(
113100 }
114101 return err
115102 })
116- return nil
117- }, func (c container.Summary , t time.Time ) error {
118- printer .HandleEvent (api.ContainerEvent {
119- Type : api .ContainerEventAttach ,
120- Container : "" , // actual name will be set by start event
121- ID : c .ID ,
122- Service : c .Labels [api .ServiceLabel ],
123- })
124- return nil
125- })
126- printer .Stop ()
127- return err
103+ }
104+ })
105+ eg .Go (func () error {
106+ defer printer .Stop ()
107+ return monitor .Start (ctx )
128108 })
129109 }
130110
131111 return eg .Wait ()
132112}
133113
134- func (s * composeService ) logContainers (ctx context.Context , consumer api.LogConsumer , c container.Summary , options api.LogOptions ) error {
135- cnt , err := s .apiClient ().ContainerInspect (ctx , c .ID )
114+ func (s * composeService ) logContainer (ctx context.Context , consumer api.LogConsumer , c container.Summary , options api.LogOptions ) error {
115+ ctr , err := s .apiClient ().ContainerInspect (ctx , c .ID )
136116 if err != nil {
137117 return err
138118 }
119+ name := getContainerNameWithoutProject (c )
120+ return s .doLogContainer (ctx , consumer , name , ctr , options )
121+ }
139122
140- r , err := s .apiClient ().ContainerLogs (ctx , cnt .ID , container.LogsOptions {
123+ func (s * composeService ) doLogContainer (ctx context.Context , consumer api.LogConsumer , name string , ctr container.InspectResponse , options api.LogOptions ) error {
124+ r , err := s .apiClient ().ContainerLogs (ctx , ctr .ID , container.LogsOptions {
141125 ShowStdout : true ,
142126 ShowStderr : true ,
143127 Follow : options .Follow ,
@@ -151,11 +135,10 @@ func (s *composeService) logContainers(ctx context.Context, consumer api.LogCons
151135 }
152136 defer r .Close () //nolint:errcheck
153137
154- name := getContainerNameWithoutProject (c )
155138 w := utils .GetWriter (func (line string ) {
156139 consumer .Log (name , line )
157140 })
158- if cnt .Config .Tty {
141+ if ctr .Config .Tty {
159142 _ , err = io .Copy (w , r )
160143 } else {
161144 _ , err = stdcopy .StdCopy (w , w , r )
0 commit comments