/
request_metrics.go
66 lines (55 loc) · 1.68 KB
/
request_metrics.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
package xhttp
import (
"net/http"
"strconv"
"time"
"github.com/go-phorce/dolly/metrics"
"github.com/go-phorce/dolly/metrics/tags"
"github.com/go-phorce/dolly/xhttp/identity"
)
// a http.Handler that records execution metrics of the wrapper handler
type requestMetrics struct {
handler http.Handler
responseCodes []string
}
// NewRequestMetrics creates a wrapper handler to produce metrics for each request
func NewRequestMetrics(h http.Handler) http.Handler {
rm := requestMetrics{
handler: h,
responseCodes: make([]string, 599),
}
for idx := range rm.responseCodes {
rm.responseCodes[idx] = strconv.Itoa(idx)
}
return &rm
}
func (rm *requestMetrics) statusCode(statusCode int) string {
if (statusCode < len(rm.responseCodes)) && (statusCode > 0) {
return rm.responseCodes[statusCode]
}
return strconv.Itoa(statusCode)
}
var (
keyForHTTPReqPerf = []string{"http", "request", "perf"}
keyForHTTPReqSuccessful = []string{"http", "request", "status", "successful"}
keyForHTTPReqFailed = []string{"http", "request", "status", "failed"}
)
func (rm *requestMetrics) ServeHTTP(w http.ResponseWriter, r *http.Request) {
start := time.Now().UTC()
rc := NewResponseCapture(w)
rm.handler.ServeHTTP(rc, r)
role := identity.FromRequest(r).Identity().Role()
sc := rc.StatusCode()
tags := []metrics.Tag{
{Name: tags.Method, Value: r.Method},
{Name: tags.Role, Value: role},
{Name: tags.Status, Value: rm.statusCode(sc)},
{Name: tags.URI, Value: r.URL.Path},
}
metrics.MeasureSince(keyForHTTPReqPerf, start, tags...)
if sc >= 400 {
metrics.IncrCounter(keyForHTTPReqFailed, 1, tags...)
} else {
metrics.IncrCounter(keyForHTTPReqSuccessful, 1, tags...)
}
}