func InstrumentHandlerFunc(handlerName string, handlerFunc func(http.ResponseWriter, *http.Request)) http.HandlerFunc {
	regReqCnt := MustRegisterOrGet(reqCnt).(*CounterVec)
	regReqDur := MustRegisterOrGet(reqDur).(*SummaryVec)
	regReqSz := MustRegisterOrGet(reqSz).(*SummaryVec)
	regResSz := MustRegisterOrGet(resSz).(*SummaryVec)
	return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
		now := time.Now()
		delegate := &responseWriterDelegator{ResponseWriter: w}
		out := make(chan int)
		go computeApproximateRequestSize(r, out)
		handlerFunc(delegate, r)
		elapsed := float64(time.Since(now)) / float64(time.Microsecond)
		method := sanitizeMethod(r.Method)
		code := sanitizeCode(delegate.status)
		regReqCnt.WithLabelValues(handlerName, method, code).Inc()
		regReqDur.WithLabelValues(handlerName, method, code).Observe(elapsed)
		regResSz.WithLabelValues(handlerName, method, code).Observe(float64(delegate.written))
		regReqSz.WithLabelValues(handlerName, method, code).Observe(float64(<-out))
	})
}
InstrumentHandlerFunc wraps the given function for instrumentation. It
registers four metric vector collectors (if not already done) and reports
http metrics to the (newly or already) registered collectors:
http_requests_total (CounterVec), http_request_duration_microseconds
(SummaryVec), http_request_size_bytes (SummaryVec), http_response_size_bytes
(SummaryVec). Each has three labels: handler, method, code. The value of the
handler label is set by the handlerName parameter of this function.
package prometheus
import (
	"net/http"
	"strconv"
	"strings"
	"time"
)
var (
	instLabels = []string{"handler", "method", "code"}
	reqCnt = NewCounterVec(
		CounterOpts{
			Subsystem: "http",
			Name:      "requests_total",
			Help:      "Total number of HTTP requests made.",
		},
		instLabels,
	)
	reqDur = NewSummaryVec(
		SummaryOpts{
			Subsystem: "http",
			Name:      "request_duration_microseconds",
			Help:      "The HTTP request latencies in microseconds.",
		},
		instLabels,
	)
	reqSz = NewSummaryVec(
		SummaryOpts{
			Subsystem: "http",
			Name:      "request_size_bytes",
			Help:      "The HTTP request sizes in bytes.",
		},
		instLabels,
	)
	resSz = NewSummaryVec(
		SummaryOpts{
			Subsystem: "http",
			Name:      "response_size_bytes",
			Help:      "The HTTP response sizes in bytes.",
		},
		instLabels,
	)
)
type nower interface {
	Now() time.Time
}
type nowFunc func() time.Time
func (n nowFunc) Now() time.Time {
	return n()
}
var now nower = nowFunc(func() time.Time {
	return time.Now()
})
func nowSeries(t ...time.Time) nower {
	return nowFunc(func() time.Time {
		defer func() {
			t = t[1:]
		}()
		return t[0]
	})
}
func InstrumentHandler(handlerName string, handler http.Handler) http.HandlerFunc {
	return InstrumentHandlerFunc(handlerName, handler.ServeHTTP)
}