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  }