github.com/section/sectionctl@v1.12.3/commands/logs.go (about)

     1  package commands
     2  
     3  import (
     4  	"fmt"
     5  	"strings"
     6  	"time"
     7  
     8  	"github.com/logrusorgru/aurora" // colorable
     9  	"github.com/rs/zerolog/log"
    10  	"github.com/section/sectionctl/api"
    11  )
    12  
    13  // maxNumberLogs
    14  const maxNumberLogs = 1500
    15  
    16  // LogsCmd returns logs from an application on Section's delivery platform
    17  type LogsCmd struct {
    18  	AccountID    int    `required short:"a" help:"ID of account to query"`
    19  	AppID        int    `required short:"i" help:"ID of app to query"`
    20  	AppPath      string `default:"nodejs" help:"Path of NodeJS application in environment repository."`
    21  	InstanceName string `default:"" help:"Specific instance of NodeJS application running on Section platform."`
    22  	Number       int    `short:"n" default:100 help:"Number of log lines to fetch."`
    23  	Follow       bool   `help:"Displays recent logs and leaves the session open for logs to stream in. --instance-name required."`
    24  	// StartTimestamp  int    `default:0 help:"Start of log time stamp to fetch."`
    25  	// EndTimestamp    int    `default:0 help:"End of log time stamp to fetch."`
    26  }
    27  
    28  // Run executes the command
    29  func (c *LogsCmd) Run(cli *CLI, logWriters *LogWriters) (err error) {
    30  	s := NewSpinner("Getting logs from app",logWriters)
    31  	logsHeader := "\nInstanceName[Log Type]\t\t\tLog Message\n"
    32  	s.FinalMSG = logsHeader
    33  	s.Start()
    34  
    35  	if c.Number > maxNumberLogs {
    36  		return fmt.Errorf("number of logs queried cannot be over %d", maxNumberLogs)
    37  	}
    38  
    39  	var startTimestampRfc3339 string
    40  	if c.Follow {
    41  		log.Debug().Msg(fmt.Sprintln("Following logs..."))
    42  		if c.InstanceName == "" {
    43  			return fmt.Errorf("--instance-name is required when using --follow")
    44  		}
    45  		startTimestampRfc3339 = time.Now().Format(time.RFC3339)
    46  	}
    47  
    48  	if !(cli.Quiet) {
    49  		for {
    50  			appLogs, err := api.ApplicationLogs(c.AccountID, c.AppID, c.AppPath, c.InstanceName, c.Number, startTimestampRfc3339)
    51  			s.Stop()
    52  			if err != nil {
    53  				return err
    54  			}
    55  			var latestTimestamp string
    56  			for _, a := range appLogs {
    57  				a.Message = strings.TrimSpace(a.Message)
    58  
    59  				if a.Type == "app" {
    60  					log.Info().Msg(fmt.Sprintf("%s%s\t%s", aurora.Cyan(a.InstanceName), aurora.Cyan("["+a.Type+"]"), a.Message))
    61  				} else if a.Type == "access" {
    62  					log.Info().Msg(fmt.Sprintf("%s%s\t%s", aurora.Green(a.InstanceName), aurora.Green("["+a.Type+"]"), a.Message))
    63  				} else {
    64  					log.Info().Msg(fmt.Sprintf("%s[%s]\t%s", a.InstanceName, a.Type, a.Message))
    65  				}
    66  				if a.Timestamp != "" {
    67  					latestTimestamp = a.Timestamp
    68  				}
    69  			}
    70  			if !c.Follow {
    71  				break
    72  			}
    73  			if latestTimestamp == "" {
    74  				latestTimestamp = startTimestampRfc3339
    75  			}
    76  			t, err := time.Parse(time.RFC3339, latestTimestamp)
    77  			if err == nil {
    78  				t = t.Add(time.Second)
    79  				startTimestampRfc3339 = t.Format(time.RFC3339)
    80  			}
    81  			s.Prefix = ""
    82  			s.FinalMSG = ""
    83  			s.Start()
    84  			time.Sleep(5 * time.Second)
    85  		}
    86  	}
    87  	return nil
    88  }