func CaptureMetricsFn(w http.ResponseWriter, fn func(http.ResponseWriter)) Metrics {
	var (
		start         = time.Now()
		m             = Metrics{Code: http.StatusOK}
		headerWritten bool
		lock          sync.Mutex
		hooks         = Hooks{
			WriteHeader: func(next WriteHeaderFunc) WriteHeaderFunc {
				return func(code int) {
					next(code)
					lock.Lock()
					defer lock.Unlock()
					if !headerWritten {
						m.Code = code
						headerWritten = true
					}
				}
			},

			Write: func(next WriteFunc) WriteFunc {
				return func(p []byte) (int, error) {
					n, err := next(p)
					lock.Lock()
					defer lock.Unlock()
					m.Written += int64(n)
					headerWritten = true
					return n, err
				}
			},

			ReadFrom: func(next ReadFromFunc) ReadFromFunc {
				return func(src io.Reader) (int64, error) {
					n, err := next(src)
					lock.Lock()
					defer lock.Unlock()
					headerWritten = true
					m.Written += n
					return n, err
				}
			},
		}
	)

	fn(Wrap(w, hooks))
	m.Duration = time.Since(start)
	return m
}
func CaptureMetricsFn(w http.ResponseWriter, fn func(http.ResponseWriter)) Metrics {
	var (
		start         = time.Now()
		m             = Metrics{Code: http.StatusOK}
		headerWritten bool
		lock          sync.Mutex
		hooks         = Hooks{
			WriteHeader: func(next WriteHeaderFunc) WriteHeaderFunc {
				return func(code int) {
					next(code)
					lock.Lock()
					defer lock.Unlock()
					if !headerWritten {
						m.Code = code
						headerWritten = true
					}
				}
			},

			Write: func(next WriteFunc) WriteFunc {
				return func(p []byte) (int, error) {
					n, err := next(p)
					lock.Lock()
					defer lock.Unlock()
					m.Written += int64(n)
					headerWritten = true
					return n, err
				}
			},

			ReadFrom: func(next ReadFromFunc) ReadFromFunc {
				return func(src io.Reader) (int64, error) {
					n, err := next(src)
					lock.Lock()
					defer lock.Unlock()
					headerWritten = true
					m.Written += n
					return n, err
				}
			},
		}
	)

	fn(Wrap(w, hooks))
	m.Duration = time.Since(start)
	return m
}
func CaptureMetricsFn ( w http . ResponseWriter , fn func ( http . ResponseWriter ) ) Metrics { var ( start = time . Now ( ) m = Metrics { Code : http . StatusOK } headerWritten bool lock sync . Mutex hooks = Hooks { WriteHeader : func ( next WriteHeaderFunc ) WriteHeaderFunc { return func ( code int ) { next ( code ) lock . Lock ( ) defer lock . Unlock ( ) if ! headerWritten { m . Code = code headerWritten = true } } } , Write : func ( next WriteFunc ) WriteFunc { return func ( p [ ] byte ) ( int , error ) { n , err := next ( p ) lock . Lock ( ) defer lock . Unlock ( ) m . Written += int64 ( n ) headerWritten = true return n , err } } , ReadFrom : func ( next ReadFromFunc ) ReadFromFunc { return func ( src io . Reader ) ( int64 , error ) { n , err := next ( src ) lock . Lock ( ) defer lock . Unlock ( ) headerWritten = true m . Written += n return n , err } } , } ) fn ( Wrap ( w , hooks ) ) m . Duration = time . Since ( start ) return m }
// CaptureMetricsFn wraps w and calls fn with the wrapped w and returns the
// resulting metrics. This is very similar to CaptureMetrics (which is just
// sugar on top of this func), but is a more usable interface if your
// application doesn't use the Go http.Handler interface.
CaptureMetricsFn wraps w and calls fn with the wrapped w and returns the resulting metrics . This is very similar to CaptureMetrics ( which is just sugar on top of this func ) but is a more usable interface if your application doesn t use the Go http . Handler interface .