package main import ( "fmt" "io" "log" "os" ) type Logger struct { infoLog *log.Logger warnLog *log.Logger errorLog *log.Logger } func NewLogger(logPath string) *Logger { // Default to stdout/stderr var infoOut io.Writer = os.Stdout var errorOut io.Writer = os.Stderr if logPath != "" { // Open log file in append mode, create if not exists f, err := os.OpenFile(logPath, os.O_APPEND|os.O_CREATE|os.O_WRONLY, 0644) if err != nil { fmt.Printf("Failed to open log file: %v\n", err) } else { // MultiWriter sends output to both the terminal and the file infoOut = io.MultiWriter(os.Stdout, f) errorOut = io.MultiWriter(os.Stderr, f) } } return &Logger{ infoLog: log.New(infoOut, "INFO ", log.Ldate|log.Ltime|log.Lshortfile), warnLog: log.New(infoOut, "WARN ", log.Ldate|log.Ltime|log.Lshortfile), errorLog: log.New(errorOut, "ERROR ", log.Ldate|log.Ltime|log.Lshortfile), } } func (l *Logger) Info(format string, v ...interface{}) { l.infoLog.Output(2, fmt.Sprintf(format, v...)) } func (l *Logger) Warn(format string, v ...interface{}) { l.warnLog.Output(2, fmt.Sprintf(format, v...)) } func (l *Logger) Error(format string, v ...interface{}) { l.errorLog.Output(2, fmt.Sprintf(format, v...)) }