前言
我們依然從官方示例開始:
logger, _ := zap.NewProduction()
...
NewProduction的代碼如下:
func NewProduction(options ...Option) (*Logger, error) {
return NewProductionConfig().Build(options...)
}
func NewProductionConfig() Config {
return Config{
Level: NewAtomicLevelAt(InfoLevel),
Development: false,
Sampling: &SamplingConfig{
Initial: 100,
Thereafter: 100,
},
Encoding: "json",
EncoderConfig: NewProductionEncoderConfig(),
OutputPaths: []string{"stderr"},
ErrorOutputPaths: []string{"stderr"},
}
}
NewProduction通過創建NewProductionConfig,再通過Config Build Logger。NewProductionConfig內設定了日誌的相關格式要求。
Config
從Config的註釋來看:
Config提供了一種聲明性的方式來構造Logger,通過調用New、Options和各種zapcore.WriteSyncer和zapcore.Core的封裝來完成Logger的創建,主要是簡化了調用者Logger的創建過程。注意:Config僅提供了通用的一些配置項,一些不常用的配置項,仍需要直接使用對應的封裝來實現配置的變更。
// Config offers a declarative way to construct a logger. It doesn't do
// anything that can't be done with New, Options, and the various
// zapcore.WriteSyncer and zapcore.Core wrappers, but it's a simpler way to
// toggle common options.
//
// Note that Config intentionally supports only the most common options. More
// unusual logging setups (logging to network connections or message queues,
// splitting output between multiple files, etc.) are possible, but require
// direct use of the zapcore package. For sample code, see the package-level
// BasicConfiguration and AdvancedConfiguration examples.
//
// For an example showing runtime log level changes, see the documentation for
// AtomicLevel.
type Config struct {
// Level is the minimum enabled logging level. Note that this is a dynamic
// level, so calling Config.Level.SetLevel will atomically change the log
// level of all loggers descended from this config.
// log級別,可以通過Config.Level.SetLevel動態設置
Level AtomicLevel `json:"level" yaml:"level"`
// Development puts the logger in development mode, which changes the
// behavior of DPanicLevel and takes stacktraces more liberally.
//是否開發模式,開發模式可以追逐更多的棧信息
Development bool `json:"development" yaml:"development"`
// DisableCaller stops annotating logs with the calling function's file
// name and line number. By default, all logs are annotated.
// 是否關閉註釋性logs,默認所有logs鬥志註釋性的。
DisableCaller bool `json:"disableCaller" yaml:"disableCaller"`
// DisableStacktrace completely disables automatic stacktrace capturing. By
// default, stacktraces are captured for WarnLevel and above logs in
// development and ErrorLevel and above in production.
// 是否關閉棧追蹤
DisableStacktrace bool `json:"disableStacktrace" yaml:"disableStacktrace"`
// Sampling sets a sampling policy. A nil SamplingConfig disables sampling.
// 採樣設置,記錄全局的CPU、IO負載
Sampling *SamplingConfig `json:"sampling" yaml:"sampling"`
// Encoding sets the logger's encoding. Valid values are "json" and
// "console", as well as any third-party encodings registered via
// RegisterEncoder.
// 支持編碼json或者console
Encoding string `json:"encoding" yaml:"encoding"`
// EncoderConfig sets options for the chosen encoder. See
// zapcore.EncoderConfig for details.
// 具體編碼器配置
EncoderConfig zapcore.EncoderConfig `json:"encoderConfig" yaml:"encoderConfig"`
// OutputPaths is a list of URLs or file paths to write logging output to.
// See Open for details.
// 輸出路徑
OutputPaths []string `json:"outputPaths" yaml:"outputPaths"`
// ErrorOutputPaths is a list of URLs to write internal logger errors to.
// The default is standard error.
//
// Note that this setting only affects internal errors; for sample code that
// sends error-level logs to a different location from info- and debug-level
// logs, see the package-level AdvancedConfiguration example.
// 錯誤輸出路徑,僅用於內部錯誤
ErrorOutputPaths []string `json:"errorOutputPaths" yaml:"errorOutputPaths"`
// InitialFields is a collection of fields to add to the root logger.
// 可以額外添加的參數
InitialFields map[string]interface{} `json:"initialFields" yaml:"initialFields"`
}
EncoderConfig是針對Encoding的具體配置項,主要包含如制定特定key的名稱,時間、日期的格式等,指定後這些信息會出現在log中。
注意:如果不指定對應key的name的話,對應key的信息不處理,即不會寫入到文件中,如MessageKey爲空的話,內容主體不處理,即看不到log內容。
// An EncoderConfig allows users to configure the concrete encoders supplied by
// zapcore.
type EncoderConfig struct {
// Set the keys used for each log entry. If any key is empty, that portion
// of the entry is omitted.
MessageKey string `json:"messageKey" yaml:"messageKey"`
LevelKey string `json:"levelKey" yaml:"levelKey"`
TimeKey string `json:"timeKey" yaml:"timeKey"`
NameKey string `json:"nameKey" yaml:"nameKey"`
CallerKey string `json:"callerKey" yaml:"callerKey"`
StacktraceKey string `json:"stacktraceKey" yaml:"stacktraceKey"`
LineEnding string `json:"lineEnding" yaml:"lineEnding"`
// Configure the primitive representations of common complex types. For
// example, some users may want all time.Times serialized as floating-point
// seconds since epoch, while others may prefer ISO8601 strings.
EncodeLevel LevelEncoder `json:"levelEncoder" yaml:"levelEncoder"`
EncodeTime TimeEncoder `json:"timeEncoder" yaml:"timeEncoder"`
EncodeDuration DurationEncoder `json:"durationEncoder" yaml:"durationEncoder"`
EncodeCaller CallerEncoder `json:"callerEncoder" yaml:"callerEncoder"`
// Unlike the other primitive type encoders, EncodeName is optional. The
// zero value falls back to FullNameEncoder.
EncodeName NameEncoder `json:"nameEncoder" yaml:"nameEncoder"`
}
根據以上的瞭解,我們回頭看看NewProductionConfig。
func NewProductionConfig() Config {
return Config{
Level: NewAtomicLevelAt(InfoLevel),//日誌級別INFO
Development: false,
Sampling: &SamplingConfig{//採樣設置
Initial: 100,
Thereafter: 100,
},
Encoding: "json",//採用json格式
EncoderConfig: NewProductionEncoderConfig(),
OutputPaths: []string{"stderr"},//輸出到標準錯誤
ErrorOutputPaths: []string{"stderr"},
}
}
func NewProductionEncoderConfig() zapcore.EncoderConfig {
return zapcore.EncoderConfig{
TimeKey: "ts",//時間對應的key名
LevelKey: "level",//日誌級別對應的key名
NameKey: "logger",//logger名對應的key名
CallerKey: "caller",//時間對應的key名
MessageKey: "msg",//日誌內容對應的key名,此參數必須不爲空,否則日誌主體不處理
StacktraceKey: "stacktrace",//棧追蹤的key名
LineEnding: zapcore.DefaultLineEnding,//默認換行,即使不設置
EncodeLevel: zapcore.LowercaseLevelEncoder,//小寫
EncodeTime: zapcore.EpochTimeEncoder,//時間轉爲s
EncodeDuration: zapcore.SecondsDurationEncoder,//日期轉爲s
EncodeCaller: zapcore.ShortCallerEncoder,//記錄調用路徑格式爲package/file:line
}
}
NewProductionConfig創建的是一個這樣的Config實例:
日誌級別InfoLevel,非開發環境,採樣間隔100s,編碼格式爲json,輸出及錯誤輸出路徑均爲stderr。EncoderConfig中帶key的設置均爲指定對應參數在信息中key名稱即自定義key名,這些值未設置或爲空時不顯示在log中。
示例結果:
{"level":"info","ts":1577697584.997612,"caller":"test/test.go:14","msg":"failed to fetch URL","url":"http://test","attempt":3,"backoff":1}
根據以上對Config的瞭解,我們根據自己的需求,自定義一個config
自定義Config
config: =zap.Config{
Level: zap.NewAtomicLevelAt(zap.DebugLevel),
Development: true,
Encoding: "console",
EncoderConfig: zapcore.EncoderConfig{
MessageKey: "msg",
},
OutputPaths: []string{"stdout", "./log.txt"},
ErrorOutputPaths: []string{"stderr"},
}
l,_ := Config.Build
l.Info("this is a test config")
以上自定義Config表示意思如下:
DebugLevel及以上級別日誌輸出,Development模式,採用console模式編碼及原始格式,僅展示日誌內容,日誌會顯示在標準輸出中及保存在log.txt文件中,內部發生錯誤顯示在標準錯誤中。注意:console模式不會打印key名的,僅打印對應的value。
輸出示例:
this is a test config
需要注意的是:zap中目前並不能自定義這些通用key出現的先後順序,如對順序有要求的話,建議自行對結果進行處理。
總結
本篇主要是對Config進行進一步的說明,並對自定義config進行了示例,後續對創建的過程做說明。