github.com/orteth01/up@v0.2.0/internal/cli/logs/logs.go (about) 1 package logs 2 3 import ( 4 "io" 5 "os" 6 "time" 7 8 "github.com/apex/up/internal/cli/root" 9 "github.com/apex/up/internal/stats" 10 "github.com/pkg/errors" 11 "github.com/tj/kingpin" 12 ) 13 14 func init() { 15 cmd := root.Command("logs", "Show log output.") 16 cmd.Example(`up logs`, "Show logs from the past 5 minutes.") 17 cmd.Example(`up logs -s 30m`, "Show logs from the past 30 minutes.") 18 cmd.Example(`up logs -s 5h`, "Show logs from the past 5 hours.") 19 cmd.Example(`up logs -f`, "Show live log output.") 20 cmd.Example(`up logs error`, "Show error logs.") 21 cmd.Example(`up logs 'error or fatal'`, "Show error and fatal logs.") 22 cmd.Example(`up logs 'not info'`, "Show non-info logs.") 23 cmd.Example(`up logs 'message = "user login"'`, "Show logs with a specific message.") 24 cmd.Example(`up logs 'status = 200 duration > 150'`, "Show 200 responses with latency above 150ms.") 25 cmd.Example(`up logs 'status >= 400'`, "Show 4xx and 5xx responses.") 26 cmd.Example(`up logs 'user.email contains "@apex.sh"'`, "Show emails containing @apex.sh.") 27 cmd.Example(`up logs 'user.email = "*@apex.sh"'`, "Show emails ending with @apex.sh.") 28 cmd.Example(`up logs 'user.email = "tj@*"'`, "Show emails starting with tj@.") 29 cmd.Example(`up logs 'method in ("POST", "PUT") ip = "207.*" status = 200 duration >= 50'`, "Show logs with a more complex query.") 30 cmd.Example(`up logs error | jq`, "Pipe JSON error logs to the jq tool.") 31 32 // TODO: query arg should join remaining args 33 query := cmd.Arg("query", "Query pattern for filtering logs.").String() 34 follow := cmd.Flag("follow", "Follow or tail the live logs.").Short('f').Bool() 35 since := cmd.Flag("since", "Show logs since duration (30s, 5m, 2h, 1h30m).").Short('s').Default("5m").Duration() 36 37 cmd.Action(func(_ *kingpin.ParseContext) error { 38 c, p, err := root.Init() 39 if err != nil { 40 return errors.Wrap(err, "initializing") 41 } 42 43 q := *query 44 s := *since 45 46 if *follow { 47 s = time.Duration(0) 48 } 49 50 stats.Track("Logs", map[string]interface{}{ 51 "query": q != "", 52 "query_length": len(q), 53 "follow": *follow, 54 "since": s.Round(time.Second), 55 }) 56 57 // TODO: region flag 58 region := c.Regions[0] 59 logs := p.Logs(region, q) 60 logs.Since(time.Now().Add(-s)) 61 62 if *follow { 63 logs.Follow() 64 } 65 66 if _, err := io.Copy(os.Stdout, logs); err != nil { 67 return errors.Wrap(err, "writing logs") 68 } 69 70 return nil 71 }) 72 }