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