Skip to content

Commit c540391

Browse files
committed
Add handler provider for multiple frameworks and support chi, alice and gorilla frameworks
Signed-off-by: Xabier Larrakoetxea <[email protected]>
1 parent 4013ab5 commit c540391

File tree

13 files changed

+440
-56
lines changed

13 files changed

+440
-56
lines changed

.github/workflows/ci.yml

+6-6
Original file line numberDiff line numberDiff line change
@@ -7,28 +7,28 @@ jobs:
77
name: Check
88
runs-on: ubuntu-latest
99
# Execute the checks inside the container instead the VM.
10-
container: golangci/golangci-lint:v1.27.0-alpine
10+
container: golangci/golangci-lint:v1.31.0-alpine
1111
steps:
12-
- uses: actions/checkout@v1
12+
- uses: actions/checkout@v2
1313
- run: golangci-lint run -E goimports
1414

1515
unit-test:
1616
name: Unit test
1717
runs-on: ubuntu-latest
1818
steps:
19-
- uses: actions/checkout@v1
19+
- uses: actions/checkout@v2
2020
- uses: actions/setup-go@v1
2121
with:
22-
go-version: 1.14
22+
go-version: 1.15
2323
- run: make test
2424

2525
integration-test:
2626
name: Integration test
2727
runs-on: ubuntu-latest
2828
needs: [check, unit-test]
2929
steps:
30-
- uses: actions/checkout@v1
30+
- uses: actions/checkout@v2
3131
- uses: actions/setup-go@v1
3232
with:
33-
go-version: 1.14
33+
go-version: 1.15
3434
- run: make integration-test

CHANGELOG.md

+8-1
Original file line numberDiff line numberDiff line change
@@ -2,6 +2,13 @@
22

33
## [Unreleased]
44

5+
### Added
6+
7+
- New helper method to get an `std` HTTP provider (`std.HandlerProvider`) (used by various frameworks like Gorilla).
8+
- Support Chi library.
9+
- Support Alice library.
10+
- Support Gorilla library.
11+
512
## [0.8.0] - 2020-06-04
613

714
### Added
@@ -92,7 +99,7 @@ Breaking change: The library has been refactored to be more flexible when adding
9299
- Prometheus recorder.
93100

94101
[unreleased]: https://github.com/slok/go-http-metrics/compare/v0.8.0...HEAD
95-
[0.8.0]: https://github.com/slok/go-http-metrics/compare/v0.7.0...v0.8.0
102+
[0.8.0]: https://github.com/slok/go-http-metrics/compare/v0.7.0...v0.8.0
96103
[0.7.0]: https://github.com/slok/go-http-metrics/compare/v0.6.1...v0.7.0
97104
[0.6.1]: https://github.com/slok/go-http-metrics/compare/v0.6.0...v0.6.1
98105
[0.6.0]: https://github.com/slok/go-http-metrics/compare/v0.5.0...v0.6.0

Readme.md

+11-2
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,11 @@ The middleware is mainly focused to be compatible with Go std library using http
4242
- [Gin][gin-example]
4343
- [Echo][echo-example]
4444
- [Goji][goji-example]
45+
- [Chi][chi-example]
46+
- [Alice][alice-example]
47+
- [gorilla][gorilla-example]
48+
49+
It supports any framework that supports http.Handler provider type middleware `func(http.Handler) http.Handler` (e.g Chi, Alice, Gorilla...). Use [`std.HandlerProvider`][handler-provider-docs]
4550

4651
## Getting Started
4752

@@ -200,8 +205,8 @@ This Option is used to unregister the Recorder views before are being registered
200205
[github-actions-url]: https://github.com/slok/go-http-metrics/actions
201206
[goreport-image]: https://goreportcard.com/badge/github.com/slok/go-http-metrics
202207
[goreport-url]: https://goreportcard.com/report/github.com/slok/go-http-metrics
203-
[godoc-image]: https://godoc.org/github.com/slok/go-http-metrics?status.svg
204-
[godoc-url]: https://godoc.org/github.com/slok/go-http-metrics
208+
[godoc-image]: https://pkg.go.dev/badge/github.com/slok/go-http-metrics
209+
[godoc-url]: https://pkg.go.dev/github.com/slok/go-http-metrics
205210
[docs]: https://godoc.org/github.com/slok/go-http-metrics
206211
[examples]: examples/
207212
[red]: https://www.weave.works/blog/the-red-method-key-metrics-for-microservices-architecture/
@@ -214,5 +219,9 @@ This Option is used to unregister the Recorder views before are being registered
214219
[gin-example]: examples/gin
215220
[echo-example]: examples/echo
216221
[goji-example]: examples/goji
222+
[chi-example]: examples/chi
223+
[alice-example]: examples/alice
224+
[gorilla-example]: examples/gorilla
217225
[prometheus-recorder]: metrics/prometheus
218226
[opencensus-recorder]: metrics/opencensus
227+
[handler-provider-docs]: https://pkg.go.dev/github.com/slok/go-http-metrics/middleware/std#HandlerProvider

