package logger import ( "fmt" "log" "os" ) type Logger struct { info *log.Logger warn *log.Logger err *log.Logger debug *log.Logger level string broadcaster *Broadcaster } func New(level string) *Logger { return &Logger{ info: log.New(os.Stdout, "[INFO] ", log.Ldate|log.Ltime|log.Lshortfile), warn: log.New(os.Stdout, "[WARN] ", log.Ldate|log.Ltime|log.Lshortfile), err: log.New(os.Stderr, "[ERROR] ", log.Ldate|log.Ltime|log.Lshortfile), debug: log.New(os.Stdout, "[DEBUG] ", log.Ldate|log.Ltime|log.Lshortfile), level: level, } } // SetBroadcaster attaches a log broadcaster for real-time log streaming. func (l *Logger) SetBroadcaster(b *Broadcaster) { l.broadcaster = b } // GetBroadcaster returns the attached broadcaster (may be nil). func (l *Logger) GetBroadcaster() *Broadcaster { return l.broadcaster } func (l *Logger) Info(msg string, args ...interface{}) { l.info.Printf(msg, args...) if l.broadcaster != nil { l.broadcaster.Push("INFO", fmt.Sprintf(msg, args...)) } } func (l *Logger) Warn(msg string, args ...interface{}) { l.warn.Printf(msg, args...) if l.broadcaster != nil { l.broadcaster.Push("WARN", fmt.Sprintf(msg, args...)) } } func (l *Logger) Error(msg string, args ...interface{}) { l.err.Printf(msg, args...) if l.broadcaster != nil { l.broadcaster.Push("ERROR", fmt.Sprintf(msg, args...)) } } func (l *Logger) Debug(msg string, args ...interface{}) { if l.level == "debug" { l.debug.Printf(msg, args...) if l.broadcaster != nil { l.broadcaster.Push("DEBUG", fmt.Sprintf(msg, args...)) } } }