mirror of
				https://gitee.com/dromara/mayfly-go
				synced 2025-11-04 08:20:25 +08:00 
			
		
		
		
	refactor: slog替换logrus、日志操作统一、支持json、text格式等
This commit is contained in:
		@@ -3,11 +3,10 @@ package req
 | 
			
		||||
import (
 | 
			
		||||
	"fmt"
 | 
			
		||||
	"mayfly-go/pkg/biz"
 | 
			
		||||
	"mayfly-go/pkg/global"
 | 
			
		||||
	"mayfly-go/pkg/logx"
 | 
			
		||||
	"mayfly-go/pkg/utils/anyx"
 | 
			
		||||
	"mayfly-go/pkg/utils/runtimex"
 | 
			
		||||
	"mayfly-go/pkg/utils/stringx"
 | 
			
		||||
 | 
			
		||||
	"github.com/sirupsen/logrus"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
type SaveLogFunc func(*Ctx)
 | 
			
		||||
@@ -42,6 +41,8 @@ func (i *LogInfo) WithLogResp() *LogInfo {
 | 
			
		||||
	return i
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
const DefaultLogFrames = 10
 | 
			
		||||
 | 
			
		||||
func LogHandler(rc *Ctx) error {
 | 
			
		||||
	if rc.Conf == nil || rc.Conf.logInfo == nil {
 | 
			
		||||
		return nil
 | 
			
		||||
@@ -49,24 +50,54 @@ func LogHandler(rc *Ctx) error {
 | 
			
		||||
 | 
			
		||||
	li := rc.Conf.logInfo
 | 
			
		||||
 | 
			
		||||
	lfs := logrus.Fields{}
 | 
			
		||||
	if la := rc.LoginAccount; la != nil {
 | 
			
		||||
		lfs["uid"] = la.Id
 | 
			
		||||
		lfs["uname"] = la.Username
 | 
			
		||||
	}
 | 
			
		||||
	attrMap := make(map[string]any, 0)
 | 
			
		||||
 | 
			
		||||
	req := rc.GinCtx.Request
 | 
			
		||||
	lfs[req.Method] = req.URL.Path
 | 
			
		||||
	attrMap[req.Method] = req.URL.Path
 | 
			
		||||
 | 
			
		||||
	if la := rc.LoginAccount; la != nil {
 | 
			
		||||
		attrMap["uid"] = la.Id
 | 
			
		||||
		attrMap["uname"] = la.Username
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	// 如果需要保存日志,并且保存日志处理函数存在则执行保存日志函数
 | 
			
		||||
	if li.save && saveLog != nil {
 | 
			
		||||
		go saveLog(rc)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	logMsg := li.Description
 | 
			
		||||
 | 
			
		||||
	if logx.GetConfig().IsJsonType() {
 | 
			
		||||
		// json格式日志处理
 | 
			
		||||
		attrMap["req"] = rc.ReqParam
 | 
			
		||||
		if li.LogResp {
 | 
			
		||||
			attrMap["resp"] = rc.ResData
 | 
			
		||||
		}
 | 
			
		||||
		attrMap["exeTime"] = rc.timed
 | 
			
		||||
 | 
			
		||||
		if rc.Err != nil {
 | 
			
		||||
			nFrames := DefaultLogFrames
 | 
			
		||||
			if _, ok := rc.Err.(biz.BizError); ok {
 | 
			
		||||
				nFrames = nFrames / 2
 | 
			
		||||
			}
 | 
			
		||||
			attrMap["error"] = rc.Err
 | 
			
		||||
			// 跳过log_handler等相关堆栈
 | 
			
		||||
			attrMap["stacktrace"] = runtimex.StatckStr(5, nFrames)
 | 
			
		||||
		}
 | 
			
		||||
	} else {
 | 
			
		||||
		// 处理文本格式日志信息
 | 
			
		||||
		if err := rc.Err; err != nil {
 | 
			
		||||
			logMsg = getErrMsg(rc, err)
 | 
			
		||||
		} else {
 | 
			
		||||
			logMsg = getLogMsg(rc)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	if err := rc.Err; err != nil {
 | 
			
		||||
		global.Log.WithFields(lfs).Error(getErrMsg(rc, err))
 | 
			
		||||
		logx.ErrorWithFields(logMsg, attrMap)
 | 
			
		||||
		return nil
 | 
			
		||||
	}
 | 
			
		||||
	global.Log.WithFields(lfs).Info(getLogMsg(rc))
 | 
			
		||||
	logx.InfoWithFields(logMsg, attrMap)
 | 
			
		||||
	return nil
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
@@ -85,19 +116,23 @@ func getLogMsg(rc *Ctx) string {
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
func getErrMsg(rc *Ctx, err any) string {
 | 
			
		||||
	msg := rc.Conf.logInfo.Description
 | 
			
		||||
	msg := rc.Conf.logInfo.Description + fmt.Sprintf(" ->%dms", rc.timed)
 | 
			
		||||
	if !anyx.IsBlank(rc.ReqParam) {
 | 
			
		||||
		msg = msg + fmt.Sprintf("\n--> %s", stringx.AnyToStr(rc.ReqParam))
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	nFrames := DefaultLogFrames
 | 
			
		||||
	var errMsg string
 | 
			
		||||
	switch t := err.(type) {
 | 
			
		||||
	case biz.BizError:
 | 
			
		||||
		errMsg = fmt.Sprintf("\n<-e errCode: %d, errMsg: %s", t.Code(), t.Error())
 | 
			
		||||
		errMsg = fmt.Sprintf("\n<-e %s", t.String())
 | 
			
		||||
		nFrames = nFrames / 2
 | 
			
		||||
	case error:
 | 
			
		||||
		errMsg = fmt.Sprintf("\n<-e errMsg: %s", t.Error())
 | 
			
		||||
	case string:
 | 
			
		||||
		errMsg = fmt.Sprintf("\n<-e errMsg: %s", t)
 | 
			
		||||
	}
 | 
			
		||||
	// 加上堆栈信息
 | 
			
		||||
	errMsg += fmt.Sprintf("\n<-stacktrace: %s", runtimex.StatckStr(5, nFrames))
 | 
			
		||||
	return (msg + errMsg)
 | 
			
		||||
}
 | 
			
		||||
 
 | 
			
		||||
@@ -26,7 +26,9 @@ type Ctx struct {
 | 
			
		||||
 | 
			
		||||
func (rc *Ctx) Handle(handler HandlerFunc) {
 | 
			
		||||
	ginCtx := rc.GinCtx
 | 
			
		||||
	begin := time.Now()
 | 
			
		||||
	defer func() {
 | 
			
		||||
		rc.timed = time.Since(begin).Milliseconds()
 | 
			
		||||
		if err := recover(); err != nil {
 | 
			
		||||
			rc.Err = err
 | 
			
		||||
			ginx.ErrorRes(ginCtx, err)
 | 
			
		||||
@@ -47,7 +49,6 @@ func (rc *Ctx) Handle(handler HandlerFunc) {
 | 
			
		||||
		panic(err)
 | 
			
		||||
	}
 | 
			
		||||
 | 
			
		||||
	begin := time.Now()
 | 
			
		||||
	handler(rc)
 | 
			
		||||
	rc.timed = time.Since(begin).Milliseconds()
 | 
			
		||||
	if rc.Conf == nil || !rc.Conf.noRes {
 | 
			
		||||
 
 | 
			
		||||
@@ -5,47 +5,24 @@ import (
 | 
			
		||||
 | 
			
		||||
	"mayfly-go/pkg/biz"
 | 
			
		||||
	"mayfly-go/pkg/config"
 | 
			
		||||
	"mayfly-go/pkg/global"
 | 
			
		||||
	"mayfly-go/pkg/model"
 | 
			
		||||
	"mayfly-go/pkg/utils/stringx"
 | 
			
		||||
	"time"
 | 
			
		||||
 | 
			
		||||
	"github.com/golang-jwt/jwt/v5"
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// 初始化jwt key与expire time等
 | 
			
		||||
func InitTokenConfig() {
 | 
			
		||||
	if ExpTime == 0 {
 | 
			
		||||
		JwtKey = config.Conf.Jwt.Key
 | 
			
		||||
		ExpTime = config.Conf.Jwt.ExpireTime
 | 
			
		||||
 | 
			
		||||
		// 如果配置文件中的jwt key为空,则随机生成字符串
 | 
			
		||||
		if JwtKey == "" {
 | 
			
		||||
			JwtKey = stringx.Rand(32)
 | 
			
		||||
			global.Log.Infof("config.yml未配置jwt.key, 随机生成key为: %s", JwtKey)
 | 
			
		||||
		}
 | 
			
		||||
	}
 | 
			
		||||
}
 | 
			
		||||
 | 
			
		||||
var (
 | 
			
		||||
	JwtKey  string
 | 
			
		||||
	ExpTime uint64
 | 
			
		||||
)
 | 
			
		||||
 | 
			
		||||
// 创建用户token
 | 
			
		||||
func CreateToken(userId uint64, username string) string {
 | 
			
		||||
	InitTokenConfig()
 | 
			
		||||
 | 
			
		||||
	// 带权限创建令牌
 | 
			
		||||
	// 设置有效期,过期需要重新登录获取token
 | 
			
		||||
	token := jwt.NewWithClaims(jwt.SigningMethodHS256, jwt.MapClaims{
 | 
			
		||||
		"id":       userId,
 | 
			
		||||
		"username": username,
 | 
			
		||||
		"exp":      time.Now().Add(time.Minute * time.Duration(ExpTime)).Unix(),
 | 
			
		||||
		"exp":      time.Now().Add(time.Minute * time.Duration(config.Conf.Jwt.ExpireTime)).Unix(),
 | 
			
		||||
	})
 | 
			
		||||
 | 
			
		||||
	// 使用自定义字符串加密 and get the complete encoded token as a string
 | 
			
		||||
	tokenString, err := token.SignedString([]byte(JwtKey))
 | 
			
		||||
	tokenString, err := token.SignedString([]byte(config.Conf.Jwt.Key))
 | 
			
		||||
	biz.ErrIsNilAppendErr(err, "token创建失败: %s")
 | 
			
		||||
	return tokenString
 | 
			
		||||
}
 | 
			
		||||
@@ -55,11 +32,10 @@ func ParseToken(tokenStr string) (*model.LoginAccount, error) {
 | 
			
		||||
	if tokenStr == "" {
 | 
			
		||||
		return nil, errors.New("token error")
 | 
			
		||||
	}
 | 
			
		||||
	InitTokenConfig()
 | 
			
		||||
 | 
			
		||||
	// Parse token
 | 
			
		||||
	token, err := jwt.Parse(tokenStr, func(token *jwt.Token) (any, error) {
 | 
			
		||||
		return []byte(JwtKey), nil
 | 
			
		||||
		return []byte(config.Conf.Jwt.Key), nil
 | 
			
		||||
	})
 | 
			
		||||
	if err != nil || token == nil {
 | 
			
		||||
		return nil, err
 | 
			
		||||
 
 | 
			
		||||
		Reference in New Issue
	
	Block a user