Using Zap - Working With Global Loggers

Sometimes instead of creating a logger and then passing it around, it is convenient to just use a global logger.

The standard log library allows you to both create a custom logger using log.New() or directly use a standard logger instance by calling the package helper functions log.Printf() and the like.

zap provides such a functionality as well using zap.L() and zap.S(), however using them didn’t seem so straight forward to me.

This post is the fourth of a series of posts showing different ways of using zap. The other posts are Simple use cases, Creating custom loggers and Custom encoders.

This documentation was written for zap v1.8.

The full source for the code extracts in the rest of the post is here

You can access the global standard logger using zap.L(). The function returns the shared logger instance. A sugared version is accessible via zap.S().

From what I have seen in my brief usage of these loggers, this shared logger is not useful out of the box - if you just use them right away, they provide no output. Their sole purpose seems to be to provide a simple way to retrieve this instance anywhere in your code.

If you really want to use this standard logger usefully, you need to replace the core of the logger with that of a different logger using zap.ReplaceGlobals().

fmt.Printf("\n*** Using the global logger out of the box\n\n")

zap.S().Infow("An info message", "iteration", 1)

fmt.Printf("\n*** After replacing the global logger with a development logger\n\n")

logger, _ := zap.NewDevelopment()
zap.ReplaceGlobals(logger)
zap.S().Infow("An info message", "iteration", 1)

Output:

*** Using the global logger out of the box


*** After replacing the global logger with a development logger

2018-05-02T16:24:40.992-0700    INFO    globallogger/main.go:17 An info message {"iteration": 1}

There is also a way provided to undo a core replacement in the global loggers.

fmt.Printf("\n*** After replacing the global logger with a development logger\n\n")
logger, _ := zap.NewDevelopment()
zap.ReplaceGlobals(logger)
zap.S().Infow("An info message", "iteration", 1)

fmt.Printf("\n*** After replacing the global logger with a production logger\n\n")
logger, _ = zap.NewProduction()
undo := zap.ReplaceGlobals(logger)
zap.S().Infow("An info message", "iteration", 1)

fmt.Printf("\n*** After undoing the last replacement of the global logger\n\n")
undo()
zap.S().Infow("An info message", "iteration", 1)

Output:

*** After replacing the global logger with a development logger

2018-05-02T16:24:40.992-0700    INFO    globallogger/main.go:17 An info message {"iteration": 1}

*** After replacing the global logger with a production logger

{"level":"info","ts":1525303480.993161,"caller":"globallogger/main.go:22","msg":"An info message","iteration":1}

*** After undoing the last replacement of the global logger

2018-05-02T16:24:40.993-0700    INFO    globallogger/main.go:26 An info message {"iteration": 1}
techgolang
Using Zap - Creating custom encoders Runit, Chpst and ulimit defaults