diff --git a/global/log_hook.go b/global/log_hook.go index eb4f273..6fd7512 100644 --- a/global/log_hook.go +++ b/global/log_hook.go @@ -9,6 +9,7 @@ import ( "strings" "sync" + "github.com/mattn/go-colorable" "github.com/sirupsen/logrus" ) @@ -80,10 +81,22 @@ func (hook *LocalHook) Fire(entry *logrus.Entry) error { } // SetFormatter 设置日志格式 -func (hook *LocalHook) SetFormatter(formatter logrus.Formatter) { +func (hook *LocalHook) SetFormatter(consoleFormatter, fileFormatter logrus.Formatter) { hook.lock.Lock() defer hook.lock.Unlock() + consoleFormatter = tryChangeFormatter(consoleFormatter) + fileFormatter = tryChangeFormatter(fileFormatter) + + // 支持处理windows平台的console色彩 + logrus.SetOutput(colorable.NewColorableStdout()) + // 用于在console写出 + logrus.SetFormatter(consoleFormatter) + // 用于写入文件 + hook.formatter = fileFormatter +} + +func tryChangeFormatter(formatter logrus.Formatter) logrus.Formatter { if formatter == nil { // 用默认的 formatter = &logrus.TextFormatter{DisableColors: true} @@ -96,8 +109,8 @@ func (hook *LocalHook) SetFormatter(formatter logrus.Formatter) { // todo } } - logrus.SetFormatter(formatter) - hook.formatter = formatter + + return formatter } // SetWriter 设置Writer @@ -115,11 +128,11 @@ func (hook *LocalHook) SetPath(path string) { } // NewLocalHook 初始化本地日志钩子实现 -func NewLocalHook(args interface{}, formatter logrus.Formatter, levels ...logrus.Level) *LocalHook { +func NewLocalHook(args interface{}, consoleFormatter, fileFormatter logrus.Formatter, levels ...logrus.Level) *LocalHook { hook := &LocalHook{ lock: new(sync.Mutex), } - hook.SetFormatter(formatter) + hook.SetFormatter(consoleFormatter, fileFormatter) hook.levels = append(hook.levels, levels...) switch arg := args.(type) { @@ -177,12 +190,19 @@ func GetLogLevel(level string) []logrus.Level { } // LogFormat specialize for go-cqhttp -type LogFormat struct{} +type LogFormat struct { + EnableColor bool +} // Format implements logrus.Formatter func (f LogFormat) Format(entry *logrus.Entry) ([]byte, error) { buf := NewBuffer() defer PutBuffer(buf) + + if f.EnableColor { + buf.WriteString(GetLogLevelColorCode(entry.Level)) + } + buf.WriteByte('[') buf.WriteString(entry.Time.Format("2006-01-02 15:04:05")) buf.WriteString("] [") @@ -190,6 +210,54 @@ func (f LogFormat) Format(entry *logrus.Entry) ([]byte, error) { buf.WriteString("]: ") buf.WriteString(entry.Message) buf.WriteString(" \n") + + if f.EnableColor { + buf.WriteString(ResetSet) + } + ret := append([]byte(nil), buf.Bytes()...) // copy buffer return ret, nil } + +// 为了不引入新依赖,直接将对应库需要的部分复制过来了,具体可参考 github.com\gookit\color@v1.4.2\color.go + +// ResetSet 重置色彩 ansi code +const ResetSet = "\x1b[0m" + +const ( + // SettingTpl 开始色彩 ansi code + SettingTpl = "\x1b[%sm" +) + +var ( + colorCodePanic = fmt.Sprintf(SettingTpl, "1;31") // color.Style{color.Bold, color.Red}.String() + colorCodeFatal = fmt.Sprintf(SettingTpl, "1;31") // color.Style{color.Bold, color.Red}.String() + colorCodeError = fmt.Sprintf(SettingTpl, "31") // color.Style{color.Red}.String() + colorCodeWarn = fmt.Sprintf(SettingTpl, "33") // color.Style{color.Yellow}.String() + colorCodeInfo = fmt.Sprintf(SettingTpl, "32") // color.Style{color.Green}.String() + colorCodeDebug = fmt.Sprintf(SettingTpl, "37") // color.Style{color.White}.String() + colorCodeTrace = fmt.Sprintf(SettingTpl, "36") // color.Style{color.Cyan}.String() +) + +// GetLogLevelColorCode 获取日志等级对应色彩code +func GetLogLevelColorCode(level logrus.Level) string { + switch level { + case logrus.PanicLevel: + return colorCodePanic + case logrus.FatalLevel: + return colorCodeFatal + case logrus.ErrorLevel: + return colorCodeError + case logrus.WarnLevel: + return colorCodeWarn + case logrus.InfoLevel: + return colorCodeInfo + case logrus.DebugLevel: + return colorCodeDebug + case logrus.TraceLevel: + return colorCodeTrace + + default: + return colorCodeInfo + } +} diff --git a/go.mod b/go.mod index aab0570..c588ef7 100644 --- a/go.mod +++ b/go.mod @@ -14,6 +14,7 @@ require ( github.com/gorilla/websocket v1.4.2 github.com/kardianos/osext v0.0.0-20190222173326-2bc1f35cddc0 github.com/lestrrat-go/file-rotatelogs v2.4.0+incompatible + github.com/mattn/go-colorable v0.1.8 github.com/pkg/errors v0.9.1 github.com/segmentio/asm v1.0.0 github.com/sirupsen/logrus v1.8.1 @@ -36,7 +37,6 @@ require ( github.com/klauspost/cpuid/v2 v2.0.6 // indirect github.com/lestrrat-go/strftime v1.0.5 // indirect github.com/maruel/rs v0.0.0-20150922171536-2c81c4312fe4 // indirect - github.com/mattn/go-colorable v0.1.8 // indirect github.com/mattn/go-isatty v0.0.12 // indirect github.com/pmezard/go-difflib v1.0.0 // indirect github.com/remyoudompheng/bigfft v0.0.0-20200410134404-eec4a21b6bb0 // indirect diff --git a/main.go b/main.go index 8008252..a91c67b 100644 --- a/main.go +++ b/main.go @@ -64,7 +64,10 @@ func main() { log.Errorf("rotatelogs init err: %v", err) panic(err) } - log.AddHook(global.NewLocalHook(w, global.LogFormat{}, global.GetLogLevel(base.LogLevel)...)) + + consoleFormatter := global.LogFormat{EnableColor: true} + fileFormatter := global.LogFormat{EnableColor: false} + log.AddHook(global.NewLocalHook(w, consoleFormatter, fileFormatter, global.GetLogLevel(base.LogLevel)...)) mkCacheDir := func(path string, _type string) { if !global.PathExists(path) {