In some languages, usually scripting but some compiled ones, it’s possible to execute code whilst piping all subsequent output to a custom stream.
I’m creating a piece of software that will run completely unattended and am currently replacing the global Stdout/Stderr streams with one that I can access remotely and persistently, however I would like to divide these up. Because of how I’ve got logging configured, there’s a very simple way to do that, since loggers are created using a factory method. Example:
var debug, info, warn, critical = logging.NewLoggers("modules.gnr")
I could simply make this factory method write to a specific stream according to the provided logger namespace, but there’s an extra little detail, and that is… I’m also using Cron(-ish) jobs, and I would like each execution of the job to have it’s own log. Since the loggers are created on a package-level basis, I can’t see how I would go about doing this without passing these level-logger values around (which sounds like hell)
I had the idea of using Context (with a pointer to the relevant logger), and passing the Context around, but I really don’t want to. Is there a different, not-totally-disgusting way to do this?
Would appreciate any help. I wouldn’t say I’m new to Go, but this is by far the biggest project I’ve done in it.
You could make the loggers globally available in each package and create the loggers in the init() function which is run before main.
package somepackage
import (
"logging"
)
// Variables are global in package
var debug, info, warn, critical logging.Logger
// initalize the loggers
func init() {
debug, info, warn, critical = logging.NewLoggers("somepackage")
}
// use them in function
func someFunc() {
user, err := CurrentUser()
if err != nil {
critical.Log("Current user not found")
} else {
info.Logf("Current user is %s", user)
}
...
This is effectively what I was doing. Issue is I needed it to be “instance specific”. I ended up using context anyway, and making a single custom Logger abstraction that has Info/Infof, Warn/Warnf, etc. Then a helper method: log := logger.GetLoggers(context)