From 7057e232e68128560845fab3d488b6bfc2934aa2 Mon Sep 17 00:00:00 2001 From: loveuer Date: Sun, 14 Jan 2024 19:10:05 +0800 Subject: [PATCH] feat: api stdout logger --- ctx.go | 29 ++++++++++++++----------- middleware.go | 52 +++++++++++++++++++++++++++++++++++++++++++++ nf.go | 4 ++++ xtest/basic/main.go | 6 ++++++ 4 files changed, 79 insertions(+), 12 deletions(-) diff --git a/ctx.go b/ctx.go index 2d3a666..b1f3f17 100644 --- a/ctx.go +++ b/ctx.go @@ -14,7 +14,7 @@ import ( type Ctx struct { // origin objects - Writer http.ResponseWriter + writer http.ResponseWriter Request *http.Request // request info path string @@ -31,10 +31,11 @@ type Ctx struct { func newContext(app *App, writer http.ResponseWriter, request *http.Request) *Ctx { return &Ctx{ - Writer: writer, - Request: request, - path: request.URL.Path, - Method: request.Method, + writer: writer, + Request: request, + path: request.URL.Path, + Method: request.Method, + StatusCode: 200, app: app, index: -1, @@ -182,16 +183,16 @@ func (c *Ctx) QueryParser(out interface{}) error { func (c *Ctx) Status(code int) *Ctx { c.StatusCode = code - c.Writer.WriteHeader(code) + c.writer.WriteHeader(code) return c } func (c *Ctx) Set(key string, value string) { - c.Writer.Header().Set(key, value) + c.writer.Header().Set(key, value) } func (c *Ctx) SetHeader(key string, value string) { - c.Writer.Header().Set(key, value) + c.writer.Header().Set(key, value) } func (c *Ctx) SendString(data string) error { @@ -202,13 +203,13 @@ func (c *Ctx) SendString(data string) error { func (c *Ctx) Writef(format string, values ...interface{}) (int, error) { c.SetHeader("Content-Type", "text/plain") - return c.Writer.Write([]byte(fmt.Sprintf(format, values...))) + return c.writer.Write([]byte(fmt.Sprintf(format, values...))) } func (c *Ctx) JSON(data interface{}) error { c.SetHeader("Content-Type", "application/json") - encoder := json.NewEncoder(c.Writer) + encoder := json.NewEncoder(c.writer) if err := encoder.Encode(data); err != nil { return err @@ -217,12 +218,16 @@ func (c *Ctx) JSON(data interface{}) error { return nil } +func (c *Ctx) RawWriter() http.ResponseWriter { + return c.writer +} + func (c *Ctx) Write(data []byte) (int, error) { - return c.Writer.Write(data) + return c.writer.Write(data) } func (c *Ctx) HTML(html string) error { c.SetHeader("Content-Type", "text/html") - _, err := c.Writer.Write([]byte(html)) + _, err := c.writer.Write([]byte(html)) return err } diff --git a/middleware.go b/middleware.go index b4d14f2..2fa4059 100644 --- a/middleware.go +++ b/middleware.go @@ -2,8 +2,10 @@ package nf import ( "fmt" + "log" "os" "runtime/debug" + "time" ) func NewRecover(enableStackTrace bool) HandlerFunc { @@ -21,3 +23,53 @@ func NewRecover(enableStackTrace bool) HandlerFunc { return c.Next() } } + +func NewLogger() HandlerFunc { + l := log.New(os.Stdout, "[NF] ", 0) + + durationFormat := func(num int64) string { + var ( + unit = "ns" + ) + + if num > 1000 { + num = num / 1000 + unit = "µs" + } + + if num > 1000 { + num = num / 1000 + unit = "ms" + } + + if num > 1000 { + num = num / 1000 + unit = " s" + } + + return fmt.Sprintf("%v %s", num, unit) + } + + return func(c *Ctx) error { + start := time.Now() + + err := c.Next() + + var ( + duration = time.Now().Sub(start).Nanoseconds() + status = c.StatusCode + path = c.path + method = c.Request.Method + ) + + l.Printf("%s | %5s | %d | %s | %s", + start.Format("06/01/02T15:04:05"), + method, + status, + durationFormat(duration), + path, + ) + + return err + } +} diff --git a/nf.go b/nf.go index 0a114fa..f489cc6 100644 --- a/nf.go +++ b/nf.go @@ -42,6 +42,10 @@ func New(config ...Config) *App { app.RouterGroup = &RouterGroup{app: app} app.groups = []*RouterGroup{app.RouterGroup} + if !app.config.DisableLogger { + app.Use(NewLogger()) + } + if !app.config.DisableRecover { app.Use(NewRecover(true)) } diff --git a/xtest/basic/main.go b/xtest/basic/main.go index a7d2b58..252d6f5 100644 --- a/xtest/basic/main.go +++ b/xtest/basic/main.go @@ -4,6 +4,7 @@ import ( "github.com/loveuer/nf" "log" "net" + "time" ) func main() { @@ -13,6 +14,11 @@ func main() { name := c.Param("name") return c.JSON(nf.Map{"status": 200, "data": "hello, " + name}) }) + app.Patch("/world", func(c *nf.Ctx) error { + time.Sleep(5 * time.Second) + c.Status(404) + return c.JSON(nf.Map{"method": c.Method, "status": c.StatusCode}) + }) ln, _ := net.Listen("tcp", ":80") log.Fatal(app.RunListener(ln))