I’m going to do something I haven’t done before in these stdlib tours, and that is skip over a huge section of the GoDoc. That’s becase a huge section here is entirely redundant with what comes later:
func Debug
func Debug(msg string, args ...any)Debug calls Logger.Debug on the default logger.
And we have virtually identical entries for each of the following:
Each of these is simply an alias to the identically named method on the default logger. So instead of going through each, let’s talk about the default logger, then we’ll talk about the respective methods when we get to that portion of the GoDoc.
During the Overview section, we already talked about the existence of the default logger. The default loger is populated and usable by, well, default. You don’t need to do anything to use it:
slog.Info("yay!")
But you may want to change it, to set its level, or where it writes. And you can do that with SetDefault:
SetDefault
func SetDefault(l *Logger)SetDefault makes l the default Logger, which is used by the top-level functions Info, Debug and so on. After this call, output from the log package’s default Logger (as with log.Print, etc.) will be logged using l’s Handler, at a level controlled by SetLogLoggerLevel.
Notably, calling slog.SetDefault also updates the log package’s default logger. Two birds with one stone!
But this also relates to why I suggest not using the default logger (in either package—log or log/slog)!
Because the default logger can be modified anywhere, it’s unreliable. Even if you’re careful to set the default logger on program start, it’s possible, even if unlikely, that some library you start importing next week will change it. (Possibly even for legitimate-seeming reasons. No ill-will is necessary for this to become problematic.)
For this reason, as well as the plethora other reasons that global instances introduce problems with regard to side effects, testing, and general architecture, my general advice is to avoid using the global logger.