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  }