1

I am dealing with logs generated in go. Things are printed to stdout and a log file using io.multiwriterlog := io.MultiWriter(os.Stdout, logfile). I would like to add timestamps to both os.Stdout and logfile.

My approach is to write a write function

type writer struct {
    io.Writer
    timeFormat string
}

func (w writer) Write(b []byte) (n int, err error) {
    return w.Writer.Write(append([]byte(time.Now().Format(w.timeFormat)), b...))
}
log := io.MultiWriter(&writer{os.Stdout, "2006/01/02 15:04:05"}, logFile)

However, it does not produce the timestamp both in Stdout and logfile. Does anyone know if there is another way to do this?

1 Answers1

2

The reason why the timestamp doesn't show up in the log file is because only your writer adds the timestamp, not io.MultiWriter().

Change your use to set the multi-writer to writer.Writer, so the timestamp will be sent to both writers: os.Stdout and logFile.

logFile := &bytes.Buffer{}
log := &writer{io.MultiWriter(os.Stdout, logFile), "2006/01/02 15:04:05"}
log.Write([]byte(" hi"))

fmt.Println("\nlogFile:", logFile)

This will output (try it on the Go Playground):

2009/11/10 23:00:00 hi
logFile: 2009/11/10 23:00:00 hi

Also note that the log package (combined with io.MultiWriter) gives you this functionality out of the box, you can set the output writer using log.SetOutput():

logFile := &bytes.Buffer{}
log.SetOutput(io.MultiWriter(os.Stdout, logFile))
log.Print("hi")

fmt.Println("logFile:", logFile)

Output (try it on the Go Playground):

2009/11/10 23:00:00 hi
logFile: 2009/11/10 23:00:00 hi

Moreover, the log package also provides formatting capabilities and configurable output.

icza
  • 389,944
  • 63
  • 907
  • 827
  • Hi icza, after I tested the first approach in your answer, it works on its own. However, when I'm using exec.Cmd{stdout: log, stderr: log}, the answer fails it unlike log := io.MultiWriter(os.Stdout, plogFile). Do you have any idea why this would happen? Thank you very much! –  Aug 16 '21 at 10:10
  • You'd better post it as a new question, with [mcve], and describe the error (what "fails" mean). – icza Aug 16 '21 at 10:36