升级请求日志记录 + 升级 request wrapperHandle + 拆分after hook
This commit is contained in:
		| @ -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 日志 | ||||
|  | ||||
							
								
								
									
										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) | ||||
| 		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() | ||||
| 	} | ||||
| } | ||||
|  | ||||
| @ -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 | ||||
|  | ||||
| @ -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) | ||||
|  | ||||
		Reference in New Issue
	
	Block a user