github.com/enetx/g@v1.0.80/examples/files/stderr_to_file.go (about)

     1  package main
     2  
     3  import (
     4  	"io"
     5  	"log"
     6  	"os"
     7  
     8  	"github.com/enetx/g"
     9  )
    10  
    11  func main() {
    12  	fn := RedirectLogOutput()
    13  	defer fn()
    14  
    15  	g.NewFile("file_not_exist.txt").Stat().Unwrap()
    16  }
    17  
    18  func RedirectLogOutput() func() {
    19  	// Define the name of the log file
    20  	logfile := "logfile.txt"
    21  
    22  	// Open or create the log file in append mode with read and write permissions
    23  	f, err := os.OpenFile(logfile, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0o644)
    24  	if err != nil {
    25  		panic(err)
    26  	}
    27  
    28  	// Save the existing stdout for later use
    29  	out := os.Stdout
    30  
    31  	// Create a MultiWriter that writes to both the original stdout and the log file
    32  	mw := io.MultiWriter(out, f)
    33  
    34  	// Create a pipe to capture stdout and stderr
    35  	r, w, err := os.Pipe()
    36  	if err != nil {
    37  		panic(err)
    38  	}
    39  
    40  	// Replace stdout and stderr with the write end of the pipe
    41  	// os.Stdout = w
    42  	os.Stderr = w
    43  
    44  	// Set the log package's output to the MultiWriter, so log.Print writes to both stdout and the log file
    45  	log.SetOutput(mw)
    46  
    47  	// Create a channel to control program exit
    48  	exit := make(chan bool)
    49  
    50  	go func() {
    51  		// Copy all reads from the pipe to the MultiWriter, which writes to stdout and the log file
    52  		io.Copy(mw, r)
    53  		// Signal that copying is finished by sending true to the channel
    54  		exit <- true
    55  	}()
    56  
    57  	// Return a function that can be deferred to clean up and ensure writes finish before program exit
    58  	return func() {
    59  		// Close the write end of the pipe and wait for copying to finish
    60  		w.Close()
    61  		<-exit
    62  
    63  		// Close the log file after all writes have finished
    64  		f.Close()
    65  	}
    66  }