Skip to content

Commit

Permalink
Insturment the app with prometheus.
Browse files Browse the repository at this point in the history
  • Loading branch information
tomwilkie committed Apr 6, 2016
1 parent 26a35d7 commit 10717be
Show file tree
Hide file tree
Showing 2 changed files with 65 additions and 1 deletion.
46 changes: 46 additions & 0 deletions common/middleware/instrument.go
Original file line number Diff line number Diff line change
@@ -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
}
20 changes: 19 additions & 1 deletion prog/app.go
Original file line number Diff line number Diff line change
Expand Up @@ -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"

Expand All @@ -26,12 +27,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)
Expand All @@ -40,7 +54,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 {
Expand Down

0 comments on commit 10717be

Please sign in to comment.