package logger import ( "fmt" "os" "path/filepath" "strings" "backupx/server/internal/config" "github.com/natefinch/lumberjack" "go.uber.org/zap" "go.uber.org/zap/zapcore" ) func New(cfg config.LogConfig) (*zap.Logger, error) { level := parseLevel(cfg.Level) encoderCfg := zap.NewProductionEncoderConfig() encoderCfg.TimeKey = "time" encoderCfg.EncodeTime = zapcore.ISO8601TimeEncoder encoder := zapcore.NewJSONEncoder(encoderCfg) writers := []zapcore.WriteSyncer{zapcore.AddSync(os.Stdout)} if cfg.File != "" { if err := os.MkdirAll(filepath.Dir(cfg.File), 0o755); err != nil { return nil, fmt.Errorf("create log dir: %w", err) } rotator := &lumberjack.Logger{ Filename: cfg.File, MaxSize: cfg.MaxSize, MaxBackups: cfg.MaxBackups, MaxAge: cfg.MaxAge, LocalTime: false, Compress: true, } writers = append(writers, zapcore.AddSync(rotator)) } core := zapcore.NewCore(encoder, zapcore.NewMultiWriteSyncer(writers...), level) return zap.New(core, zap.AddCaller(), zap.AddStacktrace(zapcore.ErrorLevel)), nil } func parseLevel(value string) zapcore.Level { switch strings.ToLower(strings.TrimSpace(value)) { case "debug": return zapcore.DebugLevel case "warn": return zapcore.WarnLevel case "error": return zapcore.ErrorLevel default: return zapcore.InfoLevel } }