Skip to content

Commit 0b9edc8

Browse files
committed
Refactor for v2
Signed-off-by: Xabier Larrakoetxea <[email protected]>
1 parent ee4c4b8 commit 0b9edc8

33 files changed

+651
-388
lines changed

CHANGELOG.md

+15-1
Original file line numberDiff line numberDiff line change
@@ -2,9 +2,23 @@
22

33
## [Unreleased]
44

5+
Breaking change. The library has been refactored to me more flexible when adding new framework/libraries.
6+
57
### Added
68

7-
- New middleware helper for the Echo framework
9+
- New middleware helper for the Echo framework.
10+
11+
### Changed
12+
13+
- Refactored internally how the Middleware works and gets the data to make it easier to extend and more reliable.
14+
- Added `Reporter` interface as the service responsible of getting the data to be measured.
15+
- All different framwork helpers now implement with the new Reporter way.
16+
- Fixed Gin returning duplicated data (#31).
17+
- Standard handler now is on `middleware/std` instead of `middleware`.
18+
19+
### Removed
20+
21+
- Middleware interface in favor of a struct.
822

923
## [0.6.1] - 2020-02-07
1024

doc.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ the main Go net/http handler:
1111
"github.com/prometheus/client_golang/prometheus/promhttp"
1212
httpmetrics "github.com/slok/go-http-metrics/metrics/prometheus"
1313
httpmiddleware "github.com/slok/go-http-metrics/middleware"
14+
httpstdmiddleware "github.com/slok/go-http-metrics/middleware/std"
1415
)
1516
1617
func main() {
@@ -24,7 +25,7 @@ the main Go net/http handler:
2425
w.WriteHeader(http.StatusOK)
2526
w.Write([]byte("hello world!"))
2627
})
27-
h := mdlw.Handler("", myHandler)
28+
h := httpstdmiddleware.Measure("", mdlw, myHandler)
2829
2930
// Serve metrics.
3031
log.Printf("serving metrics at: %s", ":9090")

examples/custom/main.go

+5-4
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"github.com/prometheus/client_golang/prometheus/promhttp"
1212
metrics "github.com/slok/go-http-metrics/metrics/prometheus"
1313
"github.com/slok/go-http-metrics/middleware"
14+
"github.com/slok/go-http-metrics/middleware/std"
1415
)
1516

