-
Notifications
You must be signed in to change notification settings - Fork 4.4k
/
stats.go
129 lines (116 loc) · 3.69 KB
/
stats.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
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
package grpc
import (
"context"
"sync/atomic"
"github.com/armon/go-metrics"
"github.com/armon/go-metrics/prometheus"
"google.golang.org/grpc"
"google.golang.org/grpc/stats"
)
var StatsGauges = []prometheus.GaugeDefinition{
{
Name: []string{"grpc", "server", "connections"},
Help: "Measures the number of active gRPC connections open on the server.",
},
{
Name: []string{"grpc", "client", "connections"},
Help: "Measures the number of active gRPC connections open from the client agent to any Consul servers.",
},
{
Name: []string{"grpc", "server", "streams"},
Help: "Measures the number of active gRPC streams handled by the server.",
},
}
var StatsCounters = []prometheus.CounterDefinition{
{
Name: []string{"grpc", "client", "request", "count"},
Help: "Counts the number of gRPC requests made by the client agent to a Consul server.",
},
{
Name: []string{"grpc", "server", "request", "count"},
Help: "Counts the number of gRPC requests received by the server.",
},
{
Name: []string{"grpc", "client", "connection", "count"},
Help: "Counts the number of new gRPC connections opened by the client agent to a Consul server.",
},
{
Name: []string{"grpc", "server", "connection", "count"},
Help: "Counts the number of new gRPC connections received by the server.",
},
{
Name: []string{"grpc", "server", "stream", "count"},
Help: "Counts the number of new gRPC streams received by the server.",
},
}
var defaultMetrics = metrics.Default
// statsHandler is a grpc/stats.StatsHandler which emits connection and
// request metrics to go-metrics.
type statsHandler struct {
metrics *metrics.Metrics
activeConns uint64 // must be 8-byte aligned for atomic access
}
func newStatsHandler(m *metrics.Metrics) *statsHandler {
return &statsHandler{metrics: m}
}
// TagRPC implements grpcStats.StatsHandler
func (c *statsHandler) TagRPC(ctx context.Context, _ *stats.RPCTagInfo) context.Context {
// No-op
return ctx
}
// HandleRPC implements grpcStats.StatsHandler
func (c *statsHandler) HandleRPC(_ context.Context, s stats.RPCStats) {
label := "server"
if s.IsClient() {
label = "client"
}
switch s.(type) {
case *stats.InHeader:
c.metrics.IncrCounter([]string{"grpc", label, "request", "count"}, 1)
}
}
// TagConn implements grpcStats.StatsHandler
func (c *statsHandler) TagConn(ctx context.Context, _ *stats.ConnTagInfo) context.Context {
// No-op
return ctx
}
// HandleConn implements grpcStats.StatsHandler
func (c *statsHandler) HandleConn(_ context.Context, s stats.ConnStats) {
label := "server"
if s.IsClient() {
label = "client"
}
var count uint64
switch s.(type) {
case *stats.ConnBegin:
count = atomic.AddUint64(&c.activeConns, 1)
c.metrics.IncrCounter([]string{"grpc", label, "connection", "count"}, 1)
case *stats.ConnEnd:
// Decrement!
count = atomic.AddUint64(&c.activeConns, ^uint64(0))
}
c.metrics.SetGauge([]string{"grpc", label, "connections"}, float32(count))
}
type activeStreamCounter struct {
metrics *metrics.Metrics
// count of the number of open streaming RPCs on a server. It is accessed
// atomically.
count uint64
}
// GRPCCountingStreamInterceptor is a grpc.ServerStreamInterceptor that emits a
// a metric of the count of open streams.
func (i *activeStreamCounter) Intercept(
srv interface{},
ss grpc.ServerStream,
_ *grpc.StreamServerInfo,
handler grpc.StreamHandler,
) error {
count := atomic.AddUint64(&i.count, 1)
i.metrics.SetGauge([]string{"grpc", "server", "streams"}, float32(count))
i.metrics.IncrCounter([]string{"grpc", "server", "stream", "count"}, 1)
defer func() {
count := atomic.AddUint64(&i.count, ^uint64(0))
i.metrics.SetGauge([]string{"grpc", "server", "streams"}, float32(count))
}()
return handler(srv, ss)
}