parent
6fa26ec095
commit
70288014ea
@ -6,7 +6,9 @@ import (
|
|||||||
"os"
|
"os"
|
||||||
|
|
||||||
"github.com/prometheus/client_golang/prometheus/promhttp"
|
"github.com/prometheus/client_golang/prometheus/promhttp"
|
||||||
|
|
||||||
"mcquay.me/hwt"
|
"mcquay.me/hwt"
|
||||||
|
"mcquay.me/hwt/metrics"
|
||||||
pb "mcquay.me/hwt/rpc/hwt"
|
pb "mcquay.me/hwt/rpc/hwt"
|
||||||
)
|
)
|
||||||
|
|
||||||
@ -15,8 +17,14 @@ func main() {
|
|||||||
if err != nil {
|
if err != nil {
|
||||||
log.Fatalf("cannot get hostname: %v", err)
|
log.Fatalf("cannot get hostname: %v", err)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if err := metrics.RegisterPromMetrics(); err != nil {
|
||||||
|
log.Fatalf("registering prom metrics: %v", err)
|
||||||
|
}
|
||||||
|
|
||||||
s := &hwt.Server{hn}
|
s := &hwt.Server{hn}
|
||||||
th := pb.NewHelloWorldServer(s, nil)
|
hs := hwt.NewMetricsHooks(metrics.HTTPLatency)
|
||||||
|
th := pb.NewHelloWorldServer(s, hs)
|
||||||
sm := http.NewServeMux()
|
sm := http.NewServeMux()
|
||||||
sm.Handle("/", th)
|
sm.Handle("/", th)
|
||||||
sm.Handle("/metrics", promhttp.Handler())
|
sm.Handle("/metrics", promhttp.Handler())
|
||||||
|
46
hooks.go
Normal file
46
hooks.go
Normal 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
9
metrics/metrics.go
Normal 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
23
metrics/prom.go
Normal 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
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user