package logging import ( "fmt" "io" "log" "os" "path/filepath" "strings" "sync" "time" "gopkg.in/natefinch/lumberjack.v2" ) // LogConfig contiene la configuración para el sistema de logging type LogConfig struct { BaseDir string BaseFilename string MaxSize int // MB MaxBackups int MaxAge int // days Compress bool } // LoggerSystem es el sistema de logs centralizado type LoggerSystem struct { Info *log.Logger Error *log.Logger Debug *log.Logger writer *lumberjack.Logger mu sync.Mutex config *LogConfig } // NewLoggerSystem crea una nueva instancia del sistema de logs func NewLoggerSystem(config *LogConfig) (*LoggerSystem, error) { // Asegurar que el directorio existe if err := os.MkdirAll(config.BaseDir, 0755); err != nil { return nil, fmt.Errorf("error creando directorio de logs: %w", err) } // Crear nombre de archivo con timestamp timestamp := time.Now().Format("20060102_150405") ext := filepath.Ext(config.BaseFilename) baseName := strings.TrimSuffix(config.BaseFilename, ext) currentLogFile := filepath.Join(config.BaseDir, fmt.Sprintf("%s_%s%s", baseName, timestamp, ext)) // Configurar la rotación de logs con lumberjack logWriter := &lumberjack.Logger{ Filename: currentLogFile, MaxSize: config.MaxSize, MaxBackups: config.MaxBackups, MaxAge: config.MaxAge, Compress: config.Compress, LocalTime: true, } // Usar un writer multi para enviar logs tanto a stdout como al archivo multiWriter := io.MultiWriter(os.Stdout, logWriter) return &LoggerSystem{ Info: log.New(multiWriter, "INFO: ", log.Ldate|log.Ltime|log.Lshortfile), Error: log.New(multiWriter, "ERROR: ", log.Ldate|log.Ltime|log.Lshortfile), Debug: log.New(multiWriter, "DEBUG: ", log.Ldate|log.Ltime|log.Lshortfile), writer: logWriter, config: config, }, nil } // Close cierra el sistema de logs func (ls *LoggerSystem) Close() error { // No necesitamos cerrar explícitamente porque lumberjack se encarga de eso return nil }