升级请求日志记录 + 升级 request wrapperHandle + 拆分after hook
This commit is contained in:
parent
b2fe05111c
commit
b9c0389e7b
@ -8,14 +8,15 @@
|
|||||||
package middleware
|
package middleware
|
||||||
|
|
||||||
import (
|
import (
|
||||||
|
"git.zhangdeman.cn/zhangdeman/consts"
|
||||||
|
"git.zhangdeman.cn/zhangdeman/gin/request"
|
||||||
|
"go.uber.org/zap"
|
||||||
"strings"
|
"strings"
|
||||||
|
|
||||||
"git.zhangdeman.cn/zhangdeman/wrapper"
|
|
||||||
|
|
||||||
"git.zhangdeman.cn/zhangdeman/gin/define"
|
"git.zhangdeman.cn/zhangdeman/gin/define"
|
||||||
|
|
||||||
|
"git.zhangdeman.cn/zhangdeman/logger"
|
||||||
"github.com/gin-gonic/gin"
|
"github.com/gin-gonic/gin"
|
||||||
"go.uber.org/zap"
|
|
||||||
)
|
)
|
||||||
|
|
||||||
// fillCfg 填充默认配置
|
// fillCfg 填充默认配置
|
||||||
@ -30,20 +31,12 @@ func fillCfg(cfg *AccessConfig) {
|
|||||||
if nil == cfg.IsRecordLog {
|
if nil == cfg.IsRecordLog {
|
||||||
cfg.IsRecordLog = defaultIsRecordLog
|
cfg.IsRecordLog = defaultIsRecordLog
|
||||||
}
|
}
|
||||||
if nil == cfg.ExtraFieldList {
|
|
||||||
cfg.ExtraFieldList = make([]string, 0)
|
|
||||||
}
|
|
||||||
if nil == cfg.RequestHeaderList {
|
if nil == cfg.RequestHeaderList {
|
||||||
cfg.RequestHeaderList = make([]string, 0)
|
cfg.RequestHeaderList = make([]string, 0)
|
||||||
}
|
}
|
||||||
if nil == cfg.ResponseHeaderList {
|
if nil == cfg.ResponseHeaderList {
|
||||||
cfg.ResponseHeaderList = make([]string, 0)
|
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
|
// getLogRequestHeader 获取记录的请求header
|
||||||
@ -97,43 +90,31 @@ func LogRequest(cfg *AccessConfig) gin.HandlerFunc {
|
|||||||
handleConfig := define.GetHttpHandleConfig()
|
handleConfig := define.GetHttpHandleConfig()
|
||||||
return func(ctx *gin.Context) {
|
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()
|
ctx.Next()
|
||||||
return
|
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()
|
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))
|
finishRequestTime := request.WrapperHandle.GetCtxIntData(ctx, handleConfig.FinishRequestTimeField, 0)
|
||||||
logDataList = append(
|
ctx.Set(handleConfig.FinishRequestTimeField, finishRequestTime)
|
||||||
logDataList,
|
// 记录相应日志
|
||||||
zap.Any(handleConfig.FinishRequestTimeField, finishRequestTime.FormatUnixMilli()), // 请求完成时间
|
logResponseData := logger.NewLogData(ctx, consts.LogTypeOutput, "", map[string]any{
|
||||||
zap.Int64("pkg_gin_request_cost", finishRequestTime.UnixMilli()-startRequestTime.UnixMilli()), // 接口耗时
|
handleConfig.FinishRequestTimeField: finishRequestTime, // 完成请求时间
|
||||||
zap.Any("pkg_gin_request_header", getLogRequestHeader(ctx, cfg)), // 请求header
|
"request_cost": finishRequestTime - startRequestTime, // 请求耗时
|
||||||
zap.Any("pkg_gin_response_header", getLogResponseHeader(ctx, cfg)), // 响应header
|
"response_body": request.WrapperHandle.GetResponseBody(ctx, handleConfig.ResponseDataField, map[string]any{}), // 响应body
|
||||||
)
|
"response_header": getLogResponseHeader(ctx, cfg), // 响应header
|
||||||
|
})
|
||||||
// 扩展数据
|
cfg.Logger.Info("接口响应日志记录", logger.ZapLogDataList(logResponseData)...)
|
||||||
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(),
|
|
||||||
)
|
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,8 +128,6 @@ type AccessConfig struct {
|
|||||||
RequestHeaderList []string // 要记录哪些header , 不传全部记录
|
RequestHeaderList []string // 要记录哪些header , 不传全部记录
|
||||||
ResponseHeaderList []string // 要记录哪些响应header, 不传全部记录
|
ResponseHeaderList []string // 要记录哪些响应header, 不传全部记录
|
||||||
IsRecordLog func(ctx *gin.Context) bool // 验证当前请求是否记录日志
|
IsRecordLog func(ctx *gin.Context) bool // 验证当前请求是否记录日志
|
||||||
ExtraFieldList []string // 记录的扩展字段列表,请将相关数据使用 ctx.Set 写入上下文中, 日志会自动记录
|
|
||||||
FinishHook func(ctx *gin.Context, requestData []byte, responseData map[string]interface{}, cost int64) // 请求处理完成之后, 触发的hook函数
|
|
||||||
}
|
}
|
||||||
|
|
||||||
// defaultIsRecordLog 默认仅记录 json api 日志
|
// defaultIsRecordLog 默认仅记录 json api 日志
|
||||||
|
38
middleware/hook_after_response.go
Normal file
38
middleware/hook_after_response.go
Normal 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),
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
@ -32,7 +32,7 @@ func InitRequest() gin.HandlerFunc {
|
|||||||
requestID := getRequestID(ctx, traceID)
|
requestID := getRequestID(ctx, traceID)
|
||||||
ctx.Set(httpHandleConfig.TraceIDField, traceID)
|
ctx.Set(httpHandleConfig.TraceIDField, traceID)
|
||||||
ctx.Set(httpHandleConfig.RequestIDField, requestID)
|
ctx.Set(httpHandleConfig.RequestIDField, requestID)
|
||||||
ctx.Set(httpHandleConfig.StartRequestTimeField, time.Now())
|
ctx.Set(httpHandleConfig.StartRequestTimeField, time.Now().UnixMilli())
|
||||||
ctx.Next()
|
ctx.Next()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -160,8 +160,15 @@ func (wh *wrapperHandle) GetRequestBody(ctx *gin.Context) map[string]any {
|
|||||||
// Author : go_developer@163.com<白茶清欢>
|
// Author : go_developer@163.com<白茶清欢>
|
||||||
//
|
//
|
||||||
// Date : 15:18 2024/1/2
|
// Date : 15:18 2024/1/2
|
||||||
func (wh *wrapperHandle) GetResponseBody(ctx *gin.Context, defaultVal string) string {
|
func (wh *wrapperHandle) GetResponseBody(ctx *gin.Context, key string, defaultVal any) any {
|
||||||
return ""
|
if nil == ctx {
|
||||||
|
return defaultVal
|
||||||
|
}
|
||||||
|
if val, exist := ctx.Get(key); !exist || nil == val {
|
||||||
|
return defaultVal
|
||||||
|
} else {
|
||||||
|
return val
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// GetClientIp 获取请求客户端IP
|
// GetClientIp 获取请求客户端IP
|
||||||
|
@ -44,13 +44,13 @@ func Send(ctx *gin.Context, code interface{}, httpCode int, data interface{}) {
|
|||||||
// 设置数据已发送的标识
|
// 设置数据已发送的标识
|
||||||
defer ctx.Set(hasSendResponseFlag, true)
|
defer ctx.Set(hasSendResponseFlag, true)
|
||||||
responseConfig := define.GetHttpHandleConfig()
|
responseConfig := define.GetHttpHandleConfig()
|
||||||
finishRequestTime := time.Now()
|
finishRequestTime := time.Now().UnixMilli()
|
||||||
responseData := map[string]interface{}{
|
responseData := map[string]interface{}{
|
||||||
responseConfig.ResponseCodeField: code,
|
responseConfig.ResponseCodeField: code,
|
||||||
responseConfig.ResponseMessageField: exception.GetMessage(code),
|
responseConfig.ResponseMessageField: exception.GetMessage(code),
|
||||||
responseConfig.ResponseTraceIDField: ctx.GetString(responseConfig.ResponseTraceIDField),
|
responseConfig.ResponseTraceIDField: ctx.GetString(responseConfig.ResponseTraceIDField),
|
||||||
responseConfig.ResponseDataField: data,
|
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)
|
ctx.Set(responseConfig.FinishRequestTimeField, finishRequestTime)
|
||||||
|
Loading…
Reference in New Issue
Block a user