package config import ( "fmt" "io" "os" "path/filepath" "runtime" "strings" "time" "github.com/elastic/go-elasticsearch" "github.com/sirupsen/logrus" "github.com/tuusuario/go-sync-service/elastic" "gopkg.in/natefinch/lumberjack.v2" ) // Log instancia global del logger var Log = logrus.New() type LocalTimeHook struct { loc *time.Location } func (h LocalTimeHook) Levels() []logrus.Level { return logrus.AllLevels } func (h LocalTimeHook) Fire(e *logrus.Entry) error { if h.loc != nil { e.Time = e.Time.In(h.loc) } return nil } func InitLogger(cfg *Config) { // ========================= // Zona horaria Bolivia // ========================= loc, err := time.LoadLocation("America/La_Paz") if err != nil { // Fallback robusto para contenedores sin tzdata loc = time.FixedZone("America/La_Paz", -4*60*60) } time.Local = loc // Hook para forzar timestamps de Logrus a hora Bolivia Log.AddHook(LocalTimeHook{loc: loc}) // Configurar rotación de logs con Lumberjack rotator := &lumberjack.Logger{ Filename: cfg.LogFilePath, // Archivo de logs MaxSize: cfg.LogMaxSize, // Máximo tamaño en MB antes de rotar MaxBackups: cfg.LogMaxBackups, // Máximo número de archivos de respaldo MaxAge: cfg.LogMaxAge, // Máximo número de días para conservar logs Compress: cfg.LogCompress, // Comprimir logs antiguos } // Configurar Logrus para escribir en el archivo rotado Log.SetOutput(io.MultiWriter(os.Stdout, rotator)) Log.SetReportCaller(true) // 👈 esto agrega archivo y línea // Formato JSON con timestamp /*Log.SetFormatter(&logrus.JSONFormatter{ TimestampFormat: time.RFC3339, // Formato ISO 8601 })*/ Log.SetFormatter(&logrus.JSONFormatter{ TimestampFormat: time.RFC3339, CallerPrettyfier: func(f *runtime.Frame) (function string, file string) { // Extrae solo nombre del archivo y línea fnParts := strings.Split(f.Function, "/") return fnParts[len(fnParts)-1], fmt.Sprintf("%s:%d", filepath.Base(f.File), f.Line) }, }) // Configurar nivel de logging (DEBUG, INFO, ERROR, etc.) level, err := logrus.ParseLevel(cfg.LogLevel) if err != nil { level = logrus.InfoLevel } Log.SetLevel(level) //elastic if cfg.ElasticEnabled { Log.Info("✅ Elasticsearch enabled") es, err := elasticsearch.NewClient(elasticsearch.Config{ Addresses: []string{cfg.ElasticURL}, }) if err == nil { hook := elastic.NewElasticHook(es, "go-sync-service") Log.AddHook(hook) } else { Log.Error("No se pudo conectar a Elasticsearch: ", err) } } }