github.com/mook-as/cf-cli@v7.0.0-beta.28.0.20200120190804-b91c115fae48+incompatible/command/v7/logs_command.go (about)

     1  package v7
     2  
     3  import (
     4  	"context"
     5  
     6  	"code.cloudfoundry.org/cli/actor/sharedaction"
     7  	"code.cloudfoundry.org/cli/actor/v7action"
     8  	"code.cloudfoundry.org/cli/api/cloudcontroller/ccv3"
     9  	"code.cloudfoundry.org/cli/command"
    10  	"code.cloudfoundry.org/cli/command/flag"
    11  	"code.cloudfoundry.org/cli/command/v7/shared"
    12  	"code.cloudfoundry.org/clock"
    13  )
    14  
    15  //go:generate counterfeiter . LogsActor
    16  
    17  type LogsActor interface {
    18  	GetStreamingLogsForApplicationByNameAndSpace(appName string, spaceGUID string, client v7action.LogCacheClient) (<-chan v7action.LogMessage, <-chan error, context.CancelFunc, v7action.Warnings, error)
    19  	GetRecentLogsForApplicationByNameAndSpace(appName string, spaceGUID string, client v7action.LogCacheClient) ([]v7action.LogMessage, v7action.Warnings, error)
    20  	ScheduleTokenRefresh() (chan bool, error)
    21  }
    22  
    23  type LogsCommand struct {
    24  	RequiredArgs    flag.AppName `positional-args:"yes"`
    25  	Recent          bool         `long:"recent" description:"Dump recent logs instead of tailing"`
    26  	usage           interface{}  `usage:"CF_NAME logs APP_NAME"`
    27  	relatedCommands interface{}  `related_commands:"app, apps, ssh"`
    28  
    29  	UI             command.UI
    30  	Config         command.Config
    31  	CC_Client      *ccv3.Client
    32  	SharedActor    command.SharedActor
    33  	Actor          LogsActor
    34  	LogCacheClient v7action.LogCacheClient
    35  }
    36  
    37  func (cmd *LogsCommand) Setup(config command.Config, ui command.UI) error {
    38  	cmd.UI = ui
    39  	cmd.Config = config
    40  	cmd.SharedActor = sharedaction.NewActor(config)
    41  
    42  	ccClient, uaaClient, err := shared.GetNewClientsAndConnectToCF(config, ui, "")
    43  	if err != nil {
    44  		return err
    45  	}
    46  	cmd.CC_Client = ccClient
    47  
    48  	cmd.Actor = v7action.NewActor(ccClient, config, nil, uaaClient, clock.NewClock())
    49  	cmd.LogCacheClient = shared.NewLogCacheClient(ccClient.Info.LogCache(), config, ui)
    50  	return nil
    51  }
    52  
    53  func (cmd LogsCommand) Execute(args []string) error {
    54  	err := cmd.SharedActor.CheckTarget(true, true)
    55  	if err != nil {
    56  		return err
    57  	}
    58  
    59  	user, err := cmd.Config.CurrentUser()
    60  	if err != nil {
    61  		return err
    62  	}
    63  
    64  	cmd.UI.DisplayTextWithFlavor("Retrieving logs for app {{.AppName}} in org {{.OrgName}} / space {{.SpaceName}} as {{.Username}}...",
    65  		map[string]interface{}{
    66  			"AppName":   cmd.RequiredArgs.AppName,
    67  			"OrgName":   cmd.Config.TargetedOrganization().Name,
    68  			"SpaceName": cmd.Config.TargetedSpace().Name,
    69  			"Username":  user.Name,
    70  		})
    71  	cmd.UI.DisplayNewline()
    72  
    73  	if cmd.Recent {
    74  		return cmd.displayRecentLogs()
    75  	}
    76  	quitNowChannel, err := cmd.Actor.ScheduleTokenRefresh()
    77  	if err != nil {
    78  		return err
    79  	}
    80  
    81  	err = cmd.streamLogs()
    82  	quitNowChannel <- true
    83  	return err
    84  }
    85  
    86  func (cmd LogsCommand) displayRecentLogs() error {
    87  	messages, warnings, err := cmd.Actor.GetRecentLogsForApplicationByNameAndSpace(
    88  		cmd.RequiredArgs.AppName,
    89  		cmd.Config.TargetedSpace().GUID,
    90  		cmd.LogCacheClient,
    91  	)
    92  
    93  	for _, message := range messages {
    94  		cmd.UI.DisplayLogMessage(message, true)
    95  	}
    96  
    97  	cmd.UI.DisplayWarnings(warnings)
    98  	return err
    99  }
   100  
   101  func (cmd LogsCommand) streamLogs() error {
   102  	messages, logErrs, cancelFunc, warnings, err := cmd.Actor.GetStreamingLogsForApplicationByNameAndSpace(
   103  		cmd.RequiredArgs.AppName,
   104  		cmd.Config.TargetedSpace().GUID,
   105  		cmd.LogCacheClient,
   106  	)
   107  
   108  	cmd.UI.DisplayWarnings(warnings)
   109  	if err != nil {
   110  		return err
   111  	}
   112  
   113  	var messagesClosed, errLogsClosed bool
   114  	for {
   115  		select {
   116  		case message, ok := <-messages:
   117  			if !ok {
   118  				messagesClosed = true
   119  				break
   120  			}
   121  
   122  			cmd.UI.DisplayLogMessage(message, true)
   123  		case logErr, ok := <-logErrs:
   124  			if !ok {
   125  				errLogsClosed = true
   126  				break
   127  			}
   128  			cancelFunc()
   129  			return logErr
   130  		}
   131  
   132  		if messagesClosed && errLogsClosed {
   133  			break
   134  		}
   135  	}
   136  
   137  	return nil
   138  }