feat(middleware): add RouteTag middleware for enhanced logging and routing

- Introduced RouteTag middleware to set route tags for different API endpoints.
- Updated logger to include route tags in log output.
- Applied RouteTag middleware across various routers including API, dashboard, relay, video, and web routers for consistent logging.
This commit is contained in:
CaIon
2026-02-25 00:11:24 +08:00
parent b85192590b
commit 094ac54609
7 changed files with 34 additions and 2 deletions
+16 -2
View File
@@ -7,14 +7,28 @@ import (
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
) )
const RouteTagKey = "route_tag"
func RouteTag(tag string) gin.HandlerFunc {
return func(c *gin.Context) {
c.Set(RouteTagKey, tag)
c.Next()
}
}
func SetUpLogger(server *gin.Engine) { func SetUpLogger(server *gin.Engine) {
server.Use(gin.LoggerWithFormatter(func(param gin.LogFormatterParams) string { server.Use(gin.LoggerWithFormatter(func(param gin.LogFormatterParams) string {
var requestID string var requestID string
if param.Keys != nil { if param.Keys != nil {
requestID = param.Keys[common.RequestIdKey].(string) requestID, _ = param.Keys[common.RequestIdKey].(string)
} }
return fmt.Sprintf("[GIN] %s | %s | %3d | %13v | %15s | %7s %s\n", tag, _ := param.Keys[RouteTagKey].(string)
if tag == "" {
tag = "web"
}
return fmt.Sprintf("[GIN] %s | %s | %s | %3d | %13v | %15s | %7s %s\n",
param.TimeStamp.Format("2006/01/02 - 15:04:05"), param.TimeStamp.Format("2006/01/02 - 15:04:05"),
tag,
requestID, requestID,
param.StatusCode, param.StatusCode,
param.Latency, param.Latency,
+1
View File
@@ -13,6 +13,7 @@ import (
func SetApiRouter(router *gin.Engine) { func SetApiRouter(router *gin.Engine) {
apiRouter := router.Group("/api") apiRouter := router.Group("/api")
apiRouter.Use(middleware.RouteTag("api"))
apiRouter.Use(gzip.Gzip(gzip.DefaultCompression)) apiRouter.Use(gzip.Gzip(gzip.DefaultCompression))
apiRouter.Use(middleware.BodyStorageCleanup()) // 清理请求体存储 apiRouter.Use(middleware.BodyStorageCleanup()) // 清理请求体存储
apiRouter.Use(middleware.GlobalAPIRateLimit()) apiRouter.Use(middleware.GlobalAPIRateLimit())
+1
View File
@@ -9,6 +9,7 @@ import (
func SetDashboardRouter(router *gin.Engine) { func SetDashboardRouter(router *gin.Engine) {
apiRouter := router.Group("/") apiRouter := router.Group("/")
apiRouter.Use(middleware.RouteTag("old_api"))
apiRouter.Use(gzip.Gzip(gzip.DefaultCompression)) apiRouter.Use(gzip.Gzip(gzip.DefaultCompression))
apiRouter.Use(middleware.GlobalAPIRateLimit()) apiRouter.Use(middleware.GlobalAPIRateLimit())
apiRouter.Use(middleware.CORS()) apiRouter.Use(middleware.CORS())
+2
View File
@@ -8,6 +8,7 @@ import (
"strings" "strings"
"github.com/QuantumNous/new-api/common" "github.com/QuantumNous/new-api/common"
"github.com/QuantumNous/new-api/middleware"
"github.com/gin-gonic/gin" "github.com/gin-gonic/gin"
) )
@@ -27,6 +28,7 @@ func SetRouter(router *gin.Engine, buildFS embed.FS, indexPage []byte) {
} else { } else {
frontendBaseUrl = strings.TrimSuffix(frontendBaseUrl, "/") frontendBaseUrl = strings.TrimSuffix(frontendBaseUrl, "/")
router.NoRoute(func(c *gin.Context) { router.NoRoute(func(c *gin.Context) {
c.Set(middleware.RouteTagKey, "web")
c.Redirect(http.StatusMovedPermanently, fmt.Sprintf("%s%s", frontendBaseUrl, c.Request.RequestURI)) c.Redirect(http.StatusMovedPermanently, fmt.Sprintf("%s%s", frontendBaseUrl, c.Request.RequestURI))
}) })
} }
+9
View File
@@ -17,6 +17,7 @@ func SetRelayRouter(router *gin.Engine) {
router.Use(middleware.StatsMiddleware()) router.Use(middleware.StatsMiddleware())
// https://platform.openai.com/docs/api-reference/introduction // https://platform.openai.com/docs/api-reference/introduction
modelsRouter := router.Group("/v1/models") modelsRouter := router.Group("/v1/models")
modelsRouter.Use(middleware.RouteTag("relay"))
modelsRouter.Use(middleware.TokenAuth()) modelsRouter.Use(middleware.TokenAuth())
{ {
modelsRouter.GET("", func(c *gin.Context) { modelsRouter.GET("", func(c *gin.Context) {
@@ -41,6 +42,7 @@ func SetRelayRouter(router *gin.Engine) {
} }
geminiRouter := router.Group("/v1beta/models") geminiRouter := router.Group("/v1beta/models")
geminiRouter.Use(middleware.RouteTag("relay"))
geminiRouter.Use(middleware.TokenAuth()) geminiRouter.Use(middleware.TokenAuth())
{ {
geminiRouter.GET("", func(c *gin.Context) { geminiRouter.GET("", func(c *gin.Context) {
@@ -49,6 +51,7 @@ func SetRelayRouter(router *gin.Engine) {
} }
geminiCompatibleRouter := router.Group("/v1beta/openai/models") geminiCompatibleRouter := router.Group("/v1beta/openai/models")
geminiCompatibleRouter.Use(middleware.RouteTag("relay"))
geminiCompatibleRouter.Use(middleware.TokenAuth()) geminiCompatibleRouter.Use(middleware.TokenAuth())
{ {
geminiCompatibleRouter.GET("", func(c *gin.Context) { geminiCompatibleRouter.GET("", func(c *gin.Context) {
@@ -57,12 +60,14 @@ func SetRelayRouter(router *gin.Engine) {
} }
playgroundRouter := router.Group("/pg") playgroundRouter := router.Group("/pg")
playgroundRouter.Use(middleware.RouteTag("relay"))
playgroundRouter.Use(middleware.SystemPerformanceCheck()) playgroundRouter.Use(middleware.SystemPerformanceCheck())
playgroundRouter.Use(middleware.UserAuth(), middleware.Distribute()) playgroundRouter.Use(middleware.UserAuth(), middleware.Distribute())
{ {
playgroundRouter.POST("/chat/completions", controller.Playground) playgroundRouter.POST("/chat/completions", controller.Playground)
} }
relayV1Router := router.Group("/v1") relayV1Router := router.Group("/v1")
relayV1Router.Use(middleware.RouteTag("relay"))
relayV1Router.Use(middleware.SystemPerformanceCheck()) relayV1Router.Use(middleware.SystemPerformanceCheck())
relayV1Router.Use(middleware.TokenAuth()) relayV1Router.Use(middleware.TokenAuth())
relayV1Router.Use(middleware.ModelRequestRateLimit()) relayV1Router.Use(middleware.ModelRequestRateLimit())
@@ -161,15 +166,18 @@ func SetRelayRouter(router *gin.Engine) {
} }
relayMjRouter := router.Group("/mj") relayMjRouter := router.Group("/mj")
relayMjRouter.Use(middleware.RouteTag("relay"))
relayMjRouter.Use(middleware.SystemPerformanceCheck()) relayMjRouter.Use(middleware.SystemPerformanceCheck())
registerMjRouterGroup(relayMjRouter) registerMjRouterGroup(relayMjRouter)
relayMjModeRouter := router.Group("/:mode/mj") relayMjModeRouter := router.Group("/:mode/mj")
relayMjModeRouter.Use(middleware.RouteTag("relay"))
relayMjModeRouter.Use(middleware.SystemPerformanceCheck()) relayMjModeRouter.Use(middleware.SystemPerformanceCheck())
registerMjRouterGroup(relayMjModeRouter) registerMjRouterGroup(relayMjModeRouter)
//relayMjRouter.Use() //relayMjRouter.Use()
relaySunoRouter := router.Group("/suno") relaySunoRouter := router.Group("/suno")
relaySunoRouter.Use(middleware.RouteTag("relay"))
relaySunoRouter.Use(middleware.SystemPerformanceCheck()) relaySunoRouter.Use(middleware.SystemPerformanceCheck())
relaySunoRouter.Use(middleware.TokenAuth(), middleware.Distribute()) relaySunoRouter.Use(middleware.TokenAuth(), middleware.Distribute())
{ {
@@ -179,6 +187,7 @@ func SetRelayRouter(router *gin.Engine) {
} }
relayGeminiRouter := router.Group("/v1beta") relayGeminiRouter := router.Group("/v1beta")
relayGeminiRouter.Use(middleware.RouteTag("relay"))
relayGeminiRouter.Use(middleware.SystemPerformanceCheck()) relayGeminiRouter.Use(middleware.SystemPerformanceCheck())
relayGeminiRouter.Use(middleware.TokenAuth()) relayGeminiRouter.Use(middleware.TokenAuth())
relayGeminiRouter.Use(middleware.ModelRequestRateLimit()) relayGeminiRouter.Use(middleware.ModelRequestRateLimit())
+4
View File
@@ -10,12 +10,14 @@ import (
func SetVideoRouter(router *gin.Engine) { func SetVideoRouter(router *gin.Engine) {
// Video proxy: accepts either session auth (dashboard) or token auth (API clients) // Video proxy: accepts either session auth (dashboard) or token auth (API clients)
videoProxyRouter := router.Group("/v1") videoProxyRouter := router.Group("/v1")
videoProxyRouter.Use(middleware.RouteTag("relay"))
videoProxyRouter.Use(middleware.TokenOrUserAuth()) videoProxyRouter.Use(middleware.TokenOrUserAuth())
{ {
videoProxyRouter.GET("/videos/:task_id/content", controller.VideoProxy) videoProxyRouter.GET("/videos/:task_id/content", controller.VideoProxy)
} }
videoV1Router := router.Group("/v1") videoV1Router := router.Group("/v1")
videoV1Router.Use(middleware.RouteTag("relay"))
videoV1Router.Use(middleware.TokenAuth(), middleware.Distribute()) videoV1Router.Use(middleware.TokenAuth(), middleware.Distribute())
{ {
videoV1Router.POST("/video/generations", controller.RelayTask) videoV1Router.POST("/video/generations", controller.RelayTask)
@@ -30,6 +32,7 @@ func SetVideoRouter(router *gin.Engine) {
} }
klingV1Router := router.Group("/kling/v1") klingV1Router := router.Group("/kling/v1")
klingV1Router.Use(middleware.RouteTag("relay"))
klingV1Router.Use(middleware.KlingRequestConvert(), middleware.TokenAuth(), middleware.Distribute()) klingV1Router.Use(middleware.KlingRequestConvert(), middleware.TokenAuth(), middleware.Distribute())
{ {
klingV1Router.POST("/videos/text2video", controller.RelayTask) klingV1Router.POST("/videos/text2video", controller.RelayTask)
@@ -40,6 +43,7 @@ func SetVideoRouter(router *gin.Engine) {
// Jimeng official API routes - direct mapping to official API format // Jimeng official API routes - direct mapping to official API format
jimengOfficialGroup := router.Group("jimeng") jimengOfficialGroup := router.Group("jimeng")
jimengOfficialGroup.Use(middleware.RouteTag("relay"))
jimengOfficialGroup.Use(middleware.JimengRequestConvert(), middleware.TokenAuth(), middleware.Distribute()) jimengOfficialGroup.Use(middleware.JimengRequestConvert(), middleware.TokenAuth(), middleware.Distribute())
{ {
// Maps to: /?Action=CVSync2AsyncSubmitTask&Version=2022-08-31 and /?Action=CVSync2AsyncGetResult&Version=2022-08-31 // Maps to: /?Action=CVSync2AsyncSubmitTask&Version=2022-08-31 and /?Action=CVSync2AsyncGetResult&Version=2022-08-31
+1
View File
@@ -19,6 +19,7 @@ func SetWebRouter(router *gin.Engine, buildFS embed.FS, indexPage []byte) {
router.Use(middleware.Cache()) router.Use(middleware.Cache())
router.Use(static.Serve("/", common.EmbedFolder(buildFS, "web/dist"))) router.Use(static.Serve("/", common.EmbedFolder(buildFS, "web/dist")))
router.NoRoute(func(c *gin.Context) { router.NoRoute(func(c *gin.Context) {
c.Set(middleware.RouteTagKey, "web")
if strings.HasPrefix(c.Request.RequestURI, "/v1") || strings.HasPrefix(c.Request.RequestURI, "/api") || strings.HasPrefix(c.Request.RequestURI, "/assets") { if strings.HasPrefix(c.Request.RequestURI, "/v1") || strings.HasPrefix(c.Request.RequestURI, "/api") || strings.HasPrefix(c.Request.RequestURI, "/assets") {
controller.RelayNotFound(c) controller.RelayNotFound(c)
return return