2022-07-14 11:01:06 +08:00
|
|
|
// Package middleware ...
|
|
|
|
//
|
|
|
|
// Description : middleware ...
|
|
|
|
//
|
|
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
|
|
//
|
|
|
|
// Date : 2022-07-14 10:53
|
|
|
|
package middleware
|
|
|
|
|
|
|
|
import (
|
2024-08-17 17:31:11 +08:00
|
|
|
"strings"
|
|
|
|
|
2024-07-26 12:25:22 +08:00
|
|
|
"git.zhangdeman.cn/zhangdeman/consts"
|
|
|
|
"git.zhangdeman.cn/zhangdeman/gin/request"
|
|
|
|
"go.uber.org/zap"
|
2022-07-14 14:15:09 +08:00
|
|
|
|
|
|
|
"git.zhangdeman.cn/zhangdeman/gin/define"
|
|
|
|
|
2024-07-26 12:25:22 +08:00
|
|
|
"git.zhangdeman.cn/zhangdeman/logger"
|
2022-07-14 11:01:06 +08:00
|
|
|
"github.com/gin-gonic/gin"
|
|
|
|
)
|
|
|
|
|
2023-12-29 16:02:39 +08:00
|
|
|
// fillCfg 填充默认配置
|
2022-07-14 11:01:06 +08:00
|
|
|
//
|
|
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
|
|
//
|
2023-12-29 16:02:39 +08:00
|
|
|
// Date : 15:37 2023/12/29
|
|
|
|
func fillCfg(cfg *AccessConfig) {
|
|
|
|
if nil == cfg {
|
|
|
|
return
|
2022-07-14 14:15:09 +08:00
|
|
|
}
|
|
|
|
if nil == cfg.IsRecordLog {
|
|
|
|
cfg.IsRecordLog = defaultIsRecordLog
|
|
|
|
}
|
2023-12-29 16:12:33 +08:00
|
|
|
if nil == cfg.RequestHeaderList {
|
|
|
|
cfg.RequestHeaderList = make([]string, 0)
|
|
|
|
}
|
|
|
|
if nil == cfg.ResponseHeaderList {
|
|
|
|
cfg.ResponseHeaderList = make([]string, 0)
|
|
|
|
}
|
2023-12-29 16:02:39 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// getLogRequestHeader 获取记录的请求header
|
|
|
|
//
|
|
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
|
|
//
|
|
|
|
// Date : 15:59 2023/12/29
|
|
|
|
func getLogRequestHeader(ctx *gin.Context, cfg *AccessConfig) map[string][]string {
|
|
|
|
// 请求header
|
|
|
|
headerTable := make(map[string][]string)
|
|
|
|
if len(cfg.RequestHeaderList) == 0 {
|
|
|
|
// 全部记录
|
2024-07-23 21:34:40 +08:00
|
|
|
for headerKey := range ctx.Request.Header {
|
2023-12-29 16:02:39 +08:00
|
|
|
cfg.RequestHeaderList = append(cfg.RequestHeaderList, headerKey)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for _, key := range cfg.RequestHeaderList {
|
|
|
|
headerTable[key] = ctx.Request.Header.Values(key)
|
|
|
|
}
|
|
|
|
return headerTable
|
|
|
|
}
|
|
|
|
|
|
|
|
// getLogResponseHeader 记录相应header
|
|
|
|
//
|
|
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
|
|
//
|
|
|
|
// Date : 16:01 2023/12/29
|
|
|
|
func getLogResponseHeader(ctx *gin.Context, cfg *AccessConfig) map[string][]string {
|
|
|
|
// 响应header
|
|
|
|
responseHeaderTable := make(map[string][]string)
|
|
|
|
if len(cfg.ResponseHeaderList) == 0 {
|
|
|
|
// 全部记录
|
2024-07-23 21:34:40 +08:00
|
|
|
for headerKey := range ctx.Writer.Header() {
|
2023-12-29 16:02:39 +08:00
|
|
|
cfg.ResponseHeaderList = append(cfg.ResponseHeaderList, headerKey)
|
|
|
|
}
|
|
|
|
zap.Any("pkg_gin_response_header", ctx.Writer.Header())
|
|
|
|
}
|
|
|
|
for _, key := range cfg.ResponseHeaderList {
|
|
|
|
responseHeaderTable[key] = ctx.Writer.Header().Values(key)
|
|
|
|
}
|
|
|
|
return responseHeaderTable
|
|
|
|
}
|
|
|
|
|
2023-12-29 17:58:22 +08:00
|
|
|
// LogRequest 记录请求日志
|
2023-12-29 16:02:39 +08:00
|
|
|
//
|
|
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
|
|
//
|
|
|
|
// Date : 10:55 2022/7/14
|
2023-12-29 17:58:22 +08:00
|
|
|
func LogRequest(cfg *AccessConfig) gin.HandlerFunc {
|
2023-12-29 16:02:39 +08:00
|
|
|
fillCfg(cfg)
|
2024-07-23 21:34:40 +08:00
|
|
|
handleConfig := define.GetHttpHandleConfig()
|
2022-07-14 11:01:06 +08:00
|
|
|
return func(ctx *gin.Context) {
|
2023-12-29 16:02:39 +08:00
|
|
|
// 未传入配置或者未传入日志实例
|
2024-07-26 12:25:22 +08:00
|
|
|
if nil == cfg || nil == cfg.Logger || (nil != cfg.IsRecordLog && !cfg.IsRecordLog(ctx)) {
|
2023-12-29 16:02:39 +08:00
|
|
|
ctx.Next()
|
2022-07-14 14:15:09 +08:00
|
|
|
return
|
|
|
|
}
|
2024-07-26 12:25:22 +08:00
|
|
|
startRequestTime := request.WrapperHandle.GetCtxIntData(ctx, handleConfig.StartRequestTimeField, 0)
|
|
|
|
// 记录请求日志
|
|
|
|
logData := logger.NewLogData(ctx, consts.LogTypeRequest, "", map[string]any{
|
2024-09-26 17:40:09 +08:00
|
|
|
handleConfig.StartRequestTimeField: startRequestTime, // 开始请求时间
|
|
|
|
"request_header": getLogRequestHeader(ctx, cfg), // 请求header
|
|
|
|
"request_query": request.WrapperHandle.ParseQuery(ctx), // 获取请求query
|
|
|
|
"request_body": request.WrapperHandle.ParseBody(ctx), // 请求body
|
2024-07-26 12:25:22 +08:00
|
|
|
})
|
|
|
|
cfg.Logger.Info("接口请求日志记录", logger.ZapLogDataList(logData)...)
|
2023-12-29 16:02:39 +08:00
|
|
|
ctx.Next()
|
2022-07-14 14:15:09 +08:00
|
|
|
// 结束时间
|
2024-07-26 12:25:22 +08:00
|
|
|
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
|
|
|
|
})
|
2024-08-17 17:31:11 +08:00
|
|
|
if ctx.GetBool(define.GetHttpHandleConfig().RequestIsSuccessField) {
|
|
|
|
cfg.Logger.Info("接口响应日志记录", logger.ZapLogDataList(logResponseData)...)
|
|
|
|
} else {
|
|
|
|
cfg.Logger.Error("接口响应日志记录", logger.ZapLogDataList(logResponseData)...)
|
|
|
|
}
|
2022-07-14 14:15:09 +08:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// AccessConfig 访问记录的配置
|
|
|
|
//
|
|
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
|
|
//
|
|
|
|
// Date : 11:26 2022/7/14
|
|
|
|
type AccessConfig struct {
|
2024-07-26 12:25:22 +08:00
|
|
|
Logger *zap.Logger // 日志实例
|
|
|
|
RequestHeaderList []string // 要记录哪些header , 不传全部记录
|
|
|
|
ResponseHeaderList []string // 要记录哪些响应header, 不传全部记录
|
|
|
|
IsRecordLog func(ctx *gin.Context) bool // 验证当前请求是否记录日志
|
2022-07-14 14:15:09 +08:00
|
|
|
}
|
|
|
|
|
|
|
|
// defaultIsRecordLog 默认仅记录 json api 日志
|
|
|
|
//
|
|
|
|
// Author : go_developer@163.com<白茶清欢>
|
|
|
|
//
|
|
|
|
// Date : 11:31 2022/7/14
|
|
|
|
func defaultIsRecordLog(ctx *gin.Context) bool {
|
|
|
|
if strings.Contains(ctx.Writer.Header().Get("Content-type"), "application/json") {
|
|
|
|
return true
|
2022-07-14 11:01:06 +08:00
|
|
|
}
|
2022-07-14 14:15:09 +08:00
|
|
|
return false
|
2022-07-14 11:01:06 +08:00
|
|
|
}
|