CaptureMetrics wraps w and calls fn with the wrapped w and updates Metrics m with the resulting metrics. This is similar to CaptureMetricsFn, but allows one to customize starting Metrics object.
(w http.ResponseWriter, fn func(http.ResponseWriter))
| 44 | // Metrics m with the resulting metrics. This is similar to CaptureMetricsFn, |
| 45 | // but allows one to customize starting Metrics object. |
| 46 | func (m *Metrics) CaptureMetrics(w http.ResponseWriter, fn func(http.ResponseWriter)) { |
| 47 | var ( |
| 48 | start = time.Now() |
| 49 | headerWritten bool |
| 50 | hooks = Hooks{ |
| 51 | WriteHeader: func(next WriteHeaderFunc) WriteHeaderFunc { |
| 52 | return func(code int) { |
| 53 | next(code) |
| 54 | |
| 55 | if !(code >= 100 && code <= 199) && !headerWritten { |
| 56 | m.Code = code |
| 57 | headerWritten = true |
| 58 | } |
| 59 | } |
| 60 | }, |
| 61 | |
| 62 | Write: func(next WriteFunc) WriteFunc { |
| 63 | return func(p []byte) (int, error) { |
| 64 | n, err := next(p) |
| 65 | |
| 66 | m.Written += int64(n) |
| 67 | headerWritten = true |
| 68 | return n, err |
| 69 | } |
| 70 | }, |
| 71 | |
| 72 | WriteString: func(next WriteStringFunc) WriteStringFunc { |
| 73 | return func(s string) (int, error) { |
| 74 | n, err := next(s) |
| 75 | |
| 76 | m.Written += int64(n) |
| 77 | headerWritten = true |
| 78 | return n, err |
| 79 | } |
| 80 | }, |
| 81 | |
| 82 | ReadFrom: func(next ReadFromFunc) ReadFromFunc { |
| 83 | return func(src io.Reader) (int64, error) { |
| 84 | n, err := next(src) |
| 85 | |
| 86 | headerWritten = true |
| 87 | m.Written += n |
| 88 | return n, err |
| 89 | } |
| 90 | }, |
| 91 | } |
| 92 | ) |
| 93 | |
| 94 | // defer to ensure duration is updated even if the handler panics |
| 95 | defer func() { |
| 96 | m.Duration += time.Since(start) |
| 97 | }() |
| 98 | fn(Wrap(w, hooks)) |
| 99 | } |
| 100 | |
| 101 | // deadliner defines two methods introduced in go 1.20. The standard library |
| 102 | // seems not to provide an interface we can import, hence its definition here. |