GoLang write STDOUT and STDERR to log15 file
Clash Royale CLAN TAG#URR8PPP
GoLang write STDOUT and STDERR to log15 file
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
gopkg.in/inconshreveable/log15.v2
2 Answers
2
For creating a log file to log data of stderr or stdout. Create a file using OpenFile
and then SetOutput
to the file as.
OpenFile
SetOutput
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
@Priya what do you mean by unexpected case. If you have encountered one, Please add some code snippet to recreate the case in your post.
– Himanshu
Aug 6 at 14:50
The Application runs as .exe in windows environment . All my panic errors are logged by log15 into a log file. I faced a Runtime exception which I have not handled by
defer
. This has killed my application without writing any errors in logfile making it hard to debug– Priya
Aug 6 at 15:00
defer
@Priya On killing the application If the log is reporting
Fatal
error using log.Fatal
. Then In case of error it will not log the error it will exit from the program.– Himanshu
Aug 6 at 15:03
Fatal
log.Fatal
In my case, the error is written to stderr, but not to file
– Priya
Aug 6 at 15:04
You could capture os.Stdout
with a pipe and redirect the output to the actual stdout and your file using a io.MultiWriter
os.Stdout
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 + "n"))
()
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
os.Stderr
You'll have to find how to get a handle on the log15
file though, but that shouldn't be too hard
log15
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
By clicking "Post Your Answer", you acknowledge that you have read our updated terms of service, privacy policy and cookie policy, and that your continued use of the website is subject to these policies.
This is for known error cases, how to log the errors of unexpected cases
– Priya
Aug 6 at 14:49