🆕 add expvar middleware

It's wrapper of fasthttp/expvarhandler
pull/841/head
kiyon 2020-09-28 12:59:49 +08:00
parent e6fc09bf2c
commit 6e40c15149
3 changed files with 170 additions and 0 deletions

View File

@ -0,0 +1,61 @@
# Expvar
Expvar middleware for [Fiber](https://github.com/gofiber/fiber) that serves via its HTTP server runtime profiling data in the format expected by the expvar visualization tool. The package is typically only imported for the side effect of registering its HTTP handlers. The handled paths all begin with /debug/expvar/.
- [Signatures](#signatures)
- [Examples](#example)
### Signatures
```go
func New() fiber.Handler
```
### Example
Import the expvar package that is part of the Fiber web framework
```go
package main
import (
"expvar"
"fmt"
"github.com/gofiber/fiber/v2"
expvarmw "github.com/gofiber/fiber/v2/middleware/expvar"
)
var count = expvar.NewInt("count")
func main() {
app := fiber.New()
app.Use(expvarmw.New())
app.Get("/", func(c *fiber.Ctx) error {
count.Add(1)
return c.SendString(fmt.Sprintf("hello expvar count %d", count.Value()))
})
fmt.Println(app.Listen(":3000"))
}
```
Visit path `/debug/vars` to see all vars and use query `r=key` to filter exposed variables.
```bash
curl 127.0.0.1:3000
hello expvar count 1
curl 127.0.0.1:3000/debug/vars
{
"cmdline": ["xxx"],
"count": 1,
"expvarHandlerCalls": 33,
"expvarRegexpErrors": 0,
"memstats": {...}
}
curl 127.0.0.1:3000/debug/vars?r=c
{
"cmdline": ["xxx"],
"count": 1
}
```

View File

@ -0,0 +1,26 @@
package expvar
import (
"strings"
"github.com/gofiber/fiber/v2"
"github.com/valyala/fasthttp/expvarhandler"
)
// New creates a new middleware handler
func New() fiber.Handler {
// Return new handler
return func(c *fiber.Ctx) error {
path := c.Path()
// We are only interested in /debug/vars routes
if len(path) < 11 || !strings.HasPrefix(path, "/debug/vars") {
return c.Next()
}
if path == "/debug/vars" {
expvarhandler.ExpvarHandler(c.Context())
return nil
}
return c.Redirect("/debug/vars", 302)
}
}

View File

@ -0,0 +1,83 @@
package expvar
import (
"bytes"
"io/ioutil"
"net/http/httptest"
"testing"
"github.com/gofiber/fiber/v2"
"github.com/gofiber/fiber/v2/utils"
)
func Test_Non_Expvar_Path(t *testing.T) {
app := fiber.New()
app.Use(New())
app.Get("/", func(c *fiber.Ctx) error {
return c.SendString("escaped")
})
resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/", nil))
utils.AssertEqual(t, nil, err)
utils.AssertEqual(t, 200, resp.StatusCode)
b, err := ioutil.ReadAll(resp.Body)
utils.AssertEqual(t, nil, err)
utils.AssertEqual(t, "escaped", string(b))
}
func Test_Expvar_Index(t *testing.T) {
app := fiber.New()
app.Use(New())
app.Get("/", func(c *fiber.Ctx) error {
return c.SendString("escaped")
})
resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/debug/vars", nil))
utils.AssertEqual(t, nil, err)
utils.AssertEqual(t, 200, resp.StatusCode)
utils.AssertEqual(t, fiber.MIMEApplicationJSONCharsetUTF8, resp.Header.Get(fiber.HeaderContentType))
b, err := ioutil.ReadAll(resp.Body)
utils.AssertEqual(t, nil, err)
utils.AssertEqual(t, true, bytes.Contains(b, []byte("cmdline")))
utils.AssertEqual(t, true, bytes.Contains(b, []byte("memstat")))
}
func Test_Expvar_Filter(t *testing.T) {
app := fiber.New()
app.Use(New())
app.Get("/", func(c *fiber.Ctx) error {
return c.SendString("escaped")
})
resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/debug/vars?r=cmd", nil))
utils.AssertEqual(t, nil, err)
utils.AssertEqual(t, 200, resp.StatusCode)
utils.AssertEqual(t, fiber.MIMEApplicationJSONCharsetUTF8, resp.Header.Get(fiber.HeaderContentType))
b, err := ioutil.ReadAll(resp.Body)
utils.AssertEqual(t, nil, err)
utils.AssertEqual(t, true, bytes.Contains(b, []byte("cmdline")))
utils.AssertEqual(t, false, bytes.Contains(b, []byte("memstat")))
}
func Test_Expvar_Other_Path(t *testing.T) {
app := fiber.New()
app.Use(New())
app.Get("/", func(c *fiber.Ctx) error {
return c.SendString("escaped")
})
resp, err := app.Test(httptest.NewRequest(fiber.MethodGet, "/debug/vars/302", nil))
utils.AssertEqual(t, nil, err)
utils.AssertEqual(t, 302, resp.StatusCode)
}