From 1176426eba4a7e16cda230bfb02ae0394247082d Mon Sep 17 00:00:00 2001 From: askuy Date: Fri, 18 Jul 2025 16:58:35 +0800 Subject: [PATCH] x-header expose v2 --- server/egin/config.go | 4 ++- server/egin/container.go | 2 +- server/egin/interceptor_cost.go | 44 ++++++++++++++++++++------------- 3 files changed, 31 insertions(+), 19 deletions(-) diff --git a/server/egin/config.go b/server/egin/config.go index d62be81..7fa8789 100644 --- a/server/egin/config.go +++ b/server/egin/config.go @@ -31,6 +31,7 @@ type Config struct { EnableTraceInterceptor bool // 是否开启链路追踪,默认开启 EnableLocalMainIP bool // 自动获取ip地址 EnableResHeaderApp bool // header展示APP Name + EnableResHeaderError bool // 是否开启错误响应头,默认不开启 SlowLogThreshold time.Duration // 服务慢日志,默认500ms EnableAccessInterceptor bool // 是否开启,记录请求数据 EnableAccessInterceptorReq bool // 是否开启记录请求参数,默认不开启 @@ -76,7 +77,8 @@ func DefaultConfig() *Config { EnableAccessInterceptor: true, EnableTraceInterceptor: true, EnableMetricInterceptor: true, - EnableResHeaderApp: true, + EnableResHeaderApp: false, + EnableResHeaderError: false, AccessInterceptorReqMaxLength: 4096, AccessInterceptorResMaxLength: 4096, EnableSentinel: true, diff --git a/server/egin/container.go b/server/egin/container.go index b43b9ad..3fe3728 100644 --- a/server/egin/container.go +++ b/server/egin/container.go @@ -104,7 +104,7 @@ func (c *Container) Build(options ...Option) *Component { server := newComponent(c.name, c.config, c.logger) server.Use(healthcheck.Default()) server.Use(c.defaultServerInterceptor()) - server.Use(NewXResCostTimer(c.config.EnableResHeaderApp)) + server.Use(NewXResCostTimer(c.name, c.config.EnableResHeaderApp)) if c.config.ContextTimeout > 0 { server.Use(timeoutMiddleware(c.config.ContextTimeout)) } diff --git a/server/egin/interceptor_cost.go b/server/egin/interceptor_cost.go index 63fd85c..b130e3d 100644 --- a/server/egin/interceptor_cost.go +++ b/server/egin/interceptor_cost.go @@ -7,27 +7,47 @@ import ( "github.com/gin-gonic/gin" "github.com/gotomicro/ego/core/eapp" + "github.com/gotomicro/ego/core/econf" "github.com/gotomicro/ego/core/transport" "github.com/spf13/cast" ) -// XResCostTimer wrap gin reponse writer add start time +// XResCostTimer wrap gin response writer add start time type XResCostTimer struct { gin.ResponseWriter start time.Time ginCtx *gin.Context enableHeaderApp bool + prefixKey string } -// 如果写入header,需要这么处理 -// ctx.Request = ctx.Request.WithContext(sdkCtx.Context) +// WriteHeader 如果写入header,需要这么处理 +// ctx.Request = ctx.Request.WithContext(context) func (w *XResCostTimer) WriteHeader(statusCode int) { // header必须在c.json响应。 cost := float64(time.Since(w.start).Microseconds()) / 1000 if w.enableHeaderApp { - w.Header().Set(eapp.EgoHeaderExpose()+"time", strconv.FormatFloat(cost, 'f', -1, 64)+"|"+eapp.Name()) + errStr := w.ginCtx.Errors.ByType(gin.ErrorTypePrivate).String() + if errStr != "" { + if econf.GetBool(w.prefixKey + ".enableResHeaderError") { + w.Header().Set(eapp.EgoHeaderExpose()+"time", strconv.FormatFloat(cost, 'f', -1, 64)+"|"+errStr+"|"+eapp.Name()) + } else { + w.Header().Set(eapp.EgoHeaderExpose()+"time", strconv.FormatFloat(cost, 'f', -1, 64)+"|err|"+eapp.Name()) + } + } else { + w.Header().Set(eapp.EgoHeaderExpose()+"time", strconv.FormatFloat(cost, 'f', -1, 64)+"|ok|"+eapp.Name()) + } } else { - w.Header().Set(eapp.EgoHeaderExpose()+"time", strconv.FormatFloat(cost, 'f', -1, 64)) + errStr := w.ginCtx.Errors.ByType(gin.ErrorTypePrivate).String() + if errStr != "" { + if econf.GetBool(w.prefixKey + ".enableResHeaderError") { + w.Header().Set(eapp.EgoHeaderExpose()+"time", strconv.FormatFloat(cost, 'f', -1, 64)+"|"+errStr) + } else { + w.Header().Set(eapp.EgoHeaderExpose()+"time", strconv.FormatFloat(cost, 'f', -1, 64)+"|err") + } + } else { + w.Header().Set(eapp.EgoHeaderExpose()+"time", strconv.FormatFloat(cost, 'f', -1, 64)+"|ok") + } } for _, key := range transport.CustomHeaderKeys() { if value := cast.ToString(w.ginCtx.Request.Context().Value(key)); value != "" { @@ -46,24 +66,14 @@ func (w *XResCostTimer) Write(b []byte) (int, error) { } // NewXResCostTimer middleware to add X-Res-Cost-Time -//func NewXResCostTimer(c *gin.Context) { -// blw := &XResCostTimer{ -// ResponseWriter: c.Writer, -// start: time.Now(), -// ginCtx: c, -// } -// c.Writer = blw -// c.Next() -//} - -// NewXResCostTimer middleware to add X-Res-Cost-Time -func NewXResCostTimer(enableHeaderApp bool) gin.HandlerFunc { +func NewXResCostTimer(prefixKey string, enableHeaderApp bool) gin.HandlerFunc { return func(c *gin.Context) { blw := &XResCostTimer{ ResponseWriter: c.Writer, start: time.Now(), ginCtx: c, enableHeaderApp: enableHeaderApp, + prefixKey: prefixKey, } c.Writer = blw c.Next()