examples/alice/main.go

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package main
2+
3+
import (
4+
"log"
5+
"net/http"
6+
"os"
7+
"os/signal"
8+
"syscall"
9+
"time"
10+
11+
"github.com/justinas/alice"
12+
"github.com/prometheus/client_golang/prometheus/promhttp"
13+
metrics "github.com/slok/go-http-metrics/metrics/prometheus"
14+
"github.com/slok/go-http-metrics/middleware"
15+
"github.com/slok/go-http-metrics/middleware/std"
16+
)
17+
18+
const (
19+
srvAddr = ":8080"
20+
metricsAddr = ":8081"
21+
)
22+
23+
func main() {
24+
// Create our middleware.
25+
mdlw := middleware.New(middleware.Config{
26+
Recorder: metrics.NewRecorder(metrics.Config{}),
27+
})
28+
29+
// Create our server.
30+
mux := http.NewServeMux()
31+
mux.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) {
32+
time.Sleep(200 * time.Millisecond)
33+
w.WriteHeader(http.StatusOK)
34+
})
35+
mux.HandleFunc("/test1", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusCreated) })
36+
mux.HandleFunc("/test1/test2", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusAccepted) })
37+
mux.HandleFunc("/test1/test4", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusNonAuthoritativeInfo) })
38+
mux.HandleFunc("/test2", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusNoContent) })
39+
mux.HandleFunc("/test3", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusResetContent) })
40+
41+
// Wrap with middleware.
42+
h := alice.New(std.HandlerProvider("", mdlw)).Then(mux)
43+
44+
// Serve our handler.
45+
go func() {
46+
log.Printf("server listening at %s", srvAddr)
47+
if err := http.ListenAndServe(srvAddr, h); err != nil {
48+
log.Panicf("error while serving: %s", err)
49+
}
50+
}()
51+
52+
// Serve our metrics.
53+
go func() {
54+
log.Printf("metrics listening at %s", metricsAddr)
55+
if err := http.ListenAndServe(metricsAddr, promhttp.Handler()); err != nil {
56+
log.Panicf("error while serving metrics: %s", err)
57+
}
58+
}()
59+
60+
// Wait until some signal is captured.
61+
sigC := make(chan os.Signal, 1)
62+
signal.Notify(sigC, syscall.SIGTERM, syscall.SIGINT)
63+
<-sigC
64+
}

examples/chi/main.go

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package main
2+
3+
import (
4+
"log"
5+
"net/http"
6+
"os"
7+
"os/signal"
8+
"syscall"
9+
"time"
10+
11+
"github.com/go-chi/chi"
12+
"github.com/prometheus/client_golang/prometheus/promhttp"
13+
metrics "github.com/slok/go-http-metrics/metrics/prometheus"
14+
"github.com/slok/go-http-metrics/middleware"
15+
"github.com/slok/go-http-metrics/middleware/std"
16+
)
17+
18+
const (
19+
srvAddr = ":8080"
20+
metricsAddr = ":8081"
21+
)
22+
23+
func main() {
24+
// Create our middleware.
25+
mdlw := middleware.New(middleware.Config{
26+
Recorder: metrics.NewRecorder(metrics.Config{}),
27+
})
28+
29+
// Create our router with the metrics middleware.
30+
r := chi.NewRouter()
31+
r.Use(std.HandlerProvider("", mdlw))
32+
33+
// Add paths.
34+
r.Get("/", func(w http.ResponseWriter, r *http.Request) {
35+
time.Sleep(200 * time.Millisecond)
36+
w.WriteHeader(http.StatusOK)
37+
})
38+
r.Get("/test1", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusCreated) })
39+
r.Get("/test1/test2", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusAccepted) })
40+
r.Get("/test1/test4", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusNonAuthoritativeInfo) })
41+
r.Get("/test2", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusNoContent) })
42+
r.Get("/test3", func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusResetContent) })
43+
44+
// Serve our handler.
45+
go func() {
46+
log.Printf("server listening at %s", srvAddr)
47+
if err := http.ListenAndServe(srvAddr, r); err != nil {
48+
log.Panicf("error while serving: %s", err)
49+
}
50+
}()
51+
52+
// Serve our metrics.
53+
go func() {
54+
log.Printf("metrics listening at %s", metricsAddr)
55+
if err := http.ListenAndServe(metricsAddr, promhttp.Handler()); err != nil {
56+
log.Panicf("error while serving metrics: %s", err)
57+
}
58+
}()
59+
60+
// Wait until some signal is captured.
61+
sigC := make(chan os.Signal, 1)
62+
signal.Notify(sigC, syscall.SIGTERM, syscall.SIGINT)
63+
<-sigC
64+
}

