diff --git a/cmd/uncloud/service/logs.go b/cmd/uncloud/service/logs.go index dcc647d2..7a6406ee 100644 --- a/cmd/uncloud/service/logs.go +++ b/cmd/uncloud/service/logs.go @@ -99,15 +99,17 @@ If no services are specified, streams logs from all services defined in the Comp func runLogs(ctx context.Context, uncli *cli.CLI, serviceNames []string, opts logsOptions) error { // If no services specified, try to load them from the Compose file(s). + fromCompose := false if len(serviceNames) == 0 { + fromCompose = true project, err := compose.LoadProject(ctx, opts.files) if err != nil { - return fmt.Errorf("load compose file(s): %w", err) + return fmt.Errorf("load Compose file(s): %w", err) } // View logs for all services, including disabled by inactive profiles. serviceNames = append(project.ServiceNames(), project.DisabledServiceNames()...) if len(serviceNames) == 0 { - return errors.New("no services found in compose file(s)") + return errors.New("no services found in Compose file(s)") } } @@ -135,20 +137,40 @@ func runLogs(ctx context.Context, uncli *cli.CLI, serviceNames []string, opts lo Machines: cli.ExpandCommaSeparatedValues(opts.machines), } - // Collect log streams from all services. + // Collect log streams from all services. When service names come from a Compose file, + // skip the ones that are not found in the cluster (they may have been removed or not deployed yet). machineIDsSet := mapset.NewSet[string]() svcStreams := make([]<-chan api.ServiceLogEntry, 0, len(serviceNames)) + var foundServices, notFoundServices []string + for _, serviceName := range serviceNames { svc, ch, err := c.ServiceLogs(ctx, serviceName, logsOpts) if err != nil { + if errors.Is(err, api.ErrNotFound) && fromCompose { + notFoundServices = append(notFoundServices, serviceName) + continue + } return fmt.Errorf("stream logs for service '%s': %w", serviceName, err) } svcStreams = append(svcStreams, ch) + foundServices = append(foundServices, serviceName) machineIDs := svc.MachineIDs() machineIDsSet.Append(machineIDs...) } + if fromCompose { + if len(foundServices) == 0 { + return fmt.Errorf("stream logs for services defined in %s: no services found in the cluster", + strings.Join(opts.files, ", ")) + } + serviceNames = foundServices + + for _, name := range notFoundServices { + client.PrintWarning(fmt.Sprintf("service '%s' not found in the cluster, skipping", name)) + } + } + var stream <-chan api.ServiceLogEntry if len(serviceNames) == 1 { stream = svcStreams[0]