Skip to content
This repository was archived by the owner on Jul 18, 2025. It is now read-only.

Commit 7a4e111

Browse files
authored
Merge pull request #1852 from ulyssessouza/logs-follow-scale
2 parents ba4a742 + 287f315 commit 7a4e111

File tree

4 files changed

+76
-62
lines changed

4 files changed

+76
-62
lines changed

kube/compose.go

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -101,7 +101,7 @@ func (s *composeService) up(ctx context.Context, project *types.Project) error {
101101
})
102102

103103
} else {
104-
//update stack
104+
// update stack
105105
eventName = "Updating Compose stack"
106106
w.Event(progress.CreatingEvent(eventName))
107107

pkg/api/proxy.go

Lines changed: 26 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -96,7 +96,7 @@ func (s *ServiceProxy) WithInterceptor(interceptors ...Interceptor) *ServiceProx
9696
return s
9797
}
9898

99-
//Build implements Service interface
99+
// Build implements Service interface
100100
func (s *ServiceProxy) Build(ctx context.Context, project *types.Project, options BuildOptions) error {
101101
if s.BuildFn == nil {
102102
return ErrNotImplemented
@@ -107,7 +107,7 @@ func (s *ServiceProxy) Build(ctx context.Context, project *types.Project, option
107107
return s.BuildFn(ctx, project, options)
108108
}
109109

110-
//Push implements Service interface
110+
// Push implements Service interface
111111
func (s *ServiceProxy) Push(ctx context.Context, project *types.Project, options PushOptions) error {
112112
if s.PushFn == nil {
113113
return ErrNotImplemented
@@ -118,7 +118,7 @@ func (s *ServiceProxy) Push(ctx context.Context, project *types.Project, options
118118
return s.PushFn(ctx, project, options)
119119
}
120120

121-
//Pull implements Service interface
121+
// Pull implements Service interface
122122
func (s *ServiceProxy) Pull(ctx context.Context, project *types.Project, options PullOptions) error {
123123
if s.PullFn == nil {
124124
return ErrNotImplemented
@@ -129,7 +129,7 @@ func (s *ServiceProxy) Pull(ctx context.Context, project *types.Project, options
129129
return s.PullFn(ctx, project, options)
130130
}
131131

132-
//Create implements Service interface
132+
// Create implements Service interface
133133
func (s *ServiceProxy) Create(ctx context.Context, project *types.Project, options CreateOptions) error {
134134
if s.CreateFn == nil {
135135
return ErrNotImplemented
@@ -140,7 +140,7 @@ func (s *ServiceProxy) Create(ctx context.Context, project *types.Project, optio
140140
return s.CreateFn(ctx, project, options)
141141
}
142142

143-
//Start implements Service interface
143+
// Start implements Service interface
144144
func (s *ServiceProxy) Start(ctx context.Context, project *types.Project, options StartOptions) error {
145145
if s.StartFn == nil {
146146
return ErrNotImplemented
@@ -151,7 +151,7 @@ func (s *ServiceProxy) Start(ctx context.Context, project *types.Project, option
151151
return s.StartFn(ctx, project, options)
152152
}
153153

154-
//Restart implements Service interface
154+
// Restart implements Service interface
155155
func (s *ServiceProxy) Restart(ctx context.Context, project *types.Project, options RestartOptions) error {
156156
if s.RestartFn == nil {
157157
return ErrNotImplemented
@@ -162,7 +162,7 @@ func (s *ServiceProxy) Restart(ctx context.Context, project *types.Project, opti
162162
return s.RestartFn(ctx, project, options)
163163
}
164164

165-
//Stop implements Service interface
165+
// Stop implements Service interface
166166
func (s *ServiceProxy) Stop(ctx context.Context, project *types.Project, options StopOptions) error {
167167
if s.StopFn == nil {
168168
return ErrNotImplemented
@@ -173,7 +173,7 @@ func (s *ServiceProxy) Stop(ctx context.Context, project *types.Project, options
173173
return s.StopFn(ctx, project, options)
174174
}
175175

176-
//Up implements Service interface
176+
// Up implements Service interface
177177
func (s *ServiceProxy) Up(ctx context.Context, project *types.Project, options UpOptions) error {
178178
if s.UpFn == nil {
179179
return ErrNotImplemented
@@ -184,39 +184,39 @@ func (s *ServiceProxy) Up(ctx context.Context, project *types.Project, options U
184184
return s.UpFn(ctx, project, options)
185185
}
186186

187-
//Down implements Service interface
187+
// Down implements Service interface
188188
func (s *ServiceProxy) Down(ctx context.Context, project string, options DownOptions) error {
189189
if s.DownFn == nil {
190190
return ErrNotImplemented
191191
}
192192
return s.DownFn(ctx, project, options)
193193
}
194194

195-
//Logs implements Service interface
196-
func (s *ServiceProxy) Logs(ctx context.Context, project string, consumer LogConsumer, options LogOptions) error {
195+
// Logs implements Service interface
196+
func (s *ServiceProxy) Logs(ctx context.Context, projectName string, consumer LogConsumer, options LogOptions) error {
197197
if s.LogsFn == nil {
198198
return ErrNotImplemented
199199
}
200-
return s.LogsFn(ctx, project, consumer, options)
200+
return s.LogsFn(ctx, projectName, consumer, options)
201201
}
202202

203-
//Ps implements Service interface
203+
// Ps implements Service interface
204204
func (s *ServiceProxy) Ps(ctx context.Context, project string, options PsOptions) ([]ContainerSummary, error) {
205205
if s.PsFn == nil {
206206
return nil, ErrNotImplemented
207207
}
208208
return s.PsFn(ctx, project, options)
209209
}
210210

211-
//List implements Service interface
211+
// List implements Service interface
212212
func (s *ServiceProxy) List(ctx context.Context, options ListOptions) ([]Stack, error) {
213213
if s.ListFn == nil {
214214
return nil, ErrNotImplemented
215215
}
216216
return s.ListFn(ctx, options)
217217
}
218218

219-
//Convert implements Service interface
219+
// Convert implements Service interface
220220
func (s *ServiceProxy) Convert(ctx context.Context, project *types.Project, options ConvertOptions) ([]byte, error) {
221221
if s.ConvertFn == nil {
222222
return nil, ErrNotImplemented
@@ -227,7 +227,7 @@ func (s *ServiceProxy) Convert(ctx context.Context, project *types.Project, opti
227227
return s.ConvertFn(ctx, project, options)
228228
}
229229

230-
//Kill implements Service interface
230+
// Kill implements Service interface
231231
func (s *ServiceProxy) Kill(ctx context.Context, project *types.Project, options KillOptions) error {
232232
if s.KillFn == nil {
233233
return ErrNotImplemented
@@ -238,7 +238,7 @@ func (s *ServiceProxy) Kill(ctx context.Context, project *types.Project, options
238238
return s.KillFn(ctx, project, options)
239239
}
240240

241-
//RunOneOffContainer implements Service interface
241+
// RunOneOffContainer implements Service interface
242242
func (s *ServiceProxy) RunOneOffContainer(ctx context.Context, project *types.Project, options RunOptions) (int, error) {
243243
if s.RunOneOffContainerFn == nil {
244244
return 0, ErrNotImplemented
@@ -249,7 +249,7 @@ func (s *ServiceProxy) RunOneOffContainer(ctx context.Context, project *types.Pr
249249
return s.RunOneOffContainerFn(ctx, project, options)
250250
}
251251

252-
//Remove implements Service interface
252+
// Remove implements Service interface
253253
func (s *ServiceProxy) Remove(ctx context.Context, project *types.Project, options RemoveOptions) error {
254254
if s.RemoveFn == nil {
255255
return ErrNotImplemented
@@ -260,7 +260,7 @@ func (s *ServiceProxy) Remove(ctx context.Context, project *types.Project, optio
260260
return s.RemoveFn(ctx, project, options)
261261
}
262262

263-
//Exec implements Service interface
263+
// Exec implements Service interface
264264
func (s *ServiceProxy) Exec(ctx context.Context, project *types.Project, options RunOptions) (int, error) {
265265
if s.ExecFn == nil {
266266
return 0, ErrNotImplemented
@@ -271,7 +271,7 @@ func (s *ServiceProxy) Exec(ctx context.Context, project *types.Project, options
271271
return s.ExecFn(ctx, project, options)
272272
}
273273

274-
//Copy implements Service interface
274+
// Copy implements Service interface
275275
func (s *ServiceProxy) Copy(ctx context.Context, project *types.Project, options CopyOptions) error {
276276
if s.CopyFn == nil {
277277
return ErrNotImplemented
@@ -282,47 +282,47 @@ func (s *ServiceProxy) Copy(ctx context.Context, project *types.Project, options
282282
return s.CopyFn(ctx, project, options)
283283
}
284284

285-
//Pause implements Service interface
285+
// Pause implements Service interface
286286
func (s *ServiceProxy) Pause(ctx context.Context, project string, options PauseOptions) error {
287287
if s.PauseFn == nil {
288288
return ErrNotImplemented
289289
}
290290
return s.PauseFn(ctx, project, options)
291291
}
292292

293-
//UnPause implements Service interface
293+
// UnPause implements Service interface
294294
func (s *ServiceProxy) UnPause(ctx context.Context, project string, options PauseOptions) error {
295295
if s.UnPauseFn == nil {
296296
return ErrNotImplemented
297297
}
298298
return s.UnPauseFn(ctx, project, options)
299299
}
300300

301-
//Top implements Service interface
301+
// Top implements Service interface
302302
func (s *ServiceProxy) Top(ctx context.Context, project string, services []string) ([]ContainerProcSummary, error) {
303303
if s.TopFn == nil {
304304
return nil, ErrNotImplemented
305305
}
306306
return s.TopFn(ctx, project, services)
307307
}
308308

309-
//Events implements Service interface
309+
// Events implements Service interface
310310
func (s *ServiceProxy) Events(ctx context.Context, project string, options EventsOptions) error {
311311
if s.EventsFn == nil {
312312
return ErrNotImplemented
313313
}
314314
return s.EventsFn(ctx, project, options)
315315
}
316316

317-
//Port implements Service interface
317+
// Port implements Service interface
318318
func (s *ServiceProxy) Port(ctx context.Context, project string, service string, port int, options PortOptions) (string, int, error) {
319319
if s.PortFn == nil {
320320
return "", 0, ErrNotImplemented
321321
}
322322
return s.PortFn(ctx, project, service, port, options)
323323
}
324324

325-
//Images implements Service interface
325+
// Images implements Service interface
326326
func (s *ServiceProxy) Images(ctx context.Context, project string, options ImagesOptions) ([]ImageSummary, error) {
327327
if s.ImagesFn == nil {
328328
return nil, ErrNotImplemented

pkg/compose/logs.go

Lines changed: 46 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -20,54 +20,68 @@ import (
2020
"context"
2121
"io"
2222

23-
"github.com/docker/compose-cli/pkg/api"
24-
"github.com/docker/docker/api/types"
2523
"github.com/docker/docker/pkg/stdcopy"
2624
"golang.org/x/sync/errgroup"
2725

26+
"github.com/docker/compose-cli/pkg/api"
2827
"github.com/docker/compose-cli/pkg/utils"
28+
"github.com/docker/docker/api/types"
2929
)
3030

3131
func (s *composeService) Logs(ctx context.Context, projectName string, consumer api.LogConsumer, options api.LogOptions) error {
3232
containers, err := s.getContainers(ctx, projectName, oneOffExclude, true, options.Services...)
33-
3433
if err != nil {
3534
return err
3635
}
37-
eg, ctx := errgroup.WithContext(ctx)
38-
for _, c := range containers {
39-
service := c.Labels[api.ServiceLabel]
40-
container, err := s.apiClient.ContainerInspect(ctx, c.ID)
41-
if err != nil {
42-
return err
43-
}
4436

45-
name := getContainerNameWithoutProject(c)
37+
eg, ctx := errgroup.WithContext(ctx)
38+
if options.Follow {
4639
eg.Go(func() error {
47-
r, err := s.apiClient.ContainerLogs(ctx, container.ID, types.ContainerLogsOptions{
48-
ShowStdout: true,
49-
ShowStderr: true,
50-
Follow: options.Follow,
51-
Since: options.Since,
52-
Until: options.Until,
53-
Tail: options.Tail,
54-
Timestamps: options.Timestamps,
40+
printer := newLogPrinter(consumer)
41+
return s.watchContainers(projectName, options.Services, printer.HandleEvent, containers, func(c types.Container) error {
42+
return s.logContainers(ctx, consumer, c, options)
5543
})
56-
if err != nil {
57-
return err
58-
}
59-
defer r.Close() // nolint errcheck
44+
})
45+
}
6046

61-
w := utils.GetWriter(func(line string) {
62-
consumer.Log(name, service, line)
63-
})
64-
if container.Config.Tty {
65-
_, err = io.Copy(w, r)
66-
} else {
67-
_, err = stdcopy.StdCopy(w, w, r)
68-
}
69-
return err
47+
for _, c := range containers {
48+
c := c
49+
eg.Go(func() error {
50+
return s.logContainers(ctx, consumer, c, options)
7051
})
7152
}
7253
return eg.Wait()
7354
}
55+
56+
func (s *composeService) logContainers(ctx context.Context, consumer api.LogConsumer, c types.Container, options api.LogOptions) error {
57+
cnt, err := s.apiClient.ContainerInspect(ctx, c.ID)
58+
if err != nil {
59+
return err
60+
}
61+
62+
service := c.Labels[api.ServiceLabel]
63+
r, err := s.apiClient.ContainerLogs(ctx, cnt.ID, types.ContainerLogsOptions{
64+
ShowStdout: true,
65+
ShowStderr: true,
66+
Follow: options.Follow,
67+
Since: options.Since,
68+
Until: options.Until,
69+
Tail: options.Tail,
70+
Timestamps: options.Timestamps,
71+
})
72+
if err != nil {
73+
return err
74+
}
75+
defer r.Close() // nolint errcheck
76+
77+
name := getContainerNameWithoutProject(c)
78+
w := utils.GetWriter(func(line string) {
79+
consumer.Log(name, service, line)
80+
})
81+
if cnt.Config.Tty {
82+
_, err = io.Copy(w, r)
83+
} else {
84+
_, err = stdcopy.StdCopy(w, w, r)
85+
}
86+
return err
87+
}

pkg/compose/start.go

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -47,7 +47,7 @@ func (s *composeService) start(ctx context.Context, project *types.Project, opti
4747
}
4848

4949
eg.Go(func() error {
50-
return s.watchContainers(project, options.AttachTo, listener, attached, func(container moby.Container) error {
50+
return s.watchContainers(project.Name, options.AttachTo, listener, attached, func(container moby.Container) error {
5151
return s.attachContainer(ctx, container, listener, project)
5252
})
5353
})
@@ -69,14 +69,14 @@ func (s *composeService) start(ctx context.Context, project *types.Project, opti
6969
type containerWatchFn func(container moby.Container) error
7070

7171
// watchContainers uses engine events to capture container start/die and notify ContainerEventListener
72-
func (s *composeService) watchContainers(project *types.Project, services []string, listener api.ContainerEventListener, containers Containers, onStart containerWatchFn) error {
72+
func (s *composeService) watchContainers(projectName string, services []string, listener api.ContainerEventListener, containers Containers, onStart containerWatchFn) error {
7373
watched := map[string]int{}
7474
for _, c := range containers {
7575
watched[c.ID] = 0
7676
}
7777

7878
ctx, stop := context.WithCancel(context.Background())
79-
err := s.Events(ctx, project.Name, api.EventsOptions{
79+
err := s.Events(ctx, projectName, api.EventsOptions{
8080
Services: services,
8181
Consumer: func(event api.Event) error {
8282
inspected, err := s.apiClient.ContainerInspect(ctx, event.Container)

0 commit comments

Comments
 (0)