From 015db63169d4c3d7b93ea1a06a70e5a08f6f3b3f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Thu, 14 Jul 2022 14:15:09 +0800 Subject: [PATCH] =?UTF-8?q?=E5=A2=9E=E5=8A=A0=20access=20=E8=AE=B0?= =?UTF-8?q?=E5=BD=95=E4=B8=AD=E9=97=B4=E4=BB=B6?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- define/response.go | 2 + middleware/access_log.go | 98 +++++++++++++++++++++++++++++++++++++++- 2 files changed, 99 insertions(+), 1 deletion(-) diff --git a/define/response.go b/define/response.go index b14ebcf..82076bd 100644 --- a/define/response.go +++ b/define/response.go @@ -14,6 +14,8 @@ var ( TraceIDField = "trace_id" // StartRequestTimeField 开始请求时间字段 StartRequestTimeField = "start_request_time" + // FinishRequestTimeField 完成请求时间 + FinishRequestTimeField = "finish_request_time" // ResponseCodeField 响应状态码字段 ResponseCodeField = "code" // ResponseMessageField 响应信息字段 diff --git a/middleware/access_log.go b/middleware/access_log.go index 11cb58b..1977414 100644 --- a/middleware/access_log.go +++ b/middleware/access_log.go @@ -8,6 +8,12 @@ package middleware import ( + "strings" + + "git.zhangdeman.cn/zhangdeman/util" + + "git.zhangdeman.cn/zhangdeman/gin/define" + "github.com/gin-gonic/gin" "go.uber.org/zap" ) @@ -17,8 +23,98 @@ import ( // Author : go_developer@163.com<白茶清欢> // // Date : 10:55 2022/7/14 -func Access(logger *zap.Logger) gin.HandlerFunc { +func Access(cfg *AccessConfig) gin.HandlerFunc { + // 未传入配置或者未传入日志实例 + if nil == cfg || nil == cfg.Logger { + return func(ctx *gin.Context) { + ctx.Next() + } + } + if nil == cfg.IsRecordLog { + cfg.IsRecordLog = defaultIsRecordLog + } + if nil == cfg.ExtraFieldList { + cfg.ExtraFieldList = make([]string, 0) + } + cfg.ExtraFieldList = append(cfg.ExtraFieldList, define.RecordRequestDataField, define.RecordResponseDataField) return func(ctx *gin.Context) { + ctx.Next() + if !cfg.IsRecordLog(ctx) { + // 不记录日志 + return + } + startRequestTime := ctx.GetInt64(define.StartRequestTimeField) + logDataList := []zap.Field{ + // 开始请求时间 + zap.Any(define.StartRequestTimeField, util.Time.FormatUnixNano(startRequestTime)), + } + // 结束时间 + finishRequestTime := ctx.GetInt64(define.FinishRequestTimeField) + logDataList = append( + logDataList, + zap.Any(define.FinishRequestTimeField, util.Time.FormatUnixNano(startRequestTime)), + zap.Int64("pkg_gin_request_cost", finishRequestTime-startRequestTime), + ) + // 请求header + if len(cfg.RequestHeaderList) == 0 { + // 全部记录 + zap.Any("pkg_gin_request_header", ctx.Request.Header) + } else { + headerTable := make(map[string][]string, 0) + for _, key := range cfg.RequestHeaderList { + headerTable[key] = ctx.Request.Header.Values(key) + } + zap.Any("pkg_gin_request_header", headerTable) + } + + // 响应header + if len(cfg.ResponseHeaderList) == 0 { + // 全部记录 + zap.Any("pkg_gin_response_header", ctx.Writer.Header()) + } else { + headerTable := make(map[string][]string, 0) + for _, key := range cfg.ResponseHeaderList { + headerTable[key] = ctx.Writer.Header().Values(key) + } + zap.Any("pkg_gin_response_header", headerTable) + } + + // 扩展数据 + for _, field := range cfg.ExtraFieldList { + val, _ := ctx.Get(field) + logDataList = append(logDataList, zap.Any(field, val)) + } + cfg.Logger.Info("请求日志记录", logDataList...) + if nil != cfg.FinishHook { + // hook 不为nil, 自动触发 + cfg.FinishHook(ctx) + } } } + +// AccessConfig 访问记录的配置 +// +// Author : go_developer@163.com<白茶清欢> +// +// 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) // 请求处理完成之后, 触发的hook函数 +} + +// 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 + } + return false +}