升级请求日志记录 + 升级 request wrapperHandle + 拆分after hook

This commit is contained in:
白茶清欢 2024-07-26 12:25:22 +08:00
parent b2fe05111c
commit b9c0389e7b
5 changed files with 78 additions and 54 deletions

View File

@ -8,14 +8,15 @@
package middleware
import (
"git.zhangdeman.cn/zhangdeman/consts"
"git.zhangdeman.cn/zhangdeman/gin/request"
"go.uber.org/zap"
"strings"
"git.zhangdeman.cn/zhangdeman/wrapper"
"git.zhangdeman.cn/zhangdeman/gin/define"
"git.zhangdeman.cn/zhangdeman/logger"
"github.com/gin-gonic/gin"
"go.uber.org/zap"
)
// fillCfg 填充默认配置
@ -30,20 +31,12 @@ func fillCfg(cfg *AccessConfig) {
if nil == cfg.IsRecordLog {
cfg.IsRecordLog = defaultIsRecordLog
}
if nil == cfg.ExtraFieldList {
cfg.ExtraFieldList = make([]string, 0)
}
if nil == cfg.RequestHeaderList {
cfg.RequestHeaderList = make([]string, 0)
}
if nil == cfg.ResponseHeaderList {
cfg.ResponseHeaderList = make([]string, 0)
}
if nil == cfg.ExtraFieldList {
cfg.ExtraFieldList = make([]string, 0)
}
handleConfig := define.GetHttpHandleConfig()
cfg.ExtraFieldList = append(cfg.ExtraFieldList, handleConfig.RecordRequestDataField, handleConfig.RecordResponseDataField)
}
// getLogRequestHeader 获取记录的请求header
@ -97,43 +90,31 @@ func LogRequest(cfg *AccessConfig) gin.HandlerFunc {
handleConfig := define.GetHttpHandleConfig()
return func(ctx *gin.Context) {
// 未传入配置或者未传入日志实例
if nil == cfg || nil == cfg.Logger || !cfg.IsRecordLog(ctx) {
if nil == cfg || nil == cfg.Logger || (nil != cfg.IsRecordLog && !cfg.IsRecordLog(ctx)) {
ctx.Next()
return
}
startRequestTime := request.WrapperHandle.GetCtxIntData(ctx, handleConfig.StartRequestTimeField, 0)
// 记录请求日志
logData := logger.NewLogData(ctx, consts.LogTypeRequest, "", map[string]any{
handleConfig.StartRequestTimeField: startRequestTime, // 开始请求时间
"request_header": getLogRequestHeader(ctx, cfg), // 请求header
"request_query": request.WrapperHandle.GetQuery(ctx), // 获取请求query
"request_body": request.WrapperHandle.GetRequestBody(ctx), // 请求body
})
cfg.Logger.Info("接口请求日志记录", logger.ZapLogDataList(logData)...)
ctx.Next()
startRequestTime := wrapper.OwnTime(ctx.GetTime(handleConfig.StartRequestTimeField))
logDataList := []zap.Field{
// 开始请求时间
zap.Any(handleConfig.StartRequestTimeField, startRequestTime.FormatUnixMilli()),
}
// 结束时间
finishRequestTime := wrapper.OwnTime(ctx.GetTime(handleConfig.FinishRequestTimeField))
logDataList = append(
logDataList,
zap.Any(handleConfig.FinishRequestTimeField, finishRequestTime.FormatUnixMilli()), // 请求完成时间
zap.Int64("pkg_gin_request_cost", finishRequestTime.UnixMilli()-startRequestTime.UnixMilli()), // 接口耗时
zap.Any("pkg_gin_request_header", getLogRequestHeader(ctx, cfg)), // 请求header
zap.Any("pkg_gin_response_header", getLogResponseHeader(ctx, cfg)), // 响应header
)
// 扩展数据
for _, field := range cfg.ExtraFieldList {
val, _ := ctx.Get(field)
logDataList = append(logDataList, zap.Any(field, val))
}
cfg.Logger.Info("请求日志记录", logDataList...)
if nil == cfg.FinishHook {
return
}
// hook 不为nil, 自动触发
cfg.FinishHook(
ctx,
[]byte(ctx.GetString(handleConfig.RecordRequestDataField)),
ctx.GetStringMap(handleConfig.RecordResponseDataField),
finishRequestTime.UnixMilli()-startRequestTime.UnixMilli(),
)
finishRequestTime := request.WrapperHandle.GetCtxIntData(ctx, handleConfig.FinishRequestTimeField, 0)
ctx.Set(handleConfig.FinishRequestTimeField, finishRequestTime)
// 记录相应日志
logResponseData := logger.NewLogData(ctx, consts.LogTypeOutput, "", map[string]any{
handleConfig.FinishRequestTimeField: finishRequestTime, // 完成请求时间
"request_cost": finishRequestTime - startRequestTime, // 请求耗时
"response_body": request.WrapperHandle.GetResponseBody(ctx, handleConfig.ResponseDataField, map[string]any{}), // 响应body
"response_header": getLogResponseHeader(ctx, cfg), // 响应header
})
cfg.Logger.Info("接口响应日志记录", logger.ZapLogDataList(logResponseData)...)
}
}
@ -143,12 +124,10 @@ func LogRequest(cfg *AccessConfig) gin.HandlerFunc {
//
// Date : 11:26 2022/7/14
type AccessConfig struct {
Logger *zap.Logger // 日志实例
RequestHeaderList []string // 要记录哪些header , 不传全部记录
ResponseHeaderList []string // 要记录哪些响应header, 不传全部记录
IsRecordLog func(ctx *gin.Context) bool // 验证当前请求是否记录日志
ExtraFieldList []string // 记录的扩展字段列表,请将相关数据使用 ctx.Set 写入上下文中, 日志会自动记录
FinishHook func(ctx *gin.Context, requestData []byte, responseData map[string]interface{}, cost int64) // 请求处理完成之后, 触发的hook函数
Logger *zap.Logger // 日志实例
RequestHeaderList []string // 要记录哪些header , 不传全部记录
ResponseHeaderList []string // 要记录哪些响应header, 不传全部记录
IsRecordLog func(ctx *gin.Context) bool // 验证当前请求是否记录日志
}
// defaultIsRecordLog 默认仅记录 json api 日志

View File

@ -0,0 +1,38 @@
// Package middleware ...
//
// Description : middleware ...
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 2024-07-26 11:54
package middleware
import (
"git.zhangdeman.cn/zhangdeman/gin/define"
"git.zhangdeman.cn/zhangdeman/gin/request"
"github.com/gin-gonic/gin"
)
type HookFunc func(ctx *gin.Context, requestData []byte, responseData map[string]interface{}, cost int64)
// HookAfterResponseMiddleware 请求最终处理完成之后执行的中间件
//
// Author : go_developer@163.com<白茶清欢>
//
// Date : 11:55 2024/7/26
func HookAfterResponseMiddleware(ctx *gin.Context, hookFunc HookFunc) gin.HandlerFunc {
handleConfig := define.GetHttpHandleConfig()
return func(ctx *gin.Context) {
ctx.Next()
if nil == hookFunc {
return
}
// hook 不为nil, 自动触发
hookFunc(
ctx,
[]byte(ctx.GetString(handleConfig.RecordRequestDataField)),
ctx.GetStringMap(handleConfig.RecordResponseDataField),
request.WrapperHandle.GetCtxIntData(ctx, handleConfig.StartRequestTimeField, 0)-request.WrapperHandle.GetCtxIntData(ctx, handleConfig.StartRequestTimeField, 0),
)
}
}

View File

@ -32,7 +32,7 @@ func InitRequest() gin.HandlerFunc {
requestID := getRequestID(ctx, traceID)
ctx.Set(httpHandleConfig.TraceIDField, traceID)
ctx.Set(httpHandleConfig.RequestIDField, requestID)
ctx.Set(httpHandleConfig.StartRequestTimeField, time.Now())
ctx.Set(httpHandleConfig.StartRequestTimeField, time.Now().UnixMilli())
ctx.Next()
}
}

View File

@ -160,8 +160,15 @@ func (wh *wrapperHandle) GetRequestBody(ctx *gin.Context) map[string]any {
// Author : go_developer@163.com<白茶清欢>
//
// Date : 15:18 2024/1/2
func (wh *wrapperHandle) GetResponseBody(ctx *gin.Context, defaultVal string) string {
return ""
func (wh *wrapperHandle) GetResponseBody(ctx *gin.Context, key string, defaultVal any) any {
if nil == ctx {
return defaultVal
}
if val, exist := ctx.Get(key); !exist || nil == val {
return defaultVal
} else {
return val
}
}
// GetClientIp 获取请求客户端IP

View File

@ -44,13 +44,13 @@ func Send(ctx *gin.Context, code interface{}, httpCode int, data interface{}) {
// 设置数据已发送的标识
defer ctx.Set(hasSendResponseFlag, true)
responseConfig := define.GetHttpHandleConfig()
finishRequestTime := time.Now()
finishRequestTime := time.Now().UnixMilli()
responseData := map[string]interface{}{
responseConfig.ResponseCodeField: code,
responseConfig.ResponseMessageField: exception.GetMessage(code),
responseConfig.ResponseTraceIDField: ctx.GetString(responseConfig.ResponseTraceIDField),
responseConfig.ResponseDataField: data,
responseConfig.HandleRequestCostField: finishRequestTime.UnixMilli() - ctx.GetTime(responseConfig.StartRequestTimeField).UnixMilli(),
responseConfig.HandleRequestCostField: finishRequestTime - ctx.GetTime(responseConfig.StartRequestTimeField).UnixMilli(),
}
// 记录完成时间
ctx.Set(responseConfig.FinishRequestTimeField, finishRequestTime)