I’m new to setting up logging from scratch and im not aware of the best practices to do so in go. I’m using the charmbracelet/log library and this is how I’m setting up the logger in the main.go using the init function
func init() {
log.SetReportCaller(true)
log.SetReportTimestamp(true)
log.SetTimeFormat(time.Kitchen)
log.SetPrefix("Ares")
log.SetLevel(log.DebugLevel) // TODO : make configurable
log.SetFormatter(log.TextFormatter) // TODO : make configurable
}
With this approach, I’m not sure how to set it up to also spit out a log file when the program shuts down.
I am planning on generating a lot of logs and then use those logs as an excuse to setup elk stack along with Grafana and Prometheus just because I have an excuse to set those up in my project that is going to have multiple microservices some in go and some in python.
I’d really appreciate it if you had some advice on setting up robust logging and observability in general as well.
I did ask this to perplexity and it basically told me to use the io.Multiwriter construct to achieve this https://www.perplexity.ai/search/how-can-i-setup-logging-in-gol-YHG8eEgbTTW1JrGCKSl1.g#0
I was wondering if there is a better way to do this instead of the way given above.
theredditbandit is a new contributor to this site. Take care in asking for clarification, commenting, and answering.
Check out our Code of Conduct.
1
With this approach, I’m not sure how to set it up to also spit out a log file when the program shuts down.
First, open your output file with os.OpenFile. If successful, you’ll end up with an os.File, which implements io.Writer
. os.Stderr
also implements io.Writer
.
Write to both io.Writer
s at once with io.MultiWriter.
Finally, you can set that as your log’s output with log.SetOutput.
It might end up looking something like this:
package main
import (
"io"
"log"
"os"
"os/exec"
)
func main() {
if f, err := os.OpenFile("/tmp/f", os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0644); err != nil {
panic(err)
} else {
defer f.Close()
log.SetOutput(io.MultiWriter(f, os.Stderr))
}
for i := 0; i < 3; i++ {
log.Print("Hello World!")
cmd := exec.Command("wc", "/tmp/f")
cmd.Stdout = os.Stdout
cmd.Stderr = os.Stderr
if err := cmd.Run(); err != nil {
panic(err)
}
}
}