Skip to content

Commit 339ba92

Browse files
committed
middleware(prometheus): add http_requests_in_flight metric
Fixes #453
1 parent e3a6034 commit 339ba92

File tree

3 files changed

+26
-4
lines changed

3 files changed

+26
-4
lines changed

http_proxy.go

+5
Original file line numberDiff line numberDiff line change
@@ -374,6 +374,11 @@ func (hp *HTTPProxy) middlewareStack() (martian.RequestResponseModifier, *martia
374374
stack.AddResponseModifier(p)
375375

376376
trace = new(martian.ProxyTrace)
377+
trace.ReadRequest = func(info martian.ReadRequestInfo) {
378+
if info.Req != nil {
379+
p.ReadRequest(info.Req)
380+
}
381+
}
377382
trace.WroteResponse = func(info martian.WroteResponseInfo) {
378383
if info.Res != nil {
379384
p.WroteResponse(info.Res)

middleware/prometheus.go

+18-4
Original file line numberDiff line numberDiff line change
@@ -40,10 +40,11 @@ var sizeBuckets = []float64{ //nolint:gochecknoglobals // this is a global varia
4040
// Unlike the promhttp.InstrumentHandler* chaining, this middleware creates only one delegator per request.
4141
// It partitions the metrics by HTTP status code, HTTP method, destination host name and source IP.
4242
type Prometheus struct {
43-
requestsTotal *prometheus.CounterVec
44-
requestDuration *prometheus.HistogramVec
45-
requestSize *prometheus.HistogramVec
46-
responseSize *prometheus.HistogramVec
43+
requestsInFlight *prometheus.GaugeVec
44+
requestsTotal *prometheus.CounterVec
45+
requestDuration *prometheus.HistogramVec
46+
requestSize *prometheus.HistogramVec
47+
responseSize *prometheus.HistogramVec
4748
}
4849

4950
func NewPrometheus(r prometheus.Registerer, namespace string) *Prometheus {
@@ -54,6 +55,11 @@ func NewPrometheus(r prometheus.Registerer, namespace string) *Prometheus {
5455
l := []string{"code", "method"}
5556

5657
return &Prometheus{
58+
requestsInFlight: f.NewGaugeVec(prometheus.GaugeOpts{
59+
Namespace: namespace,
60+
Name: "http_requests_in_flight",
61+
Help: "Current number of HTTP requests being served.",
62+
}, []string{"method"}),
5763
requestsTotal: f.NewCounterVec(prometheus.CounterOpts{
5864
Namespace: namespace,
5965
Name: "http_requests_total",
@@ -82,6 +88,8 @@ func NewPrometheus(r prometheus.Registerer, namespace string) *Prometheus {
8288

8389
func (p *Prometheus) Wrap(h http.Handler) http.Handler {
8490
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
91+
p.requestsInFlight.WithLabelValues(r.Method).Inc()
92+
8593
d := newDelegator(w, nil)
8694

8795
r.Body = bodyCounter(r.Body)
@@ -100,6 +108,7 @@ func (p *Prometheus) Wrap(h http.Handler) http.Handler {
100108
reqSize = c.Count()
101109
}
102110

111+
p.requestsInFlight.WithLabelValues(r.Method).Dec()
103112
p.requestSize.WithLabelValues(lv[:]...).Observe(float64(reqSize))
104113
p.responseSize.WithLabelValues(lv[:]...).Observe(float64(d.Written()))
105114
})
@@ -115,12 +124,17 @@ func (p *Prometheus) ModifyResponse(res *http.Response) error {
115124
return nil
116125
}
117126

127+
func (p *Prometheus) ReadRequest(req *http.Request) {
128+
p.requestsInFlight.WithLabelValues(req.Method).Inc()
129+
}
130+
118131
func (p *Prometheus) WroteResponse(res *http.Response) {
119132
elapsed := martian.ContextDuration(res.Request.Context()).Seconds()
120133

121134
req := res.Request
122135
lv := [2]string{strconv.Itoa(res.StatusCode), req.Method}
123136

137+
p.requestsInFlight.WithLabelValues(req.Method).Dec()
124138
p.requestsTotal.WithLabelValues(lv[:]...).Inc()
125139
p.requestDuration.WithLabelValues(lv[:]...).Observe(elapsed)
126140

middleware/testdata/TestPrometheusWrap.golden.txt

+3
Original file line numberDiff line numberDiff line change
@@ -29,6 +29,9 @@ test_http_request_size_bytes_bucket{code="200",method="GET",le="1.048576e+07"} 4
2929
test_http_request_size_bytes_bucket{code="200",method="GET",le="+Inf"} 4
3030
test_http_request_size_bytes_sum{code="200",method="GET"} 0
3131
test_http_request_size_bytes_count{code="200",method="GET"} 4
32+
# HELP test_http_requests_in_flight Current number of HTTP requests being served.
33+
# TYPE test_http_requests_in_flight gauge
34+
test_http_requests_in_flight{method="GET"} 0
3235
# HELP test_http_requests_total Total number of HTTP requests processed.
3336
# TYPE test_http_requests_total counter
3437
test_http_requests_total{code="200",method="GET"} 4

0 commit comments

Comments
 (0)