github.com/kaisenlinux/docker.io@v0.0.0-20230510090727-ea55db55fac7/swarmkit/cmd/swarmctl/service/logs.go (about) 1 package service 2 3 import ( 4 "context" 5 "fmt" 6 "io" 7 "os" 8 9 "github.com/docker/swarmkit/api" 10 "github.com/docker/swarmkit/cmd/swarmctl/common" 11 "github.com/pkg/errors" 12 "github.com/spf13/cobra" 13 ) 14 15 var ( 16 logsCmd = &cobra.Command{ 17 Use: "logs <service ID...>", 18 Short: "Obtain log output from a service", 19 Aliases: []string{"log"}, 20 RunE: func(cmd *cobra.Command, args []string) error { 21 if len(args) == 0 { 22 return errors.New("missing service IDs") 23 } 24 25 follow, err := cmd.Flags().GetBool("follow") 26 if err != nil { 27 return err 28 } 29 30 ctx := context.Background() 31 conn, err := common.DialConn(cmd) 32 if err != nil { 33 return err 34 } 35 36 c := api.NewControlClient(conn) 37 r := common.NewResolver(cmd, c) 38 39 serviceIDs := []string{} 40 for _, arg := range args { 41 service, err := getService(common.Context(cmd), c, arg) 42 if err != nil { 43 return err 44 } 45 serviceIDs = append(serviceIDs, service.ID) 46 } 47 48 client := api.NewLogsClient(conn) 49 stream, err := client.SubscribeLogs(ctx, &api.SubscribeLogsRequest{ 50 Selector: &api.LogSelector{ 51 ServiceIDs: serviceIDs, 52 }, 53 Options: &api.LogSubscriptionOptions{ 54 Follow: follow, 55 }, 56 }) 57 if err != nil { 58 return errors.Wrap(err, "failed to subscribe to logs") 59 } 60 61 for { 62 log, err := stream.Recv() 63 if err == io.EOF { 64 return nil 65 } 66 if err != nil { 67 return errors.Wrap(err, "failed receiving stream message") 68 } 69 70 for _, msg := range log.Messages { 71 out := os.Stdout 72 if msg.Stream == api.LogStreamStderr { 73 out = os.Stderr 74 } 75 76 fmt.Fprintf(out, "%s@%s❯ ", 77 r.Resolve(api.Task{}, msg.Context.TaskID), 78 r.Resolve(api.Node{}, msg.Context.NodeID), 79 ) 80 out.Write(msg.Data) // assume new line? 81 } 82 } 83 }, 84 } 85 ) 86 87 func init() { 88 logsCmd.Flags().BoolP("follow", "f", false, "Follow log output") 89 }