@@ -108,6 +108,40 @@ func InstrumentHandlerCounter(counter *prometheus.CounterVec, next http.Handler)
108
108
})
109
109
}
110
110
111
+ // InstrumentHandlerTimeToWriteHeader is a middleware that wraps the provided
112
+ // http.Handler to observe with the provided ObserverVec the request duration
113
+ // until the response headers are written. The ObserverVec must have zero, one,
114
+ // or two labels. The only allowed label names are "code" and "method". The
115
+ // function panics if any other instance labels are provided. The Observe
116
+ // method of the Observer in the ObserverVec is called with the request
117
+ // duration in seconds. Partitioning happens by HTTP status code and/or HTTP
118
+ // method if the respective instance label names are present in the
119
+ // ObserverVec. For unpartitioned observations, use an ObserverVec with zero
120
+ // labels. Note that partitioning of Histograms is expensive and should be used
121
+ // judiciously.
122
+ //
123
+ // If the wrapped Handler does not set a status code via WriteHeader, no value
124
+ // is reported.
125
+ //
126
+ // If the wrapped Handler panics before calling WriteHeader, no value is
127
+ // reported.
128
+ //
129
+ // See the example for InstrumentHandlerDuration for example usage.
130
+ func InstrumentHandlerTimeToWriteHeader (obs prometheus.ObserverVec , next http.Handler ) http.HandlerFunc {
131
+ code , method := checkLabels (obs )
132
+
133
+ return http .HandlerFunc (func (w http.ResponseWriter , r * http.Request ) {
134
+ now := time .Now ()
135
+ d := & wroteHeaderDelegator {
136
+ delegator : newDelegator (w ),
137
+ observeWriteHeader : func (status int ) {
138
+ obs .With (labels (code , method , r .Method , status )).Observe (time .Since (now ).Seconds ())
139
+ },
140
+ }
141
+ next .ServeHTTP (d , r )
142
+ })
143
+ }
144
+
111
145
// InstrumentHandlerRequestSize is a middleware that wraps the provided
112
146
// http.Handler to observe the request size with the provided ObserverVec.
113
147
// The ObserverVec must have zero, one, or two labels. The only allowed label
@@ -415,6 +449,19 @@ type delegator interface {
415
449
http.ResponseWriter
416
450
}
417
451
452
+ type wroteHeaderDelegator struct {
453
+ observeWriteHeader func (int )
454
+
455
+ delegator
456
+ }
457
+
458
+ func (r * wroteHeaderDelegator ) WriteHeader (code int ) {
459
+ r .delegator .WriteHeader (code )
460
+ if r .observeWriteHeader != nil {
461
+ r .observeWriteHeader (code )
462
+ }
463
+ }
464
+
418
465
type responseWriterDelegator struct {
419
466
http.ResponseWriter
420
467
0 commit comments