You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
143 lines
4.7 KiB
143 lines
4.7 KiB
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
|
|
}
|