GoLang将STDOUT和STDERR写入log15文件

I have GoLang Application where I use log15 to write logs to a file. The package I use for log15 is gopkg.in/inconshreveable/log15.v2 I run into a situation where I want to write the information of STDERR and STDOUT to the same file where I write log15 logs. Is there any possible ways to achieve the same

For creating a log file to log data of stderr or stdout. Create a file using OpenFile and then SetOutput to the file as.

f, err := os.OpenFile("EDUC_LOG", os.O_RDWR|os.O_CREATE|os.O_APPEND, 0664)

if err != nil {
    panic(err)
}

defer f.Close()

log.SetOutput(f)

This will print the output to log file everytime you try to log some value like in case of an error as

if err != nil{
       log.Println(err) // this will create a file if not created to output the log in a file.
}

Edited:

Fatal error will print the output on stdout rather than in a file, Since the program will exit before writing anything to the file.

package main

import (
    "log"
)

func main() {
    log.Println("error1")
    log.Fatal("error1")
    log.Println("error2") // this will not print since the program will exit the main with fatal error
}

Playground Example

You could capture os.Stdout with a pipe and redirect the output to the actual stdout and your file using a io.MultiWriter

f, _ := os.OpenFile("my.log", os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0664)
multiWriter := io.MultiWriter(os.Stdout, f)
rd, wr, err := os.Pipe()
if err != nil {
    os.Exit(1)
}

// overwrite os.Stdout
os.Stdout = wr

go func() {
    scanner := bufio.NewScanner(rd)
    for scanner.Scan() {
        stdoutLine := scanner.Text()
        multiWriter.Write([]byte(stdoutLine + "
"))
    }
}()


fmt.Println("foobar")

// hacky sleep to ensure the go routine can write before program exits
time.Sleep(time.Second) 

You can apply the same with os.Stderr of course

You'll have to find how to get a handle on the log15 file though, but that shouldn't be too hard

The issue you might have with this approach is that there is no guarantee that the goroutine will do its job when the program ends (see the sleep hack), not sure how to achieve that