Skip to content

Commit

Permalink
Add metrics middleware to collect request duration metrics (#4486)
Browse files Browse the repository at this point in the history
  • Loading branch information
tamirms authored Jul 28, 2022
1 parent 90f32cc commit 738befe
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 14 deletions.
63 changes: 63 additions & 0 deletions exp/lighthorizon/http.go
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
package main

import (
"github.com/go-chi/chi"
"github.com/go-chi/chi/middleware"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"
"github.com/stellar/go/exp/lighthorizon/actions"
"github.com/stellar/go/exp/lighthorizon/services"
"net/http"
"strconv"
"time"
)

func newWrapResponseWriter(w http.ResponseWriter, r *http.Request) middleware.WrapResponseWriter {
mw, ok := w.(middleware.WrapResponseWriter)
if !ok {
mw = middleware.NewWrapResponseWriter(w, r.ProtoMajor)
}

return mw
}

func prometheusMiddleware(requestDurationMetric *prometheus.SummaryVec) func(next http.Handler) http.Handler {
return func(next http.Handler) http.Handler {
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
mw := newWrapResponseWriter(w, r)

then := time.Now()
next.ServeHTTP(mw, r)
duration := time.Since(then)

requestDurationMetric.With(prometheus.Labels{
"status": strconv.FormatInt(int64(mw.Status()), 10),
"method": r.Method,
}).Observe(float64(duration.Seconds()))
})
}
}

func lightHorizonHTTPHandler(registry *prometheus.Registry, lightHorizon services.LightHorizon) http.Handler {
requestDurationMetric := prometheus.NewSummaryVec(
prometheus.SummaryOpts{
Namespace: "horizon_lite", Subsystem: "http", Name: "requests_duration_seconds",
Help: "HTTP requests durations, sliding window = 10m",
},
[]string{"status", "method"},
)
registry.MustRegister(requestDurationMetric)

router := chi.NewMux()
router.Use(prometheusMiddleware(requestDurationMetric))

router.Route("/accounts/{account_id}", func(r chi.Router) {
r.MethodFunc(http.MethodGet, "/transactions", actions.NewTXByAccountHandler(lightHorizon))
r.MethodFunc(http.MethodGet, "/operations", actions.NewOpsByAccountHandler(lightHorizon))
})

router.MethodFunc(http.MethodGet, "/", actions.ApiDocs())
router.Method(http.MethodGet, "/metrics", promhttp.HandlerFor(registry, promhttp.HandlerOpts{}))

return router
}
15 changes: 1 addition & 14 deletions exp/lighthorizon/main.go
Original file line number Diff line number Diff line change
Expand Up @@ -4,11 +4,7 @@ import (
"flag"
"net/http"

"github.com/go-chi/chi"
"github.com/prometheus/client_golang/prometheus"
"github.com/prometheus/client_golang/prometheus/promhttp"

"github.com/stellar/go/exp/lighthorizon/actions"
"github.com/stellar/go/exp/lighthorizon/archive"
"github.com/stellar/go/exp/lighthorizon/index"
"github.com/stellar/go/exp/lighthorizon/services"
Expand Down Expand Up @@ -71,14 +67,5 @@ if left empty, uses a temporary directory`)
},
}

router := chi.NewMux()
router.Route("/accounts/{account_id}", func(r chi.Router) {
r.MethodFunc(http.MethodGet, "/transactions", actions.NewTXByAccountHandler(lightHorizon))
r.MethodFunc(http.MethodGet, "/operations", actions.NewOpsByAccountHandler(lightHorizon))
})

router.MethodFunc(http.MethodGet, "/", actions.ApiDocs())
router.Method(http.MethodGet, "/metrics", promhttp.HandlerFor(registry, promhttp.HandlerOpts{}))

log.Fatal(http.ListenAndServe(":8080", router))
log.Fatal(http.ListenAndServe(":8080", lightHorizonHTTPHandler(registry, lightHorizon)))
}

0 comments on commit 738befe

Please sign in to comment.