package log import ( "fmt" "os" "github.com/Dreamacro/clash/common/observable" log "github.com/sirupsen/logrus" ) var ( logCh = make(chan any) source = observable.NewObservable(logCh) level = INFO ) func init() { log.SetOutput(os.Stdout) log.SetLevel(log.DebugLevel) } type Event struct { LogLevel LogLevel Payload string } func (e *Event) Type() string { return e.LogLevel.String() } func Infoln(format string, v ...any) { event := newLog(INFO, format, v...) logCh <- event print(event) } func Warnln(format string, v ...any) { event := newLog(WARNING, format, v...) logCh <- event print(event) } func Errorln(format string, v ...any) { event := newLog(ERROR, format, v...) logCh <- event print(event) } func Debugln(format string, v ...any) { event := newLog(DEBUG, format, v...) logCh <- event print(event) } func Fatalln(format string, v ...any) { log.Fatalf(format, v...) } func Subscribe() observable.Subscription { sub, _ := source.Subscribe() return sub } func UnSubscribe(sub observable.Subscription) { source.UnSubscribe(sub) } func Level() LogLevel { return level } func SetLevel(newLevel LogLevel) { level = newLevel } func print(data *Event) { if data.LogLevel < level { return } switch data.LogLevel { case INFO: log.Infoln(data.Payload) case WARNING: log.Warnln(data.Payload) case ERROR: log.Errorln(data.Payload) case DEBUG: log.Debugln(data.Payload) } } func newLog(logLevel LogLevel, format string, v ...any) *Event { return &Event{ LogLevel: logLevel, Payload: fmt.Sprintf(format, v...), } } func PrintLog(logLevel LogLevel, format string, v ...interface{}) { event := newLog(logLevel, format, v...) logCh <- event print(event) }