Logging is an integral part of developing modern applications. It not only helps us track the running status of the program, but also provides valuable debugging information when problems arise.
There are many log libraries to choose from in Go, but Zap is the top of it in terms of performance and flexibility.
Today, I will take you into the deep understanding of how to use Zap for structured logging in a Go project and show how to customize log output to meet the needs of the production environment.
Why choose Zap?
Zap is a high-performance log library developed by Uber, designed for scenarios that require fast, structured logging. Compared with other log libraries, Zap has better performance, especially in high concurrency environments that require frequent logging.
In addition, Zap provides two logging interfaces:LoggerandSugaredLogger。
- LoggerProvides the most basic, type-safe structured logging method. Although it is a little complicated to use, it is unrivalled in performance and is very suitable for scenarios with extreme performance requirements.
- SugaredLoggerIt is encapsulated on the Logger to provide a more convenient logging method. Although slightly inferior to Logger in performance, its flexibility and ease of use make it the first choice for most scenarios.
Basic logging example
To better understand the use of Zap, let's start with a simple example.
package log_demo import ( "/zap" ) var logger * func InitLogger() { // Initialize Logger, here we use the configuration of the development environment logger, _ = () } func ZapPrintLog() { InitLogger() defer () // Make sure all logs in the log buffer are written to // Record a log at the information level and comes with a structured key-value pair ("This is a log message", ("key1", "value1"), zap.Float64s("key2", []float64{1.0, 2.0, 3.0})) }
In this example, we()
Initialize a Logger and useThe method records a log at the information level.
and
zap.Float64s
It is a field constructor provided by Zap for structured logs, which record the log content in the form of key-value pairs.
More convenient SugaredLogger
While structured logs are very useful, sometimes we just need to quickly log some information. at this time,SugaredLogger
It came in handy. It supports similarlogging method makes the code more concise.
package log_demo import ( "/zap" ) var sugaredLogger * func InitLogger() { logger, _ := () sugaredLogger = () } func ZapPrintLog1() { InitLogger() defer () // Use SugaredLogger to log ("This is a formatted log: %s", "example") ("This is a log message", "key1", "value1", "key2", []float64{1.0, 2.0, 3.0}) }
In the above code,SugaredLogger
ProvidedInfof
andInfow
Method, the former allows you to use it likeThe same formats the logs, the latter combines the advantages of structured logs to make logging more flexible.
Custom log configuration
In actual production environments, we may need to have more granular control over log output, such as outputting logs to files, consoles, or cutting logs by size or time.
Zap itself does not support log cutting, but we can use third-party librarieslumberjackTo implement this function.
package log_demo import ( "/zap" "/zap/zapcore" "/natefinch/lumberjack.v2" ) // InitCustomLogger InitCustomLogger Initializes a custom Loggerfunc InitCustomLogger() { // Create a log cutter writeSyncer := (&{ Filename: "", // Log file path MaxSize: 10, // Maximum size of a single log file (MB) MaxBackups: 5, // Keep up to 5 backups MaxAge: 30, // Maximum number of days for log retention Compress: true, // Enable log compression }) // Configure log encoder encoderConfig := () = zapcore.ISO8601TimeEncoder // Time format = // Log level capitalization encoder := (encoderConfig) // Create Logger Core core := (encoder, writeSyncer, ) // () will add the file name and line number of the calling function to the log // (1) The file name and line number of the calling function will be skipped // When we do not directly use the initialized logger instance to record the log, but wrap it into a function, etc., the function call chain of the log log will be increased. If we want to obtain accurate call information, we need to skip it through the AddCallerSkip function logger = (core, (), (1)) } func ZapPrintLog2() { InitCustomLogger() defer () ("This is a custom log message", ("key1", "value1"), zap.Float64s("key2", []float64{1.0, 2.0, 3.0})) }
In this example, weAutomatic log file cutting and management is realized.
The encoding format of the log is configured to ensure that the log output not only has structured information, but also has clear timestamps and log-level identification. In addition, we used
()
and(1)
, These two functions can add the file name and line number of the calling function in the log to help us locate the log source faster.
Application scenario example: Record debugging information
Suppose we need to record some debugging information when developing a web application. At this point, use theInitCustomLogger
Functions can record this information very easily.
func main() { ZapPrintLog2() // Call the customized log printing function // Assume that there is other business logic here for i := 0; i < 3; i++ { ("Processing iteration", ("iteration", i)) } }
In this short example,The current number of iterations will be recorded in each loop and the logs will be output to the specified log file.
Conclusion
Zap
It is a powerful and flexible log library. Whether you need extreme performance or want logging to be simpler and more intuitive, Zap can meet your needs.
Through this article, you not only understand how to use Zap for structured logging in Go, but also learn how to customize log output to meet the needs in the actual production environment.
Mastering the use of Zap will take your Go project to the next level in log management. If you haven’t tried Zap yet, now is a good time to get started!
This is the article about using Zap to easily solve structured logs in Go language. For more related contents of structured logs in Go, please search for my previous articles or continue browsing the related articles below. I hope everyone will support me in the future!