In Go, logging is a very important aspect. When developing any application, you need to record the behavior of the application in one place so that you can investigate and troubleshoot if needed. The log package in the standard library provides some basic logging functions, but in actual applications, more complex and advanced logging tools may be needed. This is where custom logging comes into play.
In this article, we will learn how to use custom logs in Go.
Although the log package in the standard library can already meet basic logging needs, please note that the log package has its limitations. You may want lower-level and more customized controls. Therefore, we will use the third-party package "zap" to create a custom logger.
To use zap, you need to install it first, which can be done with the following command:
go get -u go.uber.org/zap
After the installation is complete, you can create a basic logger:
package main import "go.uber.org/zap" func main() { logger, err := zap.NewProduction() if err != nil { panic(err) } logger.Info("Hello, world!") }
In the sample code above, we use the NewProduction() function to create a production-level logger.
Of course, this is not enough to meet the needs, we need to define our own logger. You can create a generic logger using zap.NewDevelopment() or zap.NewProduction(), but for complex applications you may need to create a custom logger.
In the following example code, we define a custom logger named "myLogger":
package main import ( "go.uber.org/zap" "go.uber.org/zap/zapcore" ) func main() { cfg := zap.Config{ Encoding: "console", Level: zap.NewAtomicLevelAt(zapcore.DebugLevel), OutputPaths: []string{"stdout"}, ErrorOutputPaths: []string{"stderr"}, EncoderConfig: zapcore.EncoderConfig{ TimeKey: "timestamp", MessageKey: "message", CallerKey: "caller", EncodeTime: zapcore.ISO8601TimeEncoder, EncodeDuration: zapcore.StringDurationEncoder, EncodeCaller: zapcore.ShortCallerEncoder, }, } logger, err := cfg.Build() if err != nil { panic(err) } logger.Debug("Debug message") logger.Info("Info message") logger.Warn("Warn message") logger.Error("Error message") }
In the above example, we first define a custom logger named "cfg " configuration structure. The configuration structure contains all parameters required by the logger, such as output format, log level, output location, etc.
Then, we use the cfg.Build() function to create the logger. This will give us a logger with custom settings that we can use to print log messages. In the above example, we printed different levels of log messages.
An important feature in custom loggers is the ability to add contextual information. By adding contextual information, you can better understand what happened and locate the problem quickly.
In the following example, we use the logger.With() function to add a context field named "user_id":
package main import ( "go.uber.org/zap" "go.uber.org/zap/zapcore" ) func main() { cfg := zap.Config{ Encoding: "console", Level: zap.NewAtomicLevelAt(zapcore.DebugLevel), OutputPaths: []string{"stdout"}, ErrorOutputPaths: []string{"stderr"}, EncoderConfig: zapcore.EncoderConfig{ TimeKey: "timestamp", MessageKey: "message", CallerKey: "caller", EncodeTime: zapcore.ISO8601TimeEncoder, EncodeDuration: zapcore.StringDurationEncoder, EncodeCaller: zapcore.ShortCallerEncoder, }, } logger, err := cfg.Build() if err != nil { panic(err) } userId := "user123" logger = logger.With(zap.String("user_id", userId)) logger.Info("Info message") }
In the above example, we use the logger.With( ) function creates a new logger. It will contain a context field called "user_id" with the value "user123".
This is very useful in real-world applications as you can easily understand which users are using the system and troubleshoot user-related issues.
By default, custom loggers log messages to stdout. However, in actual applications, you need to record log messages to files to facilitate log management and deployment.
zap logger provides multiple output types such as file, stdout and stderr. Depending on your application, you can choose the type of output.
In the following example, we are logging to a file:
package main import ( "go.uber.org/zap" "go.uber.org/zap/zapcore" ) func main() { cfg := zap.Config{ Encoding: "console", Level: zap.NewAtomicLevelAt(zapcore.DebugLevel), OutputPaths: []string{"myapp.log"}, ErrorOutputPaths: []string{"myapp.log"}, EncoderConfig: zapcore.EncoderConfig{ TimeKey: "timestamp", MessageKey: "message", CallerKey: "caller", EncodeTime: zapcore.ISO8601TimeEncoder, EncodeDuration: zapcore.StringDurationEncoder, EncodeCaller: zapcore.ShortCallerEncoder, }, } logger, err := cfg.Build() if err != nil { panic(err) } logger.Info("Testing log file...") }
In the above example, we are providing the file path in the OutputPaths and ErrorOutputPaths fields, which will make the logger Write log messages to the myapp.log file.
To sum up, custom loggers provide more flexibility and customization capabilities so that you can meet the needs of actual applications. With custom loggers, you can easily log any specific information and make it easier to process and analyze the log data when needed.
The above is the detailed content of How to use custom logs in Go?. For more information, please follow other related articles on the PHP Chinese website!