From 081b81d170e2df4e0cc66ca6a4ead07aeead5e9b Mon Sep 17 00:00:00 2001 From: Roland Shoemaker Date: Sat, 26 Sep 2015 18:01:03 -0700 Subject: [PATCH] Add a facebookgo/stats client that sends StatsD metrics for facebookgo/httpdown --- cmd/boulder-wfe/main.go | 6 ++-- cmd/ocsp-responder/main.go | 6 ++-- metrics/metrics.go | 68 +++++++++++++++++++++++++++----------- 3 files changed, 55 insertions(+), 25 deletions(-) diff --git a/cmd/boulder-wfe/main.go b/cmd/boulder-wfe/main.go index e100ff9c5..d0892da87 100644 --- a/cmd/boulder-wfe/main.go +++ b/cmd/boulder-wfe/main.go @@ -126,14 +126,14 @@ func main() { auditlogger.Info(fmt.Sprintf("Server running, listening on %s...\n", c.WFE.ListenAddress)) srv := &http.Server{ - Addr: c.WFE.ListenAddress, - ConnState: httpMonitor.ConnectionMonitor, - Handler: httpMonitor.Handle(), + Addr: c.WFE.ListenAddress, + Handler: httpMonitor.Handle(), } hd := &httpdown.HTTP{ StopTimeout: wfe.ShutdownStopTimeout, KillTimeout: wfe.ShutdownKillTimeout, + Stats: metrics.NewFBAdapter(stats, "WFE"), } err = httpdown.ListenAndServe(srv, hd) cmd.FailOnError(err, "Error starting HTTP server") diff --git a/cmd/ocsp-responder/main.go b/cmd/ocsp-responder/main.go index 02e1c6724..4a15564c0 100644 --- a/cmd/ocsp-responder/main.go +++ b/cmd/ocsp-responder/main.go @@ -174,14 +174,14 @@ func main() { httpMonitor := metrics.NewHTTPMonitor(stats, m, "OCSP") srv := &http.Server{ - Addr: c.OCSPResponder.ListenAddress, - ConnState: httpMonitor.ConnectionMonitor, - Handler: httpMonitor.Handle(), + Addr: c.OCSPResponder.ListenAddress, + Handler: httpMonitor.Handle(), } hd := &httpdown.HTTP{ StopTimeout: stopTimeout, KillTimeout: killTimeout, + Stats: metrics.NewFBAdapter(stats, "OCSP"), } err = httpdown.ListenAndServe(srv, hd) cmd.FailOnError(err, "Error starting HTTP server") diff --git a/metrics/metrics.go b/metrics/metrics.go index 96bf86639..0d1d031b2 100644 --- a/metrics/metrics.go +++ b/metrics/metrics.go @@ -7,7 +7,6 @@ package metrics import ( "fmt" - "net" "net/http" "strings" "sync/atomic" @@ -22,7 +21,6 @@ type HTTPMonitor struct { statsPrefix string handler http.Handler connectionsInFlight int64 - openConnections int64 } // NewHTTPMonitor returns a new initialized HTTPMonitor @@ -32,26 +30,9 @@ func NewHTTPMonitor(stats statsd.Statter, handler http.Handler, prefix string) H handler: handler, statsPrefix: prefix, connectionsInFlight: 0, - openConnections: 0, } } -// ConnectionMonitor provides states on open connection state -func (h *HTTPMonitor) ConnectionMonitor(_ net.Conn, state http.ConnState) { - var open int64 - switch state { - case http.StateNew: - open = atomic.AddInt64(&h.openConnections, 1) - case http.StateHijacked: - fallthrough - case http.StateClosed: - open = atomic.AddInt64(&h.openConnections, -1) - default: - return - } - h.stats.Gauge(fmt.Sprintf("%s.HTTP.OpenConnections", h.statsPrefix), open, 1.0) -} - // Handle wraps handlers and records various metrics about requests to these handlers // and sends them to StatsD func (h *HTTPMonitor) Handle() http.Handler { @@ -85,3 +66,52 @@ func (h *HTTPMonitor) watchAndServe(w http.ResponseWriter, r *http.Request) { } h.stats.TimingDuration(fmt.Sprintf("%s.HTTP.ResponseTime.%s", h.statsPrefix, endpoint), cClosed, 1.0) } + +// FBAdapter provides a facebookgo/stats client interface that sends metrics via +// a StatsD client +type FBAdapter struct { + stats statsd.Statter + prefix string +} + +// NewFBAdapter returns a new adapter +func NewFBAdapter(stats statsd.Statter, prefix string) FBAdapter { + return FBAdapter{stats: stats, prefix: prefix} +} + +// BumpAvg is essentially statsd.Statter.Gauge +func (fba FBAdapter) BumpAvg(key string, val float64) { + fba.stats.Gauge(fmt.Sprintf("%s.%s", fba.prefix, key), int64(val), 1.0) +} + +// BumpSum is essentially statsd.Statter.Inc (httpdown only ever uses positive +// deltas) +func (fba FBAdapter) BumpSum(key string, val float64) { + fba.stats.Inc(fmt.Sprintf("%s.%s", fba.prefix, key), int64(val), 1.0) +} + +type btHolder struct { + key string + stats statsd.Statter + started time.Time +} + +func (bth btHolder) End() { + bth.stats.TimingDuration(bth.key, time.Since(bth.started), 1.0) +} + +// BumpTime is essentially a (much better) statsd.Statter.TimingDuration +func (fba FBAdapter) BumpTime(key string) interface { + End() +} { + return btHolder{ + key: fmt.Sprintf("%s.%s", fba.prefix, key), + started: time.Now(), + stats: fba.stats, + } +} + +// BumpHistogram isn't used by facebookgo/httpdown +func (fba FBAdapter) BumpHistogram(_ string, _ float64) { + return +}