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 }