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