2020-07-22 23:57:29 +00:00
|
|
|
package grpc
|
|
|
|
|
|
|
|
import (
|
|
|
|
"context"
|
|
|
|
"sync/atomic"
|
|
|
|
|
|
|
|
"github.com/armon/go-metrics"
|
2020-11-13 02:12:12 +00:00
|
|
|
"github.com/armon/go-metrics/prometheus"
|
2020-07-22 23:57:29 +00:00
|
|
|
"google.golang.org/grpc"
|
|
|
|
"google.golang.org/grpc/stats"
|
|
|
|
)
|
|
|
|
|
2020-11-13 02:12:12 +00:00
|
|
|
var StatsGauges = []prometheus.GaugeDefinition{
|
|
|
|
{
|
2020-11-13 21:18:04 +00:00
|
|
|
Name: []string{"grpc", "server", "connections"},
|
2020-11-16 19:02:11 +00:00
|
|
|
Help: "Measures the number of active gRPC connections open on the server.",
|
2020-11-13 02:12:12 +00:00
|
|
|
},
|
|
|
|
{
|
2020-11-13 21:18:04 +00:00
|
|
|
Name: []string{"grpc", "client", "connections"},
|
2020-11-16 19:02:11 +00:00
|
|
|
Help: "Measures the number of active gRPC connections open from the client agent to any Consul servers.",
|
2020-11-13 02:12:12 +00:00
|
|
|
},
|
|
|
|
{
|
2020-11-13 21:18:04 +00:00
|
|
|
Name: []string{"grpc", "server", "streams"},
|
2020-11-16 19:02:11 +00:00
|
|
|
Help: "Measures the number of active gRPC streams handled by the server.",
|
2020-11-13 02:12:12 +00:00
|
|
|
},
|
|
|
|
}
|
|
|
|
var StatsCounters = []prometheus.CounterDefinition{
|
|
|
|
{
|
2020-11-13 21:18:04 +00:00
|
|
|
Name: []string{"grpc", "client", "request", "count"},
|
2020-11-16 19:02:11 +00:00
|
|
|
Help: "Counts the number of gRPC requests made by the client agent to a Consul server.",
|
2020-11-13 02:12:12 +00:00
|
|
|
},
|
|
|
|
{
|
2020-11-13 21:18:04 +00:00
|
|
|
Name: []string{"grpc", "server", "request", "count"},
|
2020-11-16 19:02:11 +00:00
|
|
|
Help: "Counts the number of gRPC requests received by the server.",
|
2020-11-13 02:12:12 +00:00
|
|
|
},
|
|
|
|
{
|
2020-11-13 21:18:04 +00:00
|
|
|
Name: []string{"grpc", "client", "connection", "count"},
|
2020-11-16 19:02:11 +00:00
|
|
|
Help: "Counts the number of new gRPC connections opened by the client agent to a Consul server.",
|
2020-11-13 02:12:12 +00:00
|
|
|
},
|
|
|
|
{
|
2020-11-13 21:18:04 +00:00
|
|
|
Name: []string{"grpc", "server", "connection", "count"},
|
2020-11-16 19:02:11 +00:00
|
|
|
Help: "Counts the number of new gRPC connections received by the server.",
|
2020-11-13 02:12:12 +00:00
|
|
|
},
|
|
|
|
{
|
2020-11-13 21:18:04 +00:00
|
|
|
Name: []string{"grpc", "server", "stream", "count"},
|
2020-11-16 19:02:11 +00:00
|
|
|
Help: "Counts the number of new gRPC streams received by the server.",
|
2020-11-13 02:12:12 +00:00
|
|
|
},
|
|
|
|
}
|
2020-09-14 17:16:13 +00:00
|
|
|
|
2020-11-11 19:27:07 +00:00
|
|
|
var defaultMetrics = metrics.Default
|
2020-09-14 17:16:13 +00:00
|
|
|
|
2020-07-22 23:57:29 +00:00
|
|
|
// statsHandler is a grpc/stats.StatsHandler which emits connection and
|
|
|
|
// request metrics to go-metrics.
|
|
|
|
type statsHandler struct {
|
2020-09-14 17:16:13 +00:00
|
|
|
metrics *metrics.Metrics
|
2020-07-22 23:57:29 +00:00
|
|
|
activeConns uint64 // must be 8-byte aligned for atomic access
|
|
|
|
}
|
|
|
|
|
2020-10-14 19:43:48 +00:00
|
|
|
func newStatsHandler(m *metrics.Metrics) *statsHandler {
|
|
|
|
return &statsHandler{metrics: m}
|
2020-09-14 17:16:13 +00:00
|
|
|
}
|
|
|
|
|
2020-07-22 23:57:29 +00:00
|
|
|
// 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:
|
2020-10-15 20:40:33 +00:00
|
|
|
c.metrics.IncrCounter([]string{"grpc", label, "request", "count"}, 1)
|
2020-07-22 23:57:29 +00:00
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
// 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)
|
2020-10-15 20:40:33 +00:00
|
|
|
c.metrics.IncrCounter([]string{"grpc", label, "connection", "count"}, 1)
|
2020-07-22 23:57:29 +00:00
|
|
|
case *stats.ConnEnd:
|
|
|
|
// Decrement!
|
|
|
|
count = atomic.AddUint64(&c.activeConns, ^uint64(0))
|
|
|
|
}
|
2020-10-15 20:29:09 +00:00
|
|
|
c.metrics.SetGauge([]string{"grpc", label, "connections"}, float32(count))
|
2020-07-22 23:57:29 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
type activeStreamCounter struct {
|
2020-10-14 19:43:48 +00:00
|
|
|
metrics *metrics.Metrics
|
2020-07-22 23:57:29 +00:00
|
|
|
// 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)
|
2020-10-15 20:29:09 +00:00
|
|
|
i.metrics.SetGauge([]string{"grpc", "server", "streams"}, float32(count))
|
2020-10-15 20:40:33 +00:00
|
|
|
i.metrics.IncrCounter([]string{"grpc", "server", "stream", "count"}, 1)
|
2020-07-22 23:57:29 +00:00
|
|
|
defer func() {
|
|
|
|
count := atomic.AddUint64(&i.count, ^uint64(0))
|
2020-10-15 20:29:09 +00:00
|
|
|
i.metrics.SetGauge([]string{"grpc", "server", "streams"}, float32(count))
|
2020-07-22 23:57:29 +00:00
|
|
|
}()
|
|
|
|
|
|
|
|
return handler(srv, ss)
|
|
|
|
}
|