|
|
package log
import ( "encoding/json" "fmt" "github.com/spf13/pflag" "go.uber.org/zap" "go.uber.org/zap/zapcore" "strings" )
const ( flagLevel = "log.level" flagDisableCaller = "log.disable-caller" flagDisableStacktrace = "log.disable-stacktrace" flagFormat = "log.format" flagEnableColor = "log.enable-color" flagOutputPaths = "log.output-paths" flagErrorOutputPaths = "log.error-output-paths" flagDevelopment = "log.development" flagName = "log.name"
ConsoleFormat = "console" JsonFormat = "json" )
// Options 日志有关的配置. 设置参考zap的配置
type Options struct { OutputPaths []string `json:"output-paths" mapstructure:"output-paths"` ErrorOutputPaths []string `json:"error-output-paths" mapstructure:"error-output-paths"` Level string `json:"level" mapstructure:"level"` Format string `json:"format" mapstructure:"format"` DisableCaller bool `json:"disable-caller" mapstructure:"disable-caller"` DisableStacktrace bool `json:"disable-stacktrace" mapstructure:"disable-stacktrace"` EnableColor bool `json:"enable-color" mapstructure:"enable-color"` Development bool `json:"development" mapstructure:"development"` Name string `json:"name" mapstructure:"name"` }
// NewOptions 新建带默认参数的日志配置
func NewOptions() *Options { return &Options{ Level: zapcore.InfoLevel.String(), DisableCaller: false, DisableStacktrace: false, Format: ConsoleFormat, EnableColor: false, Development: false, OutputPaths: []string{"stdout"}, ErrorOutputPaths: []string{"stderr"}, } }
// Validate 验证日志配置.
func (o *Options) Validate() []error { var errs []error
var zapLevel zapcore.Level if err := zapLevel.UnmarshalText([]byte(o.Level)); err != nil { errs = append(errs, err) }
format := strings.ToLower(o.Format) if format != ConsoleFormat && format != JsonFormat { errs = append(errs, fmt.Errorf("not a valid log format: %q", o.Format)) }
return errs }
// AddFlags 读取命令行参数设置日志配置
func (o *Options) AddFlags(fs *pflag.FlagSet) { fs.StringVar(&o.Level, flagLevel, o.Level, "Minimum log output `LEVEL`.") fs.BoolVar(&o.DisableCaller, flagDisableCaller, o.DisableCaller, "Disable output of caller information in the log.") fs.BoolVar(&o.DisableStacktrace, flagDisableStacktrace, o.DisableStacktrace, "Disable the log to record a stack trace for all messages at or above panic level.") fs.StringVar(&o.Format, flagFormat, o.Format, "Log output `FORMAT`, support plain or json format.") fs.BoolVar(&o.EnableColor, flagEnableColor, o.EnableColor, "Enable output ansi colors in plain format logs.") fs.StringSliceVar(&o.OutputPaths, flagOutputPaths, o.OutputPaths, "Output paths of log.") fs.StringSliceVar(&o.ErrorOutputPaths, flagErrorOutputPaths, o.ErrorOutputPaths, "Error output paths of log.") fs.BoolVar( &o.Development, flagDevelopment, o.Development, "Development puts the logger in development mode, which changes "+ "the behavior of DPanicLevel and takes stacktraces more liberally.", ) fs.StringVar(&o.Name, flagName, o.Name, "The name of the logger.") }
func (o *Options) String() string { data, _ := json.Marshal(o)
return string(data) }
// Build 将设置安装到全局zap logger
func (o *Options) Build() error { var zapLevel zapcore.Level if err := zapLevel.UnmarshalText([]byte(o.Level)); err != nil { zapLevel = zapcore.InfoLevel } encodeLevel := zapcore.CapitalLevelEncoder if o.Format == ConsoleFormat && o.EnableColor { encodeLevel = zapcore.CapitalColorLevelEncoder }
zc := &zap.Config{ Level: zap.NewAtomicLevelAt(zapLevel), Development: o.Development, DisableCaller: o.DisableCaller, DisableStacktrace: o.DisableStacktrace, Sampling: &zap.SamplingConfig{ Initial: 100, Thereafter: 100, }, Encoding: o.Format, EncoderConfig: zapcore.EncoderConfig{ MessageKey: "message", LevelKey: "level", TimeKey: "timestamp", NameKey: "logger", CallerKey: "caller", StacktraceKey: "stacktrace", LineEnding: zapcore.DefaultLineEnding, EncodeLevel: encodeLevel, EncodeTime: timeEncoder, EncodeDuration: autoDurationEncoder, EncodeCaller: zapcore.ShortCallerEncoder, EncodeName: zapcore.FullNameEncoder, }, OutputPaths: o.OutputPaths, ErrorOutputPaths: o.ErrorOutputPaths, } logger, err := zc.Build(zap.AddStacktrace(zapcore.PanicLevel)) if err != nil { return err } zap.RedirectStdLog(logger.Named(o.Name)) zap.ReplaceGlobals(logger)
return nil }
|