-
Notifications
You must be signed in to change notification settings - Fork 622
/
metrics.go
87 lines (72 loc) · 2.09 KB
/
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
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
// Package metrics constructs the metrics the application will track.
package metrics
import (
"context"
"expvar"
"runtime"
)
// This holds the single instance of the metrics value needed for
// collecting metrics. The expvar package is already based on a singleton
// for the different metrics that are registered with the package so there
// isn't much choice here.
var m metrics
// metrics represents the set of metrics we gather. These fields are
// safe to be accessed concurrently thanks to expvar. No extra abstraction is required.
type metrics struct {
goroutines *expvar.Int
requests *expvar.Int
errors *expvar.Int
panics *expvar.Int
}
// init constructs the metrics value that will be used to capture metrics.
// The metrics value is stored in a package level variable since everything
// inside of expvar is registered as a singleton. The use of once will make
// sure this initialization only happens once.
func init() {
m = metrics{
goroutines: expvar.NewInt("goroutines"),
requests: expvar.NewInt("requests"),
errors: expvar.NewInt("errors"),
panics: expvar.NewInt("panics"),
}
}
type ctxKey int
const key ctxKey = 1
// Set sets the metrics data into the context.
func Set(ctx context.Context) context.Context {
return context.WithValue(ctx, key, &m)
}
// AddGoroutines refreshes the goroutine metric.
func AddGoroutines(ctx context.Context) int64 {
if v, ok := ctx.Value(key).(*metrics); ok {
g := int64(runtime.NumGoroutine())
v.goroutines.Set(g)
return g
}
return 0
}
// AddRequests increments the request metric by 1.
func AddRequests(ctx context.Context) int64 {
v, ok := ctx.Value(key).(*metrics)
if ok {
v.requests.Add(1)
return v.requests.Value()
}
return 0
}
// AddErrors increments the errors metric by 1.
func AddErrors(ctx context.Context) int64 {
if v, ok := ctx.Value(key).(*metrics); ok {
v.errors.Add(1)
return v.errors.Value()
}
return 0
}
// AddPanics increments the panics metric by 1.
func AddPanics(ctx context.Context) int64 {
if v, ok := ctx.Value(key).(*metrics); ok {
v.panics.Add(1)
return v.panics.Value()
}
return 0
}