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  }