package logx import ( "fmt" "os" "sync" "time" "cn/oneao/base-go/conf" "github.com/cloudwego/hertz/pkg/common/hlog" "go.uber.org/zap" "go.uber.org/zap/zapcore" "gopkg.in/natefinch/lumberjack.v2" ) var ( zapLogger *zap.Logger mu sync.Mutex currentDay = make(map[string]string) currentSync = make(map[string]zapcore.WriteSyncer) ) // InitLog 从配置初始化日志 func InitLog() { cfg := conf.GetConf().Log // LogConfig 从 YAML 读取 if cfg.Dir == "" { cfg.Dir = "./logs" } if cfg.MaxSize <= 0 { cfg.MaxSize = 10 } if cfg.MaxBackups <= 0 { cfg.MaxBackups = 30 } if cfg.MaxAge <= 0 { cfg.MaxAge = 7 } dynamicLevel := zap.NewAtomicLevel() dynamicLevel.SetLevel(LogLevel()) logger := NewLogger( WithCores([]CoreConfig{ { Enc: zapcore.NewConsoleEncoder(consoleEncoderConfig()), Ws: zapcore.AddSync(os.Stdout), Lvl: dynamicLevel, }, { Enc: zapcore.NewJSONEncoder(humanEncoderConfig()), Ws: getWriteSyncer(fmt.Sprintf("%s/debug", cfg.Dir), &cfg), Lvl: zap.LevelEnablerFunc(func(lev zapcore.Level) bool { return lev == zap.DebugLevel }), }, { Enc: zapcore.NewJSONEncoder(humanEncoderConfig()), Ws: getWriteSyncer(fmt.Sprintf("%s/info", cfg.Dir), &cfg), Lvl: zap.LevelEnablerFunc(func(lev zapcore.Level) bool { return lev == zap.InfoLevel }), }, { Enc: zapcore.NewJSONEncoder(humanEncoderConfig()), Ws: getWriteSyncer(fmt.Sprintf("%s/warn", cfg.Dir), &cfg), Lvl: zap.LevelEnablerFunc(func(lev zapcore.Level) bool { return lev == zap.WarnLevel }), }, { Enc: zapcore.NewJSONEncoder(humanEncoderConfig()), Ws: getWriteSyncer(fmt.Sprintf("%s/error", cfg.Dir), &cfg), Lvl: zap.LevelEnablerFunc(func(lev zapcore.Level) bool { return lev >= zap.ErrorLevel }), }, }...), ) hlog.SetLogger(logger) zapLogger = logger.Logger() } func getWriteSyncer(basePath string, cfg *conf.LogConfig) zapcore.WriteSyncer { mu.Lock() defer mu.Unlock() today := time.Now().Format("2006-01-02") if day, ok := currentDay[basePath]; !ok || day != today { currentDay[basePath] = today file := fmt.Sprintf("%s/%s.log", basePath, today) currentSync[basePath] = zapcore.AddSync(&lumberjack.Logger{ Filename: file, MaxSize: cfg.MaxSize, MaxBackups: cfg.MaxBackups, MaxAge: cfg.MaxAge, Compress: cfg.Compress, LocalTime: true, }) } return currentSync[basePath] } func LogLevel() zapcore.Level { level := conf.GetConf().Log.Level switch level { case "trace": return zapcore.DebugLevel case "debug": return zapcore.DebugLevel case "info": return zapcore.InfoLevel case "warn": return zapcore.WarnLevel case "error": return zapcore.ErrorLevel case "dpanic": return zapcore.DPanicLevel case "panic": return zapcore.PanicLevel case "fatal": return zapcore.FatalLevel default: return zapcore.InfoLevel } } func consoleEncoderConfig() zapcore.EncoderConfig { return zapcore.EncoderConfig{ MessageKey: "msg", LevelKey: "level", TimeKey: "ts", EncodeTime: customTimeEncoder, EncodeLevel: zapcore.CapitalColorLevelEncoder, EncodeCaller: zapcore.ShortCallerEncoder, } } func humanEncoderConfig() zapcore.EncoderConfig { return zapcore.EncoderConfig{ MessageKey: "Message", LevelKey: "Level", NameKey: "Name", TimeKey: "Ts", CallerKey: "Caller", FunctionKey: "Func", StacktraceKey: "Stacktrace", LineEnding: "\n", EncodeTime: customTimeEncoder, EncodeLevel: zapcore.LowercaseLevelEncoder, EncodeDuration: zapcore.SecondsDurationEncoder, EncodeCaller: zapcore.ShortCallerEncoder, } } func customTimeEncoder(t time.Time, enc zapcore.PrimitiveArrayEncoder) { enc.AppendString(t.Format("2006-01-02 15:04:05.000")) }