Insturment the app with prometheus.

This commit is contained in:
Tom Wilkie
2016-04-06 14:58:28 +01:00
parent 5d7604cc21
commit 727553962b
2 changed files with 65 additions and 1 deletions
+46
View File
@@ -0,0 +1,46 @@
package middleware
import (
"net/http"
"strconv"
"time"
"github.com/gorilla/mux"
"github.com/prometheus/client_golang/prometheus"
)
type Instrument struct {
RouteMatcher RouteMatcher
Duration *prometheus.SummaryVec
}
// RouteMatcher is implemented by mux.Router.
type RouteMatcher interface {
Match(*http.Request, *mux.RouteMatch) bool
}
func (i Instrument) Wrap(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
begin := time.Now()
interceptor := &interceptor{ResponseWriter: w, statusCode: http.StatusOK}
next.ServeHTTP(interceptor, r)
var (
route = i.getRouteName(r)
status = strconv.Itoa(interceptor.statusCode)
took = time.Since(begin)
)
i.Duration.WithLabelValues(r.Method, route, status).Observe(float64(took.Nanoseconds()))
})
}
func (i Instrument) getRouteName(r *http.Request) string {
var routeMatch mux.RouteMatch
if !i.RouteMatcher.Match(r, &routeMatch) {
return "unmatched_path"
}
name := routeMatch.Route.GetName()
if name == "" {
return "unnamed_path"
}
return name
}
+19 -1
View File
@@ -16,6 +16,7 @@ import (
"github.com/aws/aws-sdk-go/aws"
"github.com/aws/aws-sdk-go/aws/credentials"
"github.com/gorilla/mux"
"github.com/prometheus/client_golang/prometheus"
"github.com/weaveworks/go-checkpoint"
"github.com/weaveworks/weave/common"
@@ -27,12 +28,25 @@ import (
"github.com/weaveworks/scope/probe/docker"
)
var (
requestDuration = prometheus.NewSummaryVec(prometheus.SummaryOpts{
Namespace: "scope",
Name: "request_duration_nanoseconds",
Help: "Time spent serving HTTP requests.",
}, []string{"method", "route", "status_code"})
)
func init() {
prometheus.MustRegister(requestDuration)
}
// Router creates the mux for all the various app components.
func router(collector app.Collector, controlRouter app.ControlRouter, pipeRouter app.PipeRouter) http.Handler {
router := mux.NewRouter().SkipClean(true)
// We pull in the http.DefaultServeMux to get the pprof routes
router.PathPrefix("/debug/pprof").Handler(http.DefaultServeMux)
router.Path("/metrics").Handler(prometheus.Handler())
app.RegisterReportPostHandler(collector, router)
app.RegisterControlRoutes(router, controlRouter)
@@ -41,7 +55,11 @@ func router(collector app.Collector, controlRouter app.ControlRouter, pipeRouter
router.PathPrefix("/").Handler(http.FileServer(FS(false)))
return router
instrument := middleware.Instrument{
RouteMatcher: router,
Duration: requestDuration,
}
return instrument.Wrap(router)
}
func awsConfigFromURL(url *url.URL) *aws.Config {