diff --git a/main.go b/main.go index b63ee18..a7ad7e8 100644 --- a/main.go +++ b/main.go @@ -23,6 +23,9 @@ func main() { err := fmt.Errorf("error parsing arguments: %v", args.Err) panic(err) } + if args.FileOutput != "" { + defer tools.LogOutput(args.FileOutput)() + } // var file *os.File // if args.FileOutput != "" { // _, fileString, _ := tools.IsValidPath(args.FileOutput) diff --git a/tools/file-works.go b/tools/file-works.go index 445ce33..a3c97b1 100644 --- a/tools/file-works.go +++ b/tools/file-works.go @@ -2,6 +2,8 @@ package tools import ( "fmt" + "io" + "log" "os" "path/filepath" "runtime" @@ -66,3 +68,42 @@ func IsValidPath(path string) (isValid bool, absPath string, err error) { return true, absPath, nil } + +func LogOutput(logfile string) func() { + // open file read/write | create if not exist | clear file at open if exists + f, _ := os.OpenFile(logfile, os.O_RDWR|os.O_CREATE|os.O_TRUNC, 0666) + + // save existing stdout | MultiWriter writes to saved stdout and file + out := os.Stdout + mw := io.MultiWriter(out, f) + + // get pipe reader and writer | writes to pipe writer come out pipe reader + r, w, _ := os.Pipe() + + // replace stdout,stderr with pipe writer | all writes to stdout, stderr will go through pipe instead (fmt.print, log) + os.Stdout = w + os.Stderr = w + + // writes with log.Print should also write to mw + log.SetOutput(mw) + + //create channel to control exit | will block until all copies are finished + exit := make(chan bool) + + go func() { + // copy all reads from pipe to multiwriter, which writes to stdout and file + _, _ = io.Copy(mw, r) + // when r or w is closed copy will finish and true will be sent to channel + exit <- true + }() + + // function to be deferred in main until program exits + return func() { + // close writer then block on exit channel | this will let mw finish writing before the program exits + _ = w.Close() + <-exit + // close file after all writes have finished + _ = f.Close() + } + +}