Adds request latency tracking

Fixes #1
This commit is contained in:
Stephen McQuay 2018-01-21 14:50:32 -08:00
parent 6fa26ec095
commit 70288014ea
Signed by: sm
GPG Key ID: 4E4B72F479BA3CE5
4 changed files with 87 additions and 1 deletions

View File

@ -6,7 +6,9 @@ import (
"os"
"github.com/prometheus/client_golang/prometheus/promhttp"
"mcquay.me/hwt"
"mcquay.me/hwt/metrics"
pb "mcquay.me/hwt/rpc/hwt"
)
@ -15,8 +17,14 @@ func main() {
if err != nil {
log.Fatalf("cannot get hostname: %v", err)
}
if err := metrics.RegisterPromMetrics(); err != nil {
log.Fatalf("registering prom metrics: %v", err)
}
s := &hwt.Server{hn}
th := pb.NewHelloWorldServer(s, nil)
hs := hwt.NewMetricsHooks(metrics.HTTPLatency)
th := pb.NewHelloWorldServer(s, hs)
sm := http.NewServeMux()
sm.Handle("/", th)
sm.Handle("/metrics", promhttp.Handler())

46
hooks.go Normal file
View File

@ -0,0 +1,46 @@
package hwt
import (
"context"
"time"
"github.com/twitchtv/twirp"
)
var reqStartKey = new(int)
type Timer func(path string, dur time.Duration)
func NewMetricsHooks(timer Timer) *twirp.ServerHooks {
hs := &twirp.ServerHooks{}
hs.RequestReceived = func(ctx context.Context) (context.Context, error) {
return markReqStart(ctx), nil
}
hs.ResponseSent = func(ctx context.Context) {
name, ok := twirp.MethodName(ctx)
if !ok {
// XXX (sm) : something else?
panic("missing name")
}
start, ok := getReqStart(ctx)
if !ok {
// XXX (sm) : something else?
panic("missing start")
}
dur := time.Now().Sub(start)
timer(name, dur)
}
return hs
}
func markReqStart(ctx context.Context) context.Context {
return context.WithValue(ctx, reqStartKey, time.Now())
}
func getReqStart(ctx context.Context) (time.Time, bool) {
t, ok := ctx.Value(reqStartKey).(time.Time)
return t, ok
}

9
metrics/metrics.go Normal file
View File

@ -0,0 +1,9 @@
package metrics
import (
"time"
)
func HTTPLatency(path string, dur time.Duration) {
httpReqLat.WithLabelValues(path).Observe(float64(dur) / float64(time.Millisecond))
}

23
metrics/prom.go Normal file
View File

@ -0,0 +1,23 @@
package metrics
import (
"github.com/pkg/errors"
"github.com/prometheus/client_golang/prometheus"
)
var (
httpReqLat = prometheus.NewSummaryVec(
prometheus.SummaryOpts{
Name: "hwt_request_latency_ms",
Help: "Latency in ms of http requests grouped by req path",
},
[]string{"path"},
)
)
func RegisterPromMetrics() error {
if err := prometheus.Register(httpReqLat); err != nil {
return errors.Wrap(err, "registering http request latency")
}
return nil
}