package logger import ( "fmt" "os" "gcy_hpc_server/internal/config" "go.uber.org/zap" "go.uber.org/zap/zapcore" "gopkg.in/natefinch/lumberjack.v2" ) func NewLogger(cfg config.LogConfig) (*zap.Logger, error) { level := applyDefault(cfg.Level, "info") var zapLevel zapcore.Level if err := zapLevel.UnmarshalText([]byte(level)); err != nil { return nil, fmt.Errorf("invalid log level %q: %w", level, err) } encoding := applyDefault(cfg.Encoding, "json") encoderConfig := zap.NewProductionEncoderConfig() encoderConfig.TimeKey = "ts" encoderConfig.EncodeTime = zapcore.ISO8601TimeEncoder encoderConfig.EncodeLevel = zapcore.CapitalLevelEncoder var encoder zapcore.Encoder switch encoding { case "console": encoder = zapcore.NewConsoleEncoder(encoderConfig) default: encoder = zapcore.NewJSONEncoder(encoderConfig) } var syncers []zapcore.WriteSyncer stdout := true if cfg.OutputStdout != nil { stdout = *cfg.OutputStdout } if stdout { syncers = append(syncers, zapcore.AddSync(os.Stdout)) } if cfg.FilePath != "" { maxSize := applyDefaultInt(cfg.MaxSize, 100) maxBackups := applyDefaultInt(cfg.MaxBackups, 5) maxAge := applyDefaultInt(cfg.MaxAge, 30) compress := cfg.Compress || (cfg.MaxSize == 0 && cfg.MaxBackups == 0 && cfg.MaxAge == 0) lj := &lumberjack.Logger{ Filename: cfg.FilePath, MaxSize: maxSize, MaxBackups: maxBackups, MaxAge: maxAge, Compress: compress, } syncers = append(syncers, zapcore.AddSync(lj)) } if len(syncers) == 0 { syncers = append(syncers, zapcore.AddSync(os.Stdout)) } writeSyncer := syncers[0] if len(syncers) > 1 { writeSyncer = zapcore.NewMultiWriteSyncer(syncers...) } core := zapcore.NewCore(encoder, writeSyncer, zapLevel) opts := []zap.Option{ zap.AddCaller(), zap.AddStacktrace(zapcore.ErrorLevel), } return zap.New(core, opts...), nil } func applyDefault(val, def string) string { if val == "" { return def } return val } func applyDefaultInt(val, def int) int { if val == 0 { return def } return val }