examples/gorilla/main.go

+64
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,64 @@
1+
package main
2+
3+
import (
4+
"log"
5+
"net/http"
6+
"os"
7+
"os/signal"
8+
"syscall"
9+
"time"
10+
11+
"github.com/gorilla/mux"
12+
"github.com/prometheus/client_golang/prometheus/promhttp"
13+
metrics "github.com/slok/go-http-metrics/metrics/prometheus"
14+
"github.com/slok/go-http-metrics/middleware"
15+
"github.com/slok/go-http-metrics/middleware/std"
16+
)
17+
18+
const (
19+
srvAddr = ":8080"
20+
metricsAddr = ":8081"
21+
)
22+
23+
func main() {
24+
// Create our middleware.
25+
mdlw := middleware.New(middleware.Config{
26+
Recorder: metrics.NewRecorder(metrics.Config{}),
27+
})
28+
29+
// Create our router with the metrics middleware.
30+
r := mux.NewRouter()
31+
r.Use(std.HandlerProvider("", mdlw))
32+
33+
// Add paths.
34+
r.Methods("GET").Path("/").HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
35+
time.Sleep(200 * time.Millisecond)
36+
w.WriteHeader(http.StatusOK)
37+
})
38+
r.Methods("GET").Path("/test1").HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusCreated) })
39+
r.Methods("GET").Path("/test1/test2").HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusAccepted) })
40+
r.Methods("GET").Path("/test1/test4").HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusNonAuthoritativeInfo) })
41+
r.Methods("GET").Path("/test2").HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusNoContent) })
42+
r.Methods("GET").Path("/test3").HandlerFunc(func(w http.ResponseWriter, r *http.Request) { w.WriteHeader(http.StatusResetContent) })
43+
44+
// Serve our handler.
45+
go func() {
46+
log.Printf("server listening at %s", srvAddr)
47+
if err := http.ListenAndServe(srvAddr, r); err != nil {
48+
log.Panicf("error while serving: %s", err)
49+
}
50+
}()
51+
52+
// Serve our metrics.
53+
go func() {
54+
log.Printf("metrics listening at %s", metricsAddr)
55+
if err := http.ListenAndServe(metricsAddr, promhttp.Handler()); err != nil {
56+
log.Panicf("error while serving metrics: %s", err)
57+
}
58+
}()
59+
60+
// Wait until some signal is captured.
61+
sigC := make(chan os.Signal, 1)
62+
signal.Notify(sigC, syscall.SIGTERM, syscall.SIGINT)
63+
<-sigC
64+
}

go.mod

+10-7
Original file line numberDiff line numberDiff line change
@@ -1,16 +1,19 @@
11
module github.com/slok/go-http-metrics
22

33
require (
4-
contrib.go.opencensus.io/exporter/prometheus v0.1.0
5-
github.com/emicklei/go-restful v2.12.0+incompatible
4+
contrib.go.opencensus.io/exporter/prometheus v0.2.0
5+
github.com/emicklei/go-restful v2.14.2+incompatible
66
github.com/gin-gonic/gin v1.6.3
7+
github.com/go-chi/chi v4.1.2+incompatible
8+
github.com/gorilla/mux v1.8.0
79
github.com/julienschmidt/httprouter v1.3.0
8-
github.com/labstack/echo/v4 v4.1.16
9-
github.com/prometheus/client_golang v1.6.0
10-
github.com/stretchr/testify v1.6.0
10+
github.com/justinas/alice v1.2.0
11+
github.com/labstack/echo/v4 v4.1.17
12+
github.com/prometheus/client_golang v1.7.1
13+
github.com/stretchr/testify v1.6.1
1114
github.com/urfave/negroni v1.0.0
12-
go.opencensus.io v0.22.3
15+
go.opencensus.io v0.22.4
1316
goji.io v2.0.2+incompatible
1417
)
1518

16-
go 1.14
19+
go 1.15

0 commit comments

Comments
 (0)