mirror of
https://gitee.com/dromara/mayfly-go
synced 2025-11-03 16:00:25 +08:00
221 lines
5.5 KiB
Go
221 lines
5.5 KiB
Go
package application
|
||
|
||
import (
|
||
"context"
|
||
"encoding/json"
|
||
"fmt"
|
||
"mayfly-go/internal/sys/domain/entity"
|
||
"mayfly-go/internal/sys/domain/repository"
|
||
"mayfly-go/pkg/cache"
|
||
"mayfly-go/pkg/contextx"
|
||
"mayfly-go/pkg/errorx"
|
||
"mayfly-go/pkg/logx"
|
||
"mayfly-go/pkg/model"
|
||
"mayfly-go/pkg/req"
|
||
"mayfly-go/pkg/utils/anyx"
|
||
"mayfly-go/pkg/utils/collx"
|
||
"mayfly-go/pkg/utils/jsonx"
|
||
"mayfly-go/pkg/utils/structx"
|
||
"mayfly-go/pkg/utils/timex"
|
||
"time"
|
||
)
|
||
|
||
type CreateLogReq struct {
|
||
Type int8 `json:"type"`
|
||
Description string `json:"description"`
|
||
ReqParam any `json:"reqParam" ` // 请求参数
|
||
Resp string `json:"resp" ` // 响应结构
|
||
Extra map[string]any // 额外日志信息
|
||
}
|
||
|
||
type AppendLogReq struct {
|
||
Type int8 `json:"type"`
|
||
AppendResp string `json:"appendResp" ` // 追加日志信息
|
||
Extra map[string]any // 额外日志信息
|
||
}
|
||
|
||
type Syslog interface {
|
||
GetPageList(condition *entity.SysLogQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error)
|
||
|
||
// 从请求上下文的参数保存系统日志
|
||
SaveFromReq(req *req.Ctx)
|
||
|
||
GetLogDetail(logId uint64) *entity.SysLog
|
||
|
||
// CreateLog 创建日志信息
|
||
CreateLog(ctx context.Context, log *CreateLogReq) (uint64, error)
|
||
|
||
// AppendLog 追加日志信息
|
||
AppendLog(logId uint64, appendLog *AppendLogReq)
|
||
|
||
// SetExtra 设置指定日志的extra信息, val为空则移除该key
|
||
SetExtra(logId uint64, key string, val any)
|
||
|
||
// Flush 实时追加的日志到数据库里
|
||
Flush(logId uint64, clearExtra bool)
|
||
}
|
||
|
||
type syslogAppImpl struct {
|
||
SyslogRepo repository.Syslog `inject:""`
|
||
}
|
||
|
||
func (m *syslogAppImpl) GetPageList(condition *entity.SysLogQuery, pageParam *model.PageParam, toEntity any, orderBy ...string) (*model.PageResult[any], error) {
|
||
return m.SyslogRepo.GetPageList(condition, pageParam, toEntity, orderBy...)
|
||
}
|
||
|
||
func (m *syslogAppImpl) SaveFromReq(req *req.Ctx) {
|
||
lg := contextx.GetLoginAccount(req.MetaCtx)
|
||
if lg == nil {
|
||
lg = &model.LoginAccount{Id: 0, Username: "-"}
|
||
}
|
||
syslog := new(entity.SysLog)
|
||
now := time.Now()
|
||
syslog.CreateTime = &now
|
||
syslog.Creator = lg.Username
|
||
syslog.CreatorId = lg.Id
|
||
|
||
logInfo := req.GetLogInfo()
|
||
syslog.Description = logInfo.Description
|
||
if logInfo.LogResp {
|
||
respB, _ := json.Marshal(req.ResData)
|
||
syslog.Resp = string(respB)
|
||
}
|
||
|
||
reqParam := req.ReqParam
|
||
if !anyx.IsBlank(reqParam) {
|
||
// 如果是字符串类型,则不使用json序列化
|
||
if reqStr, ok := reqParam.(string); ok {
|
||
syslog.ReqParam = reqStr
|
||
} else {
|
||
reqB, _ := json.Marshal(reqParam)
|
||
syslog.ReqParam = string(reqB)
|
||
}
|
||
}
|
||
|
||
if err := req.Error; err != nil {
|
||
syslog.Type = entity.SyslogTypeError
|
||
var errMsg string
|
||
switch t := err.(type) {
|
||
case errorx.BizError:
|
||
errMsg = fmt.Sprintf("errCode: %d, errMsg: %s", t.Code(), t.Error())
|
||
case error:
|
||
errMsg = t.Error()
|
||
}
|
||
syslog.Resp = errMsg
|
||
} else {
|
||
syslog.Type = entity.SyslogTypeSuccess
|
||
}
|
||
|
||
m.SyslogRepo.Insert(req.MetaCtx, syslog)
|
||
}
|
||
|
||
func (m *syslogAppImpl) GetLogDetail(logId uint64) *entity.SysLog {
|
||
syslog := m.GetCacheLog(logId)
|
||
if syslog != nil {
|
||
return syslog
|
||
}
|
||
syslog, err := m.SyslogRepo.GetById(logId)
|
||
if err != nil {
|
||
return nil
|
||
}
|
||
return syslog
|
||
}
|
||
|
||
func (m *syslogAppImpl) CreateLog(ctx context.Context, log *CreateLogReq) (uint64, error) {
|
||
syslog := new(entity.SysLog)
|
||
structx.Copy(syslog, log)
|
||
syslog.ReqParam = anyx.ToString(log.ReqParam)
|
||
if len(log.Extra) > 0 {
|
||
syslog.Extra = jsonx.ToStr(log.Extra)
|
||
}
|
||
if err := m.SyslogRepo.Insert(ctx, syslog); err != nil {
|
||
return 0, err
|
||
}
|
||
return syslog.Id, nil
|
||
}
|
||
|
||
func (m *syslogAppImpl) AppendLog(logId uint64, appendLog *AppendLogReq) {
|
||
syslog := m.GetCacheLog(logId)
|
||
if syslog == nil {
|
||
sl, err := m.SyslogRepo.GetById(logId)
|
||
if err != nil {
|
||
logx.Warnf("追加日志不存在: %d", logId)
|
||
return
|
||
}
|
||
syslog = sl
|
||
}
|
||
|
||
appendLogMsg := fmt.Sprintf("%s %s", timex.DefaultFormat(time.Now()), appendLog.AppendResp)
|
||
syslog.Resp = fmt.Sprintf("%s\n%s", syslog.Resp, appendLogMsg)
|
||
syslog.Type = appendLog.Type
|
||
if len(appendLog.Extra) > 0 {
|
||
existExtra := jsonx.ToMap(syslog.Extra)
|
||
syslog.Extra = jsonx.ToStr(collx.MapMerge(existExtra, appendLog.Extra))
|
||
}
|
||
|
||
m.SetCacheLog(logId, syslog)
|
||
}
|
||
|
||
func (m *syslogAppImpl) SetExtra(logId uint64, key string, val any) {
|
||
syslog := m.GetCacheLog(logId)
|
||
if syslog == nil {
|
||
sl, err := m.SyslogRepo.GetById(logId)
|
||
if err != nil {
|
||
logx.Warnf("追加日志不存在: %d", logId)
|
||
return
|
||
}
|
||
syslog = sl
|
||
}
|
||
|
||
extraMap := jsonx.ToMap(syslog.Extra)
|
||
if extraMap == nil {
|
||
extraMap = make(map[string]any)
|
||
}
|
||
if anyx.IsBlank(val) {
|
||
delete(extraMap, key)
|
||
} else {
|
||
extraMap[key] = val
|
||
}
|
||
syslog.Extra = jsonx.ToStr(extraMap)
|
||
|
||
m.SetCacheLog(logId, syslog)
|
||
}
|
||
|
||
func (m *syslogAppImpl) Flush(logId uint64, clearExtra bool) {
|
||
syslog := m.GetCacheLog(logId)
|
||
if syslog == nil {
|
||
return
|
||
}
|
||
|
||
// 如果刷入库的的时候还是执行中状态,则默认改为成功状态
|
||
if syslog.Type == entity.SyslogTypeRunning {
|
||
syslog.Type = entity.SyslogTypeSuccess
|
||
}
|
||
|
||
if clearExtra {
|
||
syslog.Extra = ""
|
||
}
|
||
m.SyslogRepo.UpdateById(context.Background(), syslog)
|
||
m.DelCacheLog(logId)
|
||
}
|
||
|
||
func (m *syslogAppImpl) GetCacheLog(logId uint64) *entity.SysLog {
|
||
log := new(entity.SysLog)
|
||
if !cache.Get(getLogKey(logId), log) {
|
||
return nil
|
||
}
|
||
return log
|
||
}
|
||
|
||
func (m *syslogAppImpl) SetCacheLog(logId uint64, log *entity.SysLog) {
|
||
cache.Set(getLogKey(logId), log, time.Hour*1)
|
||
}
|
||
|
||
func (m *syslogAppImpl) DelCacheLog(logId uint64) {
|
||
cache.Del(getLogKey(logId))
|
||
}
|
||
|
||
func getLogKey(logId uint64) string {
|
||
return fmt.Sprintf("mayfly:syslog:%d", logId)
|
||
}
|