package logs import ( "context" "go.uber.org/zap" "go.uber.org/zap/zapcore" "gogs.tyduyong.com/duyong/dy-pkg/app/options" "sync" ) var ( std = New(options.NewLogOptions()) mu sync.Mutex ) func Init(opts *options.LogOptions) { mu.Lock() defer mu.Unlock() std = New(opts) } func New(opts *options.LogOptions) *zapLogger { if opts == nil { opts = options.NewLogOptions() } var zapLevel zapcore.Level if err := zapLevel.UnmarshalText([]byte(opts.Level)); err != nil { zapLevel = zapcore.InfoLevel } encodeLevel := zapcore.CapitalLevelEncoder // when output to local path, with color is forbidden if opts.Format == "console" && opts.EnableColor { encodeLevel = zapcore.CapitalColorLevelEncoder } encoderConfig := zapcore.EncoderConfig{ MessageKey: "message", LevelKey: "level", TimeKey: "timestamp", NameKey: "logger", CallerKey: "caller", StacktraceKey: "stacktrace", LineEnding: zapcore.DefaultLineEnding, EncodeLevel: encodeLevel, EncodeTime: timeEncoder, EncodeDuration: milliSecondsDurationEncoder, EncodeCaller: zapcore.ShortCallerEncoder, } loggerConfig := &zap.Config{ Level: zap.NewAtomicLevelAt(zapLevel), Development: opts.Development, DisableCaller: opts.DisableCaller, DisableStacktrace: opts.DisableStacktrace, Sampling: &zap.SamplingConfig{ Initial: 100, Thereafter: 100, }, Encoding: opts.Format, EncoderConfig: encoderConfig, OutputPaths: opts.OutputPaths, ErrorOutputPaths: opts.ErrorOutputPaths, } var err error l, err := loggerConfig.Build(zap.AddStacktrace(zapcore.PanicLevel), zap.AddCallerSkip(1)) if err != nil { panic(err) } logger := &zapLogger{ zapLogger: l.Named(opts.Name), } zap.RedirectStdLog(l) return logger } type zapLogger struct { zapLogger *zap.Logger } func Debug(msg string, fields ...Field) { std.zapLogger.Debug(msg, fields...) } func (l *zapLogger) Debug(msg string, fields ...Field) { l.zapLogger.Debug(msg, fields...) } func Debugf(format string, v ...interface{}) { std.zapLogger.Sugar().Debugf(format, v...) } func (l *zapLogger) Debugf(format string, v ...interface{}) { l.zapLogger.Sugar().Debugf(format, v...) } func Info(msg string, fields ...Field) { std.zapLogger.Info(msg, fields...) } func (l *zapLogger) Info(msg string, fields ...Field) { l.zapLogger.Info(msg, fields...) } func Infof(format string, v ...interface{}) { std.zapLogger.Sugar().Infof(format, v...) } func (l *zapLogger) Infof(format string, v ...interface{}) { l.zapLogger.Sugar().Infof(format, v...) } func Warn(msg string, fields ...Field) { std.zapLogger.Warn(msg, fields...) } func (l *zapLogger) Warn(msg string, fields ...Field) { l.zapLogger.Warn(msg, fields...) } func Warnf(format string, v ...interface{}) { std.zapLogger.Sugar().Warnf(format, v...) } func (l *zapLogger) Warnf(format string, v ...interface{}) { l.zapLogger.Sugar().Warnf(format, v...) } func Error(msg string, fields ...Field) { std.zapLogger.Error(msg, fields...) } func (l *zapLogger) Error(msg string, fields ...Field) { l.zapLogger.Error(msg, fields...) } func Errorf(format string, v ...interface{}) { std.zapLogger.Sugar().Errorf(format, v...) } func (l *zapLogger) Errorf(format string, v ...interface{}) { l.zapLogger.Sugar().Errorf(format, v...) } func Panic(msg string, fields ...Field) { std.zapLogger.Panic(msg, fields...) } func (l *zapLogger) Panic(msg string, fields ...Field) { l.zapLogger.Panic(msg, fields...) } func Panicf(format string, v ...interface{}) { std.zapLogger.Sugar().Panicf(format, v...) } func (l *zapLogger) Panicf(format string, v ...interface{}) { l.zapLogger.Sugar().Panicf(format, v...) } func Fatal(msg string, fields ...Field) { std.zapLogger.Fatal(msg, fields...) } func (l *zapLogger) Fatal(msg string, fields ...Field) { l.zapLogger.Fatal(msg, fields...) } func Fatalf(format string, v ...interface{}) { std.zapLogger.Sugar().Fatalf(format, v...) } func (l *zapLogger) Fatalf(format string, v ...interface{}) { l.zapLogger.Sugar().Fatalf(format, v...) } func L(ctx context.Context) *zapLogger { return std.L(ctx) } func (l *zapLogger) L(ctx context.Context) *zapLogger { lg := l.clone() if requestID := ctx.Value(KeyRequestID); requestID != nil { lg.zapLogger = lg.zapLogger.With(zap.Any(KeyRequestID, requestID)) } if username := ctx.Value(KeyUsername); username != nil { lg.zapLogger = lg.zapLogger.With(zap.Any(KeyUsername, username)) } return lg } func (l *zapLogger) clone() *zapLogger { c := *l return &c } func Flush() { std.Flush() } func (l *zapLogger) Flush() { _ = l.zapLogger.Sync() }