先看效果
优化前

日志杂乱无章,阅读难度高,想要找某个接口的相关信息基本上找不到
优化后

接口信息一目了然
优化教程
utility -> utils.go
// PrettyPrint函数用于将传入的interface{}类型的变量v格式化为JSON字符串并打印出来
func PrettyPrint(v interface{}) string {
// 将v转换为JSON字符串
b, err := json.Marshal(v)
// 如果转换失败,则直接打印v
if err != nil {
fmt.Println(v)
return ""
}
// 创建一个bytes.Buffer类型的变量out,用于存储格式化后的JSON字符串
var out bytes.Buffer
// 使用json.Indent函数将b格式化为JSON字符串,并存储在out中
err = json.Indent(&out, b, "", " ")
// 如果格式化失败,则直接打印v
if err != nil {
fmt.Println(v)
return ""
}
// 打印格式化后的JSON字符串
return out.String()
}
// RequestLogBeautification 请求日志美化
func RequestLogBeautification(r *ghttp.Request) (logInfo string) {
// 获取请求上下文
ctx := contexts.Get(r.Context())
// 解析日志数据
logData := service.SysLog().AnalysisLog(r.Context())
// 默认用户名为“用户未登录”
userName := "用户未登录"
// 获取用户信息
userInfo := contexts.GetUser(r.Context())
// 如果用户信息不为空,则设置用户名为用户名和ID的组合
if userInfo != nil {
userName = fmt.Sprintf("%s[%d]", userInfo.Username, userInfo.Id)
}
// 初始化日志信息
logInfo = "\n"
// 获取请求处理程序
handler := r.GetServeHandler().Handler
// 如果处理程序类型为空或参数数量不为2,则返回错误
if handler.Info.Type == nil || handler.Info.Type.NumIn() != 2 {
logInfo = "err"
return
}
// 创建请求参数对象
var objectReq = reflect.New(handler.Info.Type.In(1))
// 获取请求参数的tags和summary
tags := gmeta.Get(objectReq, "tags")
summary := gmeta.Get(objectReq, "summary")
// 设置日志信息
logInfo = fmt.Sprintf("%s\n————————————————————> %s — %s <————————————————————\n", logInfo, tags, summary)
// 获取日志时间戳并格式化
timestamp := time.Unix(logData.Timestamp, 0).Format("2006-01-02 15:04:05")
// 设置日志信息
logInfo = fmt.Sprintf(
"%s\n请求模块:%s\n操作用户:%s\n请求方法:%s\n接口路径:%s\n请求耗时:%s\nIP地址:%s\n响应时间:%s\nGET数据:%s\nPOST数据:%s\n",
logInfo,
logData.Module,
userName,
logData.Method,
logData.Url,
AutomaticTimeConversion(strconv.FormatInt(logData.TakeUpTime, 10)),
logData.Ip,
timestamp,
PrettyPrint(logData.GetData),
PrettyPrint(logData.PostData),
)
// 获取响应数据并格式化
data := PrettyPrint(ctx.Response)
// 设置日志信息
logInfo = fmt.Sprintf("%s报错信息:%s\n", logInfo, logData.ErrorData.String())
logInfo = fmt.Sprintf("%s响应结果:%s\n", logInfo, data)
// 设置日志信息
logInfo = fmt.Sprintf("%s\n————————————————————请求完成————————————————————\n\n", logInfo)
// 返回日志信息
return
}
// AutomaticTimeConversion 自动时间转换
func AutomaticTimeConversion(timeStr string) string {
// 将毫秒转换为time.Duration类型
duration, err := time.ParseDuration(timeStr + "ms")
if err != nil {
return "Invalid time"
}
if duration > time.Minute {
minute := int(duration.Minutes())
seconds := int(duration.Seconds()) % 60
return fmt.Sprintf("%d分%d秒", minute, seconds)
}
// 如果时间间隔小于1秒,则直接返回毫秒数
if duration < time.Second {
return fmt.Sprintf("%d毫秒", int(duration.Milliseconds()))
}
// 如果时间间隔大于等于1秒,则转换为秒和毫秒
seconds := int(duration.Seconds())
milliseconds := int(duration.Milliseconds()) % 1000
return fmt.Sprintf("%d秒%d毫秒", seconds, milliseconds)
}internal -> logic -> hook -> init.go
func (s *sHook) AfterOutput(r *ghttp.Request) {
s.accessLog(r)
s.lastAdminActive(r)
logStr := ""
if logStr = utility.RequestLogBeautification(r); logStr != "err" {
g.Log().Infof(gctx.New(), "%s", logStr)
}
}