2

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

2 Answers 2

3

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 + "\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

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

Sign up to request clarification or add additional context in comments.

Comments

1

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

7 Comments

This is for known error cases, how to log the errors of unexpected cases
@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.
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 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.
In my case, the error is written to stderr, but not to file
|

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.