Skip to content

Commit

Permalink
save-output-to-file-01; working first version
Browse files Browse the repository at this point in the history
  • Loading branch information
aguzmans committed Feb 26, 2024
1 parent e3a760f commit be27056
Show file tree
Hide file tree
Showing 2 changed files with 44 additions and 0 deletions.
3 changes: 3 additions & 0 deletions main.go
Original file line number Diff line number Diff line change
Expand Up @@ -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)
Expand Down
41 changes: 41 additions & 0 deletions tools/file-works.go
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,8 @@ package tools

import (
"fmt"
"io"
"log"
"os"
"path/filepath"
"runtime"
Expand Down Expand Up @@ -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()
}

}

0 comments on commit be27056

Please sign in to comment.