diff --git a/go.mod b/go.mod index 40318bb..e16bb30 100644 --- a/go.mod +++ b/go.mod @@ -7,7 +7,6 @@ require ( github.com/gin-gonic/gin v1.10.1 github.com/google/uuid v1.6.0 github.com/jedib0t/go-pretty/v6 v6.6.7 - github.com/loveuer/nf v0.3.5 golang.org/x/crypto v0.25.0 ) diff --git a/go.sum b/go.sum index 9a124e5..8ee6ceb 100644 --- a/go.sum +++ b/go.sum @@ -42,8 +42,6 @@ github.com/klauspost/cpuid/v2 v2.2.7/go.mod h1:Lcz8mBdAVJIBVzewtcLocK12l3Y+JytZY github.com/knz/go-libedit v1.10.1/go.mod h1:MZTVkCWyz0oBc7JOWP3wNAzd002ZbM/5hgShxwh4x8M= github.com/leodido/go-urn v1.4.0 h1:WT9HwE9SGECu3lg4d/dIA+jxlljEa1/ffXKmRjqdmIQ= github.com/leodido/go-urn v1.4.0/go.mod h1:bvxc+MVxLKB4z00jd1z+Dvzr47oO32F/QSNjSBOlFxI= -github.com/loveuer/nf v0.3.5 h1:DlgTa6Rx8D3/VtH9e0fLGAxmPwSYd7b3nfBltSMuypE= -github.com/loveuer/nf v0.3.5/go.mod h1:IAq0K1c/mlNQzLBvUzAD1LCWiVlt2GqTMPdDjej3Ryo= github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= diff --git a/middlewares/logger/logger.go b/middlewares/logger/logger.go new file mode 100644 index 0000000..b5ccb54 --- /dev/null +++ b/middlewares/logger/logger.go @@ -0,0 +1,74 @@ +package logger + +import ( + "fmt" + "gitea.loveuer.com/yizhisec/packages/logger" + "gitea.loveuer.com/yizhisec/packages/opt" + "gitea.loveuer.com/yizhisec/packages/tool" + "github.com/gin-gonic/gin" + "strings" + "sync" + "time" +) + +var ( + defaultTrace = "middleware-logger" + stringBuilderPool = sync.Pool{ + New: func() interface{} { + return &strings.Builder{} + }, + } +) + +func New() gin.HandlerFunc { + return func(c *gin.Context) { + start := time.Now() + ip := c.RemoteIP() + + trace := c.Request.Header.Get(opt.TraceKey) + if trace == "" { + if v, ok := c.Request.Context().Value(opt.TraceKey).(string); ok && v != "" { + trace = v + } else { + trace = defaultTrace + } + } + + c.Next() + + status := c.Writer.Status() + duration := time.Since(start) + + var logFn func(msg string, data ...any) + switch { + case status >= 500: + logFn = logger.Error + case status >= 400: + logFn = logger.Warn + default: + logFn = logger.Info + } + + if logFn != nil { + b := stringBuilderPool.Get().(*strings.Builder) + b.Reset() + + b.WriteString("[") + b.WriteString(fmt.Sprintf("%36s", trace)) + b.WriteString("] | ") + b.WriteString(fmt.Sprintf("%3d", status)) + b.WriteString(" | ") + b.WriteString(fmt.Sprintf("%15s", ip)) + b.WriteString(" | ") + b.WriteString(tool.HumanDuration(duration.Nanoseconds())) + b.WriteString(" | ") + b.WriteString(c.Request.Method) + b.WriteString(" | ") + b.WriteString(c.Request.RequestURI) + + logFn(b.String()) + + stringBuilderPool.Put(b) + } + } +} diff --git a/middlewares/logger/logger_test.go b/middlewares/logger/logger_test.go new file mode 100644 index 0000000..0acb887 --- /dev/null +++ b/middlewares/logger/logger_test.go @@ -0,0 +1,59 @@ +package logger + +import ( + "errors" + "github.com/gin-gonic/gin" + "net/http" + "testing" + "time" +) + +func TestLogger(t *testing.T) { + gin.SetMode(gin.TestMode) + app := gin.New() + app.Use(New()) + + app.GET("/200", func(c *gin.Context) { + c.JSON(200, gin.H{"hello": "world"}) + }) + app.GET("/400", func(c *gin.Context) { + c.JSON(400, gin.H{"hello": "world"}) + }) + app.GET("/500", func(c *gin.Context) { + c.JSON(500, gin.H{"hello": "world"}) + }) + + ok := make(chan struct{}) + svc := http.Server{ + Handler: app, + Addr: "127.0.0.1:8080", + } + go func() { + ok <- struct{}{} + if err := svc.ListenAndServe(); err != nil && !errors.Is(err, http.ErrServerClosed) { + t.Error(err) + } + }() + + <-ok + time.Sleep(200 * time.Millisecond) + + justErr := func(_ any, e error) error { + return e + } + + err := errors.Join( + justErr(http.Get("http://127.0.0.1:8080/200")), + justErr(http.Get("http://127.0.0.1:8080/400")), + justErr(http.Get("http://127.0.0.1:8080/500")), + ) + + if err != nil { + t.Error(err) + } + + err = svc.Shutdown(t.Context()) + if err != nil { + t.Error(err) + } +} diff --git a/tool/must.go b/tool/must.go index 0615f8d..3b70062 100644 --- a/tool/must.go +++ b/tool/must.go @@ -1,11 +1,13 @@ package tool -import "github.com/loveuer/nf/nft/log" +import ( + "gitea.loveuer.com/yizhisec/packages/logger" +) func Must(errs ...error) { for _, err := range errs { if err != nil { - log.Panic(err.Error()) + logger.Panic(err.Error()) } } }