mirror of
				https://gitee.com/dromara/mayfly-go
				synced 2025-11-04 16:30:25 +08:00 
			
		
		
		
	
		
			
				
	
	
		
			151 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
			
		
		
	
	
			151 lines
		
	
	
		
			3.6 KiB
		
	
	
	
		
			Go
		
	
	
	
	
	
package req
 | 
						||
 | 
						||
import (
 | 
						||
	"fmt"
 | 
						||
	"mayfly-go/pkg/contextx"
 | 
						||
	"mayfly-go/pkg/errorx"
 | 
						||
	"mayfly-go/pkg/i18n"
 | 
						||
	"mayfly-go/pkg/logx"
 | 
						||
	"mayfly-go/pkg/utils/anyx"
 | 
						||
	"mayfly-go/pkg/utils/runtimex"
 | 
						||
)
 | 
						||
 | 
						||
type SaveLogFunc func(*Ctx)
 | 
						||
 | 
						||
var saveLog SaveLogFunc
 | 
						||
 | 
						||
// 设置保存日志处理函数
 | 
						||
func SetSaveLogFunc(sl SaveLogFunc) {
 | 
						||
	saveLog = sl
 | 
						||
}
 | 
						||
 | 
						||
type LogInfo struct {
 | 
						||
	Description string // 请求描述
 | 
						||
 | 
						||
	LogResp bool // 是否记录返回结果
 | 
						||
	save    bool // 是否保存日志
 | 
						||
}
 | 
						||
 | 
						||
// NewLog 新建日志信息,默认不保存该日志
 | 
						||
func NewLog(description string) *LogInfo {
 | 
						||
	return &LogInfo{Description: description, LogResp: false, save: false}
 | 
						||
}
 | 
						||
 | 
						||
// NewLogI 使用msgId新建日志信息,默认不保存该日志
 | 
						||
func NewLogI(msgId i18n.MsgId) *LogInfo {
 | 
						||
	return &LogInfo{Description: i18n.T(msgId), LogResp: false, save: false}
 | 
						||
}
 | 
						||
 | 
						||
// NewLogSave 新建日志信息,并且需要保存该日志信息
 | 
						||
func NewLogSave(description string) *LogInfo {
 | 
						||
	return &LogInfo{Description: description, LogResp: false, save: true}
 | 
						||
}
 | 
						||
 | 
						||
// NewLogSaveI 使用msgId新建日志信息,并且需要保存该日志信息
 | 
						||
func NewLogSaveI(msgId i18n.MsgId) *LogInfo {
 | 
						||
	return &LogInfo{Description: i18n.T(msgId), LogResp: false, save: true}
 | 
						||
}
 | 
						||
 | 
						||
// 记录返回结果
 | 
						||
func (i *LogInfo) WithLogResp() *LogInfo {
 | 
						||
	i.LogResp = true
 | 
						||
	return i
 | 
						||
}
 | 
						||
 | 
						||
const DefaultLogFrames = 18
 | 
						||
 | 
						||
func LogHandler(rc *Ctx) error {
 | 
						||
	if rc.Conf == nil || rc.Conf.logInfo == nil {
 | 
						||
		return nil
 | 
						||
	}
 | 
						||
 | 
						||
	li := rc.Conf.logInfo
 | 
						||
 | 
						||
	attrMap := make(map[string]any, 0)
 | 
						||
 | 
						||
	req := rc.GetRequest()
 | 
						||
	attrMap[req.Method] = req.URL.Path
 | 
						||
 | 
						||
	if la := contextx.GetLoginAccount(rc.MetaCtx); la != nil {
 | 
						||
		attrMap["uid"] = la.Id
 | 
						||
		attrMap["uname"] = la.Username
 | 
						||
	}
 | 
						||
 | 
						||
	// 如果需要保存日志,并且保存日志处理函数存在则执行保存日志函数
 | 
						||
	if li.save && saveLog != nil {
 | 
						||
		go saveLog(rc)
 | 
						||
	}
 | 
						||
 | 
						||
	logMsg := li.Description
 | 
						||
	rcErr := rc.Error
 | 
						||
 | 
						||
	if logx.GetConfig().IsJsonType() {
 | 
						||
		// json格式日志处理
 | 
						||
		attrMap["req"] = rc.ReqParam
 | 
						||
		if li.LogResp {
 | 
						||
			attrMap["resp"] = rc.ResData
 | 
						||
		}
 | 
						||
		attrMap["exeTime"] = rc.timed
 | 
						||
 | 
						||
		if rcErr != nil {
 | 
						||
			nFrames := DefaultLogFrames
 | 
						||
			if _, ok := rc.Error.(errorx.BizError); ok {
 | 
						||
				nFrames = nFrames / 2
 | 
						||
			}
 | 
						||
			attrMap["error"] = rc.Err
 | 
						||
			// 跳过log_handler等相关堆栈
 | 
						||
			attrMap["stacktrace"] = runtimex.StackStr(5, nFrames)
 | 
						||
		}
 | 
						||
	} else {
 | 
						||
		// 处理文本格式日志信息
 | 
						||
		if rcErr != nil {
 | 
						||
			logMsg = getErrMsg(rc, rcErr)
 | 
						||
		} else {
 | 
						||
			logMsg = getLogMsg(rc)
 | 
						||
		}
 | 
						||
	}
 | 
						||
 | 
						||
	if rcErr != nil {
 | 
						||
		logx.ErrorWithFields(rc.MetaCtx, logMsg, attrMap)
 | 
						||
		return nil
 | 
						||
	}
 | 
						||
	logx.InfoWithFields(rc.MetaCtx, logMsg, attrMap)
 | 
						||
	return nil
 | 
						||
}
 | 
						||
 | 
						||
func getLogMsg(rc *Ctx) string {
 | 
						||
	logInfo := rc.Conf.logInfo
 | 
						||
	msg := logInfo.Description + fmt.Sprintf(" ->%dms", rc.timed)
 | 
						||
	if !anyx.IsBlank(rc.ReqParam) {
 | 
						||
		msg = msg + fmt.Sprintf("\n--> %s", anyx.ToString(rc.ReqParam))
 | 
						||
	}
 | 
						||
 | 
						||
	// 返回结果不为空,则记录返回结果
 | 
						||
	if logInfo.LogResp && !anyx.IsBlank(rc.ResData) {
 | 
						||
		msg = msg + fmt.Sprintf("\n<-- %s", anyx.ToString(rc.ResData))
 | 
						||
	}
 | 
						||
	return msg
 | 
						||
}
 | 
						||
 | 
						||
func getErrMsg(rc *Ctx, err any) string {
 | 
						||
	msg := rc.Conf.logInfo.Description + fmt.Sprintf(" ->%dms", rc.timed)
 | 
						||
	if !anyx.IsBlank(rc.ReqParam) {
 | 
						||
		msg = msg + fmt.Sprintf("\n--> %s", anyx.ToString(rc.ReqParam))
 | 
						||
	}
 | 
						||
 | 
						||
	nFrames := DefaultLogFrames
 | 
						||
	var errMsg string
 | 
						||
	switch t := err.(type) {
 | 
						||
	case *errorx.BizError:
 | 
						||
		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.StackStr(5, nFrames))
 | 
						||
	return (msg + errMsg)
 | 
						||
}
 |