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 }