...
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15 package baseapp
16
17 import (
18 "context"
19 "net/http"
20 "runtime"
21 "time"
22
23 "github.com/rcrowley/go-metrics"
24 )
25
26 const (
27 MetricsKeyRequests = "server.requests"
28 MetricsKeyRequests2xx = "server.requests.2xx"
29 MetricsKeyRequests3xx = "server.requests.3xx"
30 MetricsKeyRequests4xx = "server.requests.4xx"
31 MetricsKeyRequests5xx = "server.requests.5xx"
32
33 MetricsKeyNumGoroutines = "server.goroutines"
34 MetricsKeyMemoryUsed = "server.mem.used"
35 )
36
37 type metricsCtxKey struct{}
38
39
40
41 func MetricsCtx(ctx context.Context) metrics.Registry {
42 if r, ok := ctx.Value(metricsCtxKey{}).(metrics.Registry); ok {
43 return r
44 }
45 return metrics.DefaultRegistry
46 }
47
48
49 func WithMetricsCtx(ctx context.Context, registry metrics.Registry) context.Context {
50 return context.WithValue(ctx, metricsCtxKey{}, registry)
51 }
52
53
54
55
56 func RegisterDefaultMetrics(registry metrics.Registry) {
57 for _, key := range []string{
58 MetricsKeyRequests,
59 MetricsKeyRequests2xx,
60 MetricsKeyRequests3xx,
61 MetricsKeyRequests4xx,
62 MetricsKeyRequests5xx,
63 } {
64 metrics.GetOrRegisterCounter(key, registry)
65 }
66
67 registry.GetOrRegister(MetricsKeyNumGoroutines, func() metrics.Gauge {
68 return metrics.NewFunctionalGauge(func() int64 {
69 return int64(runtime.NumGoroutine())
70 })
71 })
72
73 registry.GetOrRegister(MetricsKeyMemoryUsed, func() metrics.Gauge {
74 return metrics.NewFunctionalGauge(func() int64 {
75 var m runtime.MemStats
76 runtime.ReadMemStats(&m)
77 return int64(m.Alloc)
78 })
79 })
80 }
81
82
83 func CountRequest(r *http.Request, status int, _ int64, _ time.Duration) {
84 registry := MetricsCtx(r.Context())
85
86 if c := registry.Get(MetricsKeyRequests); c != nil {
87 c.(metrics.Counter).Inc(1)
88 }
89
90 if key := bucketStatus(status); key != "" {
91 if c := registry.Get(key); c != nil {
92 c.(metrics.Counter).Inc(1)
93 }
94 }
95 }
96
97 func bucketStatus(status int) string {
98 switch {
99 case status >= 200 && status < 300:
100 return MetricsKeyRequests2xx
101 case status >= 300 && status < 400:
102 return MetricsKeyRequests3xx
103 case status >= 400 && status < 500:
104 return MetricsKeyRequests4xx
105 case status >= 500 && status < 600:
106 return MetricsKeyRequests5xx
107 }
108 return ""
109 }
110
View as plain text