diff --git a/README.md b/README.md index e679a01..cf12f74 100644 --- a/README.md +++ b/README.md @@ -67,6 +67,7 @@ USAGE: OPTIONS: --rate, -r "3s" rds log polling rate + --file, -f "trace/alert_DATABASE.log.2017-09-27" name of the logfile ------------------------------------------------------------ ยป ./rdstail tail -h @@ -79,5 +80,6 @@ USAGE: OPTIONS: --lines, -n "20" output the last n lines. use 0 for a full dump of the most recent file + --file, -f "trace/alert_DATABASE.log.2017-09-27" name of the logfile ``` diff --git a/main.go b/main.go index 78cb237..a2bd478 100644 --- a/main.go +++ b/main.go @@ -12,8 +12,8 @@ import ( "github.com/aws/aws-sdk-go/aws" "github.com/aws/aws-sdk-go/aws/session" "github.com/aws/aws-sdk-go/service/rds" - "github.com/urfave/cli" "github.com/litl/rdstail/src" + "github.com/urfave/cli" ) func fie(e error) { @@ -54,14 +54,28 @@ func parseDB(c *cli.Context) string { return db } +func parseFile(c *cli.Context) string { + file := c.String("file") + return file +} + func watch(c *cli.Context) { r := setupRDS(c) db := parseDB(c) rate := parseRate(c) - + file := parseFile(c) stop := make(chan struct{}) go signalListen(stop) + if file != "" { + err := rdstail.WatchFile(r, db, rate, file, func(lines string) error { + fmt.Print(lines) + return nil + }, stop) + + fie(err) + } + err := rdstail.Watch(r, db, rate, func(lines string) error { fmt.Print(lines) return nil @@ -97,7 +111,12 @@ func papertrail(c *cli.Context) { func tail(c *cli.Context) { r := setupRDS(c) db := parseDB(c) + file := parseFile(c) numLines := int64(c.Int("lines")) + if file != "" { + err := rdstail.TailFile(r, db, file, numLines) + fie(err) + } err := rdstail.Tail(r, db, numLines) fie(err) } @@ -167,6 +186,10 @@ func main() { Value: "3s", Usage: "rds log polling rate", }, + cli.StringFlag{ + Name: "file, f", + Usage: "name of the logfile to watch", + }, }, }, @@ -180,6 +203,10 @@ func main() { Value: 20, Usage: "output the last n lines. use 0 for a full dump of the most recent file", }, + cli.StringFlag{ + Name: "file, f", + Usage: "name of the logfile to tail", + }, }, }, } diff --git a/src/rdstail.go b/src/rdstail.go index ce2f0d8..c8edcb8 100644 --- a/src/rdstail.go +++ b/src/rdstail.go @@ -126,6 +126,17 @@ func Tail(r *rds.RDS, db string, numLines int64) error { return nil } +func TailFile(r *rds.RDS, db string, file string, numLines int64) error { + logFile := &rds.DescribeDBLogFilesDetails{LogFileName: aws.String(file)} + + tail, _, err := tailLogFile(r, db, *logFile.LogFileName, numLines, "") + if err != nil { + return err + } + fmt.Println(tail) + return nil +} + func Watch(r *rds.RDS, db string, rate time.Duration, callback func(string) error, stop <-chan struct{}) error { // Periodically check for new log files (unless there is a way to detect the file is done being written to) // Poll that log file, retaining the marker @@ -179,8 +190,40 @@ func Watch(r *rds.RDS, db string, rate time.Duration, callback func(string) erro return nil } } +} - return nil +func WatchFile(r *rds.RDS, db string, rate time.Duration, file string, callback func(string) error, stop <-chan struct{}) error { + logFile := &rds.DescribeDBLogFilesDetails{LogFileName: aws.String(file)} + + // Get a marker for the end of the log file by requesting the most recent line + lines, marker, err := tailLogFile(r, db, *logFile.LogFileName, 1, "") + if err != nil { + return err + } + + t := time.NewTicker(rate) + empty := 0 + const checkLogfileRate = 4 + for { + select { + case <-t.C: + lines, marker, err = tailLogFile(r, db, *logFile.LogFileName, 0, marker) + if err != nil { + return err + } + + if lines == "" { + empty++ + } else { + empty = 0 + if err := callback(lines); err != nil { + return err + } + } + case <-stop: + return nil + } + } } func FeedPapertrail(r *rds.RDS, db string, rate time.Duration, papertrailHost, app, hostname string, stop <-chan struct{}) error {