github.com/asifdxtreme/cli@v6.1.3-0.20150123051144-9ead8700b4ae+incompatible/cf/commands/application/logs.go (about) 1 package application 2 3 import ( 4 "fmt" 5 "time" 6 7 "github.com/cloudfoundry/cli/cf/api" 8 "github.com/cloudfoundry/cli/cf/command_metadata" 9 "github.com/cloudfoundry/cli/cf/configuration/core_config" 10 "github.com/cloudfoundry/cli/cf/errors" 11 . "github.com/cloudfoundry/cli/cf/i18n" 12 "github.com/cloudfoundry/cli/cf/models" 13 "github.com/cloudfoundry/cli/cf/requirements" 14 "github.com/cloudfoundry/cli/cf/terminal" 15 "github.com/cloudfoundry/cli/cf/ui_helpers" 16 "github.com/cloudfoundry/loggregatorlib/logmessage" 17 "github.com/codegangsta/cli" 18 ) 19 20 type Logs struct { 21 ui terminal.UI 22 config core_config.Reader 23 logsRepo api.LogsRepository 24 appReq requirements.ApplicationRequirement 25 } 26 27 func NewLogs(ui terminal.UI, config core_config.Reader, logsRepo api.LogsRepository) (cmd *Logs) { 28 cmd = new(Logs) 29 cmd.ui = ui 30 cmd.config = config 31 cmd.logsRepo = logsRepo 32 return 33 } 34 35 func (cmd *Logs) Metadata() command_metadata.CommandMetadata { 36 return command_metadata.CommandMetadata{ 37 Name: "logs", 38 Description: T("Tail or show recent logs for an app"), 39 Usage: T("CF_NAME logs APP_NAME"), 40 Flags: []cli.Flag{ 41 cli.BoolFlag{Name: "recent", Usage: T("Dump recent logs instead of tailing")}, 42 }, 43 } 44 } 45 46 func (cmd *Logs) GetRequirements(requirementsFactory requirements.Factory, c *cli.Context) (reqs []requirements.Requirement, err error) { 47 if len(c.Args()) != 1 { 48 cmd.ui.FailWithUsage(c) 49 } 50 51 cmd.appReq = requirementsFactory.NewApplicationRequirement(c.Args()[0]) 52 53 reqs = []requirements.Requirement{ 54 requirementsFactory.NewLoginRequirement(), 55 cmd.appReq, 56 } 57 58 return 59 } 60 61 func (cmd *Logs) Run(c *cli.Context) { 62 app := cmd.appReq.GetApplication() 63 64 if c.Bool("recent") { 65 cmd.recentLogsFor(app) 66 } else { 67 cmd.tailLogsFor(app) 68 } 69 } 70 71 func (cmd *Logs) recentLogsFor(app models.Application) { 72 cmd.ui.Say(T("Connected, dumping recent logs for app {{.AppName}} in org {{.OrgName}} / space {{.SpaceName}} as {{.Username}}...\n", 73 map[string]interface{}{ 74 "AppName": terminal.EntityNameColor(app.Name), 75 "OrgName": terminal.EntityNameColor(cmd.config.OrganizationFields().Name), 76 "SpaceName": terminal.EntityNameColor(cmd.config.SpaceFields().Name), 77 "Username": terminal.EntityNameColor(cmd.config.Username())})) 78 79 messages, err := cmd.logsRepo.RecentLogsFor(app.Guid) 80 if err != nil { 81 cmd.handleError(err) 82 } 83 84 for _, msg := range messages { 85 cmd.ui.Say("%s", LogMessageOutput(msg, time.Local)) 86 } 87 } 88 89 func (cmd *Logs) tailLogsFor(app models.Application) { 90 onConnect := func() { 91 cmd.ui.Say(T("Connected, tailing logs for app {{.AppName}} in org {{.OrgName}} / space {{.SpaceName}} as {{.Username}}...\n", 92 map[string]interface{}{ 93 "AppName": terminal.EntityNameColor(app.Name), 94 "OrgName": terminal.EntityNameColor(cmd.config.OrganizationFields().Name), 95 "SpaceName": terminal.EntityNameColor(cmd.config.SpaceFields().Name), 96 "Username": terminal.EntityNameColor(cmd.config.Username())})) 97 } 98 99 err := cmd.logsRepo.TailLogsFor(app.Guid, onConnect, func(msg *logmessage.LogMessage) { 100 cmd.ui.Say("%s", LogMessageOutput(msg, time.Local)) 101 }) 102 103 if err != nil { 104 cmd.handleError(err) 105 } 106 } 107 108 func (cmd *Logs) handleError(err error) { 109 switch err.(type) { 110 case nil: 111 case *errors.InvalidSSLCert: 112 cmd.ui.Failed(err.Error() + T("\nTIP: use 'cf login -a API --skip-ssl-validation' or 'cf api API --skip-ssl-validation' to suppress this error")) 113 default: 114 cmd.ui.Failed(err.Error()) 115 } 116 } 117 118 func LogMessageOutput(msg *logmessage.LogMessage, loc *time.Location) string { 119 logHeader, coloredLogHeader := ui_helpers.ExtractLogHeader(msg, loc) 120 logContent := ui_helpers.ExtractLogContent(msg, logHeader) 121 122 return fmt.Sprintf("%s%s", coloredLogHeader, logContent) 123 }