package logger import ( "io" "log" "os" "github.com/sirupsen/logrus" ) type Hook struct { Writer io.Writer Formatter logrus.Formatter Level []logrus.Level } func (h *Hook) Fire(entry *logrus.Entry) error { line, err := h.Formatter.Format(entry) if err != nil { return err } h.Writer.Write(line) return nil } func (h *Hook) Levels() []logrus.Level { return h.Level } func newHook(writer io.Writer, formatter logrus.Formatter, level logrus.Level) *Hook { var levels []logrus.Level for _, l := range logrus.AllLevels { if l <= level { levels = append(levels, l) } } return &Hook{ Writer: writer, Formatter: formatter, Level: levels, } } func Init(logFilePath string, logLevelStr string) *logrus.Logger { var Logger *logrus.Logger logLevel, err := logrus.ParseLevel(logLevelStr) if err != nil { logLevel = logrus.InfoLevel log.Printf("Invalid log level: %s. Defaulting to info", logLevelStr) } Logger = logrus.New() Logger.SetOutput(io.Discard) logFile, err := os.OpenFile(logFilePath, os.O_CREATE|os.O_WRONLY|os.O_APPEND, 0644) if err != nil { log.Printf("Failed to open log file: %s", logFilePath) panic(err) } Logger.AddHook(newHook( logFile, &logrus.JSONFormatter{}, logLevel, )) Logger.AddHook(newHook( os.Stderr, &logrus.TextFormatter{ FullTimestamp: true, ForceColors: true, }, logLevel, )) return Logger }