mirror of
https://github.com/Mrs4s/go-cqhttp.git
synced 2025-05-04 19:17:37 +08:00
236 lines
5.3 KiB
Go
236 lines
5.3 KiB
Go
package global
|
|
|
|
import (
|
|
"fmt"
|
|
"io"
|
|
"os"
|
|
"path/filepath"
|
|
"reflect"
|
|
"strings"
|
|
"sync"
|
|
|
|
"github.com/mattn/go-colorable"
|
|
"github.com/sirupsen/logrus"
|
|
)
|
|
|
|
// LocalHook logrus本地钩子
|
|
type LocalHook struct {
|
|
lock *sync.Mutex
|
|
levels []logrus.Level // hook级别
|
|
formatter logrus.Formatter // 格式
|
|
path string // 写入path
|
|
writer io.Writer // io
|
|
}
|
|
|
|
// Levels ref: logrus/hooks.go impl Hook interface
|
|
func (hook *LocalHook) Levels() []logrus.Level {
|
|
if len(hook.levels) == 0 {
|
|
return logrus.AllLevels
|
|
}
|
|
return hook.levels
|
|
}
|
|
|
|
func (hook *LocalHook) ioWrite(entry *logrus.Entry) error {
|
|
log, err := hook.formatter.Format(entry)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
_, err = hook.writer.Write(log)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
return nil
|
|
}
|
|
|
|
func (hook *LocalHook) pathWrite(entry *logrus.Entry) error {
|
|
dir := filepath.Dir(hook.path)
|
|
if err := os.MkdirAll(dir, os.ModePerm); err != nil {
|
|
return err
|
|
}
|
|
|
|
fd, err := os.OpenFile(hook.path, os.O_WRONLY|os.O_APPEND|os.O_CREATE, 0o666)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
defer fd.Close()
|
|
|
|
log, err := hook.formatter.Format(entry)
|
|
if err != nil {
|
|
return err
|
|
}
|
|
|
|
_, err = fd.Write(log)
|
|
return err
|
|
}
|
|
|
|
// Fire ref: logrus/hooks.go impl Hook interface
|
|
func (hook *LocalHook) Fire(entry *logrus.Entry) error {
|
|
hook.lock.Lock()
|
|
defer hook.lock.Unlock()
|
|
|
|
if hook.writer != nil {
|
|
return hook.ioWrite(entry)
|
|
}
|
|
|
|
if hook.path != "" {
|
|
return hook.pathWrite(entry)
|
|
}
|
|
|
|
return nil
|
|
}
|
|
|
|
// SetFormatter 设置日志格式
|
|
func (hook *LocalHook) SetFormatter(consoleFormatter, fileFormatter logrus.Formatter) {
|
|
hook.lock.Lock()
|
|
defer hook.lock.Unlock()
|
|
|
|
// 支持处理windows平台的console色彩
|
|
logrus.SetOutput(colorable.NewColorableStdout())
|
|
// 用于在console写出
|
|
logrus.SetFormatter(consoleFormatter)
|
|
// 用于写入文件
|
|
hook.formatter = fileFormatter
|
|
}
|
|
|
|
// SetWriter 设置Writer
|
|
func (hook *LocalHook) SetWriter(writer io.Writer) {
|
|
hook.lock.Lock()
|
|
defer hook.lock.Unlock()
|
|
hook.writer = writer
|
|
}
|
|
|
|
// SetPath 设置日志写入路径
|
|
func (hook *LocalHook) SetPath(path string) {
|
|
hook.lock.Lock()
|
|
defer hook.lock.Unlock()
|
|
hook.path = path
|
|
}
|
|
|
|
// NewLocalHook 初始化本地日志钩子实现
|
|
func NewLocalHook(args interface{}, consoleFormatter, fileFormatter logrus.Formatter, levels ...logrus.Level) *LocalHook {
|
|
hook := &LocalHook{
|
|
lock: new(sync.Mutex),
|
|
}
|
|
hook.SetFormatter(consoleFormatter, fileFormatter)
|
|
hook.levels = append(hook.levels, levels...)
|
|
|
|
switch arg := args.(type) {
|
|
case string:
|
|
hook.SetPath(arg)
|
|
case io.Writer:
|
|
hook.SetWriter(arg)
|
|
default:
|
|
panic(fmt.Sprintf("unsupported type: %v", reflect.TypeOf(args)))
|
|
}
|
|
|
|
return hook
|
|
}
|
|
|
|
// GetLogLevel 获取日志等级
|
|
//
|
|
// 可能的值有
|
|
//
|
|
// "trace","debug","info","warn","warn","error"
|
|
func GetLogLevel(level string) []logrus.Level {
|
|
switch level {
|
|
case "trace":
|
|
return []logrus.Level{
|
|
logrus.TraceLevel, logrus.DebugLevel,
|
|
logrus.InfoLevel, logrus.WarnLevel, logrus.ErrorLevel,
|
|
logrus.FatalLevel, logrus.PanicLevel,
|
|
}
|
|
case "debug":
|
|
return []logrus.Level{
|
|
logrus.DebugLevel, logrus.InfoLevel,
|
|
logrus.WarnLevel, logrus.ErrorLevel,
|
|
logrus.FatalLevel, logrus.PanicLevel,
|
|
}
|
|
case "info":
|
|
return []logrus.Level{
|
|
logrus.InfoLevel, logrus.WarnLevel,
|
|
logrus.ErrorLevel, logrus.FatalLevel, logrus.PanicLevel,
|
|
}
|
|
case "warn":
|
|
return []logrus.Level{
|
|
logrus.WarnLevel, logrus.ErrorLevel,
|
|
logrus.FatalLevel, logrus.PanicLevel,
|
|
}
|
|
case "error":
|
|
return []logrus.Level{
|
|
logrus.ErrorLevel, logrus.FatalLevel,
|
|
logrus.PanicLevel,
|
|
}
|
|
default:
|
|
return []logrus.Level{
|
|
logrus.InfoLevel, logrus.WarnLevel,
|
|
logrus.ErrorLevel, logrus.FatalLevel, logrus.PanicLevel,
|
|
}
|
|
}
|
|
}
|
|
|
|
// LogFormat specialize for go-cqhttp
|
|
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("] [")
|
|
buf.WriteString(strings.ToUpper(entry.Level.String()))
|
|
buf.WriteString("]: ")
|
|
buf.WriteString(entry.Message)
|
|
buf.WriteString(" \n")
|
|
|
|
if f.EnableColor {
|
|
buf.WriteString(colorReset)
|
|
}
|
|
|
|
ret := make([]byte, len(buf.Bytes()))
|
|
copy(ret, buf.Bytes()) // copy buffer
|
|
return ret, nil
|
|
}
|
|
|
|
const (
|
|
colorCodePanic = "\x1b[1;31m" // color.Style{color.Bold, color.Red}.String()
|
|
colorCodeFatal = "\x1b[1;31m" // color.Style{color.Bold, color.Red}.String()
|
|
colorCodeError = "\x1b[31m" // color.Style{color.Red}.String()
|
|
colorCodeWarn = "\x1b[33m" // color.Style{color.Yellow}.String()
|
|
colorCodeInfo = "\x1b[37m" // color.Style{color.White}.String()
|
|
colorCodeDebug = "\x1b[32m" // color.Style{color.Green}.String()
|
|
colorCodeTrace = "\x1b[36m" // color.Style{color.Cyan}.String()
|
|
colorReset = "\x1b[0m"
|
|
)
|
|
|
|
// 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
|
|
}
|
|
}
|