From bb5d97f6eb71557e0c4063218db801df06bc3703 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=E7=99=BD=E8=8C=B6=E6=B8=85=E6=AC=A2?= Date: Fri, 28 Feb 2025 12:26:09 +0800 Subject: [PATCH] =?UTF-8?q?=E8=A7=84=E5=88=92=E4=BA=8C=E6=AC=A1=E5=8C=85?= =?UTF-8?q?=E8=A3=85=E7=9A=84ginContext?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- go.mod | 1 + go.sum | 2 + request/context.go | 194 +++++++++++++++++++++++++++++++++++++++++++++ 3 files changed, 197 insertions(+) create mode 100644 request/context.go diff --git a/go.mod b/go.mod index 8239136..98e1df7 100644 --- a/go.mod +++ b/go.mod @@ -23,6 +23,7 @@ require ( git.zhangdeman.cn/zhangdeman/easylock v0.0.0-20230731062340-983985c12eda // indirect git.zhangdeman.cn/zhangdeman/easymap v0.0.0-20241101082529-28a6c68e38a4 // indirect git.zhangdeman.cn/zhangdeman/op_type v0.0.0-20240122104027-4928421213c0 // indirect + git.zhangdeman.cn/zhangdeman/trace v0.0.0-20231220041950-807f3d74a6fa // indirect git.zhangdeman.cn/zhangdeman/util v0.0.0-20240618042405-6ee2c904644e // indirect git.zhangdeman.cn/zhangdeman/websocket v0.0.0-20241125101541-c5ea194c9c1e // indirect github.com/BurntSushi/toml v1.4.0 // indirect diff --git a/go.sum b/go.sum index 5e9a12e..4ac3b83 100644 --- a/go.sum +++ b/go.sum @@ -24,6 +24,8 @@ git.zhangdeman.cn/zhangdeman/op_type v0.0.0-20240122104027-4928421213c0 h1:gUDlQ git.zhangdeman.cn/zhangdeman/op_type v0.0.0-20240122104027-4928421213c0/go.mod h1:VHb9qmhaPDAQDcS6vUiDCamYjZ4R5lD1XtVsh55KsMI= git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20241223084948-de2e49144fcd h1:q7GG14qgXKB4MEXQFOe7/UYebsqMfPaSX80TcPdOosI= git.zhangdeman.cn/zhangdeman/serialize v0.0.0-20241223084948-de2e49144fcd/go.mod h1:+D6uPSljwHywjVY5WSBY4TRVMj26TN5f5cFGEYMldjs= +git.zhangdeman.cn/zhangdeman/trace v0.0.0-20231220041950-807f3d74a6fa h1:2bZ9VmQF0pIZ+scnN3UuGoXjjKhccnwfIL779QGZArY= +git.zhangdeman.cn/zhangdeman/trace v0.0.0-20231220041950-807f3d74a6fa/go.mod h1:Bta0kzamTWqBIcc6robGAl/iRuyCFbzy45VGbG8L+7Y= git.zhangdeman.cn/zhangdeman/util v0.0.0-20240618042405-6ee2c904644e h1:Q973S6CcWr1ICZhFI1STFOJ+KUImCl2BaIXm6YppBqI= git.zhangdeman.cn/zhangdeman/util v0.0.0-20240618042405-6ee2c904644e/go.mod h1:VpPjBlwz8U+OxZuxzHQBv1aEEZ3pStH6bZvT21ADEbI= git.zhangdeman.cn/zhangdeman/websocket v0.0.0-20241125101541-c5ea194c9c1e h1:YE2Gi+M03UDImIpWa3I7jzSesyfu2RL8x/4ONs5v0oE= diff --git a/request/context.go b/request/context.go new file mode 100644 index 0000000..559b7e3 --- /dev/null +++ b/request/context.go @@ -0,0 +1,194 @@ +// Package request ... +// +// Description : request ... +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 2025-02-28 11:45 +package request + +import ( + "fmt" + networkUtil "git.zhangdeman.cn/zhangdeman/network/util" + "git.zhangdeman.cn/zhangdeman/wrapper" + "github.com/gin-gonic/gin" + "git.zhangdeman.cn/zhangdeman/trace" + "os" + "strings" + "sync" + "time" +) + +// getTraceID 生成traceID +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 23:12 2022/6/25 +func getTraceID(ctx *gin.Context) string { + hostname, _ := os.Hostname() + if hostname != "" { + hostname = "unknown" + } + return fmt.Sprintf( + "%v-%v-%v-%v-%v", + time.Now().UnixNano()/1e6, + strings.ReplaceAll(networkUtil.IP.GetHostIP(), ".", ""), + strings.ReplaceAll(hostname, ".", ""), + strings.ReplaceAll(networkUtil.IP.GetRemoteIP(ctx.Request), ".", ""), + wrapper.StringFromRandom(32, "").Md5().Value, + ) +} + +// getRequestID 生成requestID +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 23:12 2022/6/25 +func getRequestID(ctx *gin.Context, traceID string) string { + requestID := ctx.GetHeader("X-Forward-Request-Id") + if len(requestID) > 0 { + return requestID + } + if len(traceID) > 0 { + return traceID + } + return getTraceID(ctx) +} + +// NewContext 获取context实例 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 12:01 2025/2/28 +func NewContext(ginContext *gin.Context) *Context { + // 生成traceID + traceID := getRequestID(ginContext, "") + return &Context{ + Context: ginContext, + StartRequestTime: time.Now(), + FinishRequestTime: time.Time(int64(0)), + HandlerAfterResponse: make([]gin.HandlerFunc, 0), + CustomData: make(map[string]any), + lock: &sync.RWMutex{}, + TraceID: traceID, + Trace: trace.NewRuntime(traceID, 0), + } +} + +// Context 请求上下文信息, 对 ctx *gin.Context的二次包装 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 11:45 2025/2/28 +type Context struct { + *gin.Context `json:"-"` + StartRequestTime time.Time // 开始请求时间(全局) + FinishRequestTime time.Time // 结束请求时间(全局) + TraceID string `json:"trace_id"` // 请求trace_id + ParentAppName string `json:"parent_app_name"` // 父级应用名称 + HandlerAfterResponse []gin.HandlerFunc `json:"-"` // 响应数据之后需要执行的逻辑 + CustomData map[string]any // 业务上下文自定义数据, 可以合 ginCtx.Value 作区分 + lock *sync.RWMutex + Trace *trace.Runtime `json:"-"` // 追踪实例 +} + +// SetCustom 设置数据 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 11:58 2025/2/28 +func (ctx *Context) SetCustom(key string, val any) { + ctx.lock.Lock() + defer ctx.lock.Unlock() + if nil == ctx.CustomData { + ctx.CustomData = make(map[string]any) + } + ctx.CustomData[key] = val +} + +// CustomDataValue 获取customData +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 12:03 2025/2/28 +func (ctx *Context) CustomDataValue(key string) any { + ctx.lock.RLock() + defer ctx.lock.RUnlock() + if val, exist := ctx.CustomData[key]; exist { + return val + } else { + return nil + } +} + +// CustomDataExist 判断 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 12:04 2025/2/28 +func (ctx *Context) CustomDataExist(key string) any { + ctx.lock.RLock() + defer ctx.lock.RUnlock() + _, exist := ctx.CustomData[key] + return exist +} + +// CustomDataAppend 向数组数据中追加元素 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 12:07 2025/2/28 +func (ctx *Context) CustomDataAppend(key string, appendValue any) { + ctx.lock.Lock() + defer ctx.lock.Unlock() + val, exist := ctx.CustomData[key] + if !exist || nil == val { + ctx.CustomData[key] = []any{appendValue} + return + } + if valArr, ok := val.([]any); ok { + valArr = append(valArr, appendValue) + ctx.CustomData[key] = valArr + } + // 非数组, 忽略追加行为 +} + +// CustomDataAppendProperty 向一个map中追加/更新属性 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 12:11 2025/2/28 +func (ctx *Context) CustomDataAppendProperty(key string, appendKey string, appendValue any) { + ctx.lock.Lock() + defer ctx.lock.Unlock() + val, exist := ctx.CustomData[key] + if !exist || nil == val { + ctx.CustomData[key] = map[string]any{ + appendKey: appendValue, + } + return + } + if valMap, ok := val.(map[string]any); ok { + valMap[appendKey] = appendValue + ctx.CustomData[key] = valMap + } + // 非map, 忽略追加行为 +} + +// TraceStart 开始监控 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 12:24 2025/2/28 +func (ctx *Context) TraceStart(action string, actionData map[string]any) int { + return ctx.Trace.StartBehavior(action, actionData) +} + +// TraceEnd 完成监控 +// +// Author : go_developer@163.com<白茶清欢> +// +// Date : 12:24 2025/2/28 +func (ctx *Context) TraceEnd(behaviorID int, endData map[string]any) { + ctx.Trace.FinishBehavior(behaviorID, endData) +}