1617
const (
@@ -50,10 +51,10 @@ func main() {
5051
// Wrape our middleware on each of the different handlers with the ID of the handler
5152
// this way we reduce the cardinality, for example: `/test/2` and `/test/4` will
5253
// have the same `handler` label on the metric: `/test/:testID`
53-
mux.Handle("/", mdlw.Handler("/", rooth))
54-
mux.Handle("/test/1", mdlw.Handler("/test/:testID", testh))
55-
mux.Handle("/test/2", mdlw.Handler("/test/:testID", testh2))
56-
mux.Handle("/other-test", mdlw.Handler("/other-test", othetesth))
54+
mux.Handle("/", std.Measure("/", mdlw, rooth))
55+
mux.Handle("/test/1", std.Measure("/test/:testID", mdlw, testh))
56+
mux.Handle("/test/2", std.Measure("/test/:testID", mdlw, testh2))
57+
mux.Handle("/other-test", std.Measure("/other-test", mdlw, othetesth))
5758

5859
// Serve our handler.
5960
go func() {

examples/default/main.go

+2-1
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import (
1111
"github.com/prometheus/client_golang/prometheus/promhttp"
1212
metrics "github.com/slok/go-http-metrics/metrics/prometheus"
1313
"github.com/slok/go-http-metrics/middleware"
14+
"github.com/slok/go-http-metrics/middleware/std"
1415
)
1516

1617
const (
@@ -45,7 +46,7 @@ func main() {
4546

4647
// Wrap our main handler, we pass empty handler ID so the middleware inferes
4748
// the handler label from the URL.
48-
h := mdlw.Handler("", mux)
49+
h := std.Measure("", mdlw, mux)
4950

5051
// Serve our handler.
5152
go func() {

examples/echo/main.go

+4-1
Original file line numberDiff line numberDiff line change
@@ -28,12 +28,15 @@ func main() {
2828

2929
// Create Echo instance and global middleware.
3030
e := echo.New()
31-
e.Use(echoMiddleware.Handler("", mdlw))
31+
e.Use(echoMiddleware.Measure("", mdlw))
3232

3333
// Add our handler.
3434
e.GET("/", func(c echo.Context) error {
3535
return c.String(http.StatusOK, "Hello world")
3636
})
37+
e.GET("/json", func(c echo.Context) error {
38+
return c.JSON(http.StatusAccepted, map[string]string{"hello": "world"})
39+
})
3740
e.GET("/wrong", func(c echo.Context) error {
3841
return c.String(http.StatusTooManyRequests, "oops")
3942
})

examples/gin/main.go

+8-2
Original file line numberDiff line numberDiff line change
@@ -27,11 +27,17 @@ func main() {
2727

2828
// Create Gin engine and global middleware.
2929
engine := gin.New()
30-
engine.Use(ginmiddleware.Handler("", mdlw))
30+
engine.Use(ginmiddleware.Measure("", mdlw))
3131

3232
// Add our handler.
3333
engine.GET("/", func(c *gin.Context) {
34-
c.String(http.StatusOK, "Hello world")
34+
c.String(http.StatusOK, "Hello %s", "world")
35+
})
36+
engine.GET("/json", func(c *gin.Context) {
37+
c.JSON(http.StatusAccepted, map[string]string{"hello": "world"})
38+
})
39+
engine.GET("/yaml", func(c *gin.Context) {
40+
c.YAML(http.StatusCreated, map[string]string{"hello": "world"})
3541
})
3642
engine.GET("/wrong", func(c *gin.Context) {
3743
c.String(http.StatusTooManyRequests, "oops")

examples/gorestful/main.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -29,7 +29,7 @@ func main() {
2929
c := gorestful.NewContainer()
3030

3131
// Add the middleware for all routes.
32-
c.Filter(gorestfulmiddleware.Handler("", mdlw))
32+
c.Filter(gorestfulmiddleware.Measure("", mdlw))
3333

3434
// Add our handler.
3535
ws := &gorestful.WebService{}

examples/httprouter/main.go

+3-3
Original file line numberDiff line numberDiff line change
@@ -46,9 +46,9 @@ func main() {
4646
r := httprouter.New()
4747

4848
// Add the middleware to each route.
49-
r.GET("/", httproutermiddleware.Handler("/", h, mdlw))
50-
r.GET("/test/:id", httproutermiddleware.Handler("/test/:id", h1, mdlw))
51-
r.GET("/test2/:id", httproutermiddleware.Handler("/test2/:id", h2, mdlw))
49+
r.GET("/", httproutermiddleware.Measure("/", h, mdlw))
50+
r.GET("/test/:id", httproutermiddleware.Measure("/test/:id", h1, mdlw))
51+
r.GET("/test2/:id", httproutermiddleware.Measure("/test2/:id", h2, mdlw))
5252

5353
// Serve our handler.
5454
go func() {

examples/negroni/main.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -36,7 +36,7 @@ func main() {
3636
n := negroni.Classic()
3737

3838
// Add the middleware to negroni.
39-
n.Use(negronimiddleware.Handler("", mdlw))
39+
n.Use(negronimiddleware.Measure("", mdlw))
4040

4141
// Finally set our router on negroni.
4242
n.UseHandler(mux)

examples/opencensus/main.go

+4-2
Original file line numberDiff line numberDiff line change
@@ -10,8 +10,10 @@ import (
1010

1111
ocprometheus "contrib.go.opencensus.io/exporter/prometheus"
1212
ocmmetrics "github.com/slok/go-http-metrics/metrics/opencensus"
13-
"github.com/slok/go-http-metrics/middleware"
1413
"go.opencensus.io/stats/view"
14+
15+
"github.com/slok/go-http-metrics/middleware"
16+
"github.com/slok/go-http-metrics/middleware/std"
1517
)
1618

1719
const (
@@ -52,7 +54,7 @@ func main() {
5254

5355
// Wrap our main handler, we pass empty handler ID so the middleware inferes
5456
// the handler label from the URL.
55-
h := mdlw.Handler("", mux)
57+
h := std.Measure("", mdlw, mux)
5658

5759
// Serve our handler.
5860
go func() {

internal/mocks/doc.go

+1
Original file line numberDiff line numberDiff line change
@@ -4,3 +4,4 @@ Package mocks will have all the mocks of the library.
44
package mocks // import "github.com/slok/go-http-metrics/internal/mocks"
55

66
//go:generate mockery -output ./metrics -outpkg metrics -dir ../../metrics -name Recorder
7+
//go:generate mockery -output ./middleware -outpkg middleware -dir ../../middleware -name Reporter

internal/mocks/metrics/Recorder.go

+8-4
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

internal/mocks/middleware/Reporter.go

+86
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

middleware/echo/echo.go

+27-8
Original file line numberDiff line numberDiff line change
@@ -3,17 +3,36 @@
33
package echo
44

55
import (
6-
"net/http"
6+
"context"
77

88
"github.com/labstack/echo/v4"
99
"github.com/slok/go-http-metrics/middleware"
1010
)
1111

12-
// Handler returns a Echo compatible middleware from a Middleware factory instance.
13-
// The first handlerID argument is the same argument passed on Middleware.Handler method.
14-
func Handler(handlerID string, m middleware.Middleware) echo.MiddlewareFunc {
15-
// Wrap wrapping handler with echo's WrapMiddleware helper
16-
return echo.WrapMiddleware(func(next http.Handler) http.Handler {
17-
return m.Handler(handlerID, next)
18-
})
12+
// Measure returns a Echo measure middleware.
13+
func Measure(handlerID string, m middleware.Middleware) echo.MiddlewareFunc {
14+
return func(h echo.HandlerFunc) echo.HandlerFunc {
15+
return echo.HandlerFunc(func(c echo.Context) error {
16+
r := &reporter{c: c}
17+
var err error
18+
m.Measure(handlerID, r, func() {
19+
err = h(c)
20+
})
21+
return err
22+
})
23+
}
1924
}
25+
26+
type reporter struct {
27+
c echo.Context
28+
}
29+
30+
func (r *reporter) Method() string { return r.c.Request().Method }
31+
32+
func (r *reporter) Context() context.Context { return r.c.Request().Context() }
33+
34+
func (r *reporter) URLPath() string { return r.c.Request().URL.Path }
35+
36+
func (r *reporter) StatusCode() int { return r.c.Response().Status }
37+
38+
func (r *reporter) BytesWritten() int64 { return r.c.Response().Size }

middleware/echo/echo_test.go

+5-7
Original file line numberDiff line numberDiff line change
@@ -22,8 +22,7 @@ func getTestHandler(statusCode int) echo.HandlerFunc {
2222
}
2323

2424
func TestMiddlewareIntegration(t *testing.T) {
25-
tests := []struct {
26-
name string
25+
tests := map[string]struct {
2726
handlerID string
2827
statusCode int
2928
req *http.Request
@@ -33,8 +32,7 @@ func TestMiddlewareIntegration(t *testing.T) {
3332
expMethod string
3433
expStatusCode string
3534
}{
36-
{
37-
name: "A default HTTP middleware should call the recorder to measure.",
35+
"A default HTTP middleware should call the recorder to measure.": {
3836
statusCode: http.StatusAccepted,
3937
req: httptest.NewRequest(http.MethodPost, "/test", nil),
4038
expHandlerID: "/test",
@@ -43,8 +41,8 @@ func TestMiddlewareIntegration(t *testing.T) {
4341
},
4442
}
4543

46-
for _, test := range tests {
47-
t.Run(test.name, func(t *testing.T) {
44+
for name, test := range tests {
45+
t.Run(name, func(t *testing.T) {
4846
assert := assert.New(t)
4947

5048
// Mocks.
@@ -67,7 +65,7 @@ func TestMiddlewareIntegration(t *testing.T) {
6765
// Create our echo instance with the middleware.
6866
mdlw := middleware.New(middleware.Config{Recorder: mr})
6967
e := echo.New()
70-
e.POST("/test", getTestHandler(test.statusCode), echoMiddleware.Handler("", mdlw))
68+
e.POST("/test", getTestHandler(test.statusCode), echoMiddleware.Measure("", mdlw))
7169

7270
// Make the request.
7371
resp := httptest.NewRecorder()

middleware/echo/example_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ func Example_echoMiddleware() {
2727
h := func(c echo.Context) error {
2828
return c.String(http.StatusOK, "Hello world")
2929
}
30-
e.GET("/", h, echoMiddleware.Handler("", mdlw))
30+
e.GET("/", h, echoMiddleware.Measure("", mdlw))
3131

3232
// Serve metrics from the default prometheus registry.
3333
log.Printf("serving metrics at: %s", ":8081")

middleware/gin/example_test.go

+1-1
Original file line numberDiff line numberDiff line change
@@ -27,7 +27,7 @@ func Example_ginMiddleware() {
2727
h := func(c *gin.Context) {
2828
c.String(http.StatusOK, "Hello world")
2929
}
30-
engine.GET("/", ginmiddleware.Handler("", mdlw), h)
30+
engine.GET("/", ginmiddleware.Measure("", mdlw), h)
3131

3232
// Serve metrics from the default prometheus registry.
3333
log.Printf("serving metrics at: %s", ":8081")

0 commit comments

Comments
 (0)