diff --git a/api.go b/api.go index bc6acb3..9a2f41e 100644 --- a/api.go +++ b/api.go @@ -1,6 +1,7 @@ package api import ( + "fmt" "reflect" "github.com/gin-gonic/gin" @@ -12,7 +13,7 @@ import ( var ( validate = validator.New() requestLogidGetter = defaultLogidGetter - requestHandlerMapper = map[string]Handler{} + requestHandlerMapper = map[string]gin.HandlerFunc{} errCodeUnknownError = -10000 errCodeParameterError = -20000 errCodeUnimplementApi = -20401 @@ -56,7 +57,7 @@ func (e *Engine) POST(uri string, handler Handler) { // handlerWrapper func handlerWrapper(handler Handler) gin.HandlerFunc { handlerFunc := handler.HandlerFunc() - return func(c *gin.Context) { + wrappedHandlerFunc := func(c *gin.Context) { // Case 1. get request handler if c.Request == nil && c.Keys != nil { c.Keys["handler"] = handler @@ -78,6 +79,9 @@ func handlerWrapper(handler Handler) gin.HandlerFunc { return } } + hkey := fmt.Sprintf("%v", wrappedHandlerFunc) + requestHandlerMapper[hkey] = wrappedHandlerFunc + return wrappedHandlerFunc } // handlerWrapper @@ -114,6 +118,9 @@ func middlewareMyApiEngine() gin.HandlerFunc { // Step 3. do request c.Next() + + // Step 4. recorde metrics + cc.recordMetrics() } } @@ -141,8 +148,17 @@ func CC(c *gin.Context) *Context { } func ApiHandler(c *gin.Context) Handler { - newc := &gin.Context{Request: nil, Keys: map[string]any{}} - c.Handler()(newc) + h := c.Handler() + hkey := fmt.Sprintf("%v", h) + if _, ok := requestHandlerMapper[hkey]; !ok { + return nil + } + + newc := &gin.Context{ + Request: nil, + Keys: map[string]any{}, + } + h(newc) return newc.Keys["handler"].(Handler) } @@ -157,7 +173,7 @@ func RecordMetrics(api, errcode, appid string, costms float64) { summary.Observe(costms) } -func DumpHandler(c *Context) error { +func DumpHandlerFunc(c *Context) error { errmsg := "api not implemented" errcode := errCodeUnimplementApi return c.RESULT_ERROR(errcode, errmsg) diff --git a/context.go b/context.go index adb5e65..0959b9f 100644 --- a/context.go +++ b/context.go @@ -150,8 +150,6 @@ func (c *Context) RESULT(output interface{}) error { noticeStr := fmt.Sprintf("cost: %dms, output: '%s'", cost, string(b)) log.NoticefWithDepth(calldepth, noticeStr) - //////// metrics ////////////////////////////////// - c.recordMetrics() }(&output) if _, ok := t.FieldByName("ErrCode"); !ok { @@ -220,8 +218,11 @@ func (c *Context) recordMetrics() { metricApiSummary == nil { return } + var h = c.ApiHandler() + if h == nil { + h = unimplementHandler{c.Context} + } var ( - h = c.ApiHandler() api = h.ApiName() appid = c.AppId costus = time.Now().Sub(c.starttime).Microseconds() diff --git a/routes.go b/routes.go index 90eb6fa..fe48b6d 100644 --- a/routes.go +++ b/routes.go @@ -1,5 +1,12 @@ package api +import ( + "fmt" + "strings" + + "github.com/gin-gonic/gin" +) + // /////////////////////////////////////////////////////////////////// // IRouter & IRoutes in gin, we redefine it simple // /////////////////////////////////////////////////////////////////// @@ -42,3 +49,16 @@ type HandlerFunc func(*Context) error type IRoutes interface { POST(uri string, handler Handler) } + +type unimplementHandler struct { + c *gin.Context +} + +func (u unimplementHandler) ApiName() string { + req := u.c.Request + return strings.ToLower(fmt.Sprintf("[%s]%s", req.Method, req.RequestURI)) +} + +func (u unimplementHandler) HandlerFunc() HandlerFunc { + return DumpHandlerFunc +}