Consider this package that configures a logging adapter based on the environment, and allows changes to logging output at runtime.
package mylog
import (
"log"
"os"
"io"
)
const StdOut = "STDOUT"
var logger *log.Logger
func init() {
outputLocation := os.Getenv("MY_LOG_OUTPUT")
if outputLocation == "" || outputLocation == StdOut {
log.SetOutput(os.Stdout)
return
}
f, _ := getFile(outputLocation)
log.SetOutput(f)
}
func getFile(path string) (*os.File, error) {
openFlags := os.O_WRONLY | os.O_APPEND | os.O_CREATE
f, err := os.OpenFile(path, openFlags, 0666)
if err != nil {
return nil, err
}
return f, nil
}
func SetOutput(w io.Writer) {
logger.SetOutput(w)
}
func Debug(v ...interface{}) {
log.Println(v...)
}
There are two problems that I have with this:
w
passed to SetOutput
is a Closer
.Edit: It's difficult to give a simple example of use case that causes a problem. For example, it I import this package into a simple program that runs and exits, I could expose a method to close log files and call that (with defer
or without) before that program finishes execution. The real problem is with a long-running process (like a webserver) that does not have a point that you would want to close the log unless the process dies.
So part of my question is, is it even necessary to close the file?