-
Notifications
You must be signed in to change notification settings - Fork 0
/
middleware.go
76 lines (58 loc) · 2.31 KB
/
middleware.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
package middleware_metric
import (
"context"
"time"
"github.com/pubgo/funk/generic"
"github.com/pubgo/funk/running"
"github.com/uber-go/tally/v4"
"github.com/pubgo/lava/core/metrics"
"github.com/pubgo/lava/lava"
)
// grpc metric
// ref: https://github.com/grpc-ecosystem/go-grpc-middleware/blob/v2/providers/openmetrics/server_metrics.go
// https://github.com/grpc-ecosystem/go-grpc-middleware/blob/v2/providers/openmetrics/server_options.go
var requestDurationBucket = tally.DurationBuckets{100 * time.Millisecond, 300 * time.Millisecond, 1200 * time.Millisecond, 5000 * time.Millisecond, 10000 * time.Millisecond}
// Total number of rpc call started on the server.
func grpcServerRpcCallTotal(m metrics.Metric, method string) {
m.Tagged(metrics.Tags{"method": method}).Counter("grpc_server_rpc_total").Inc(1)
}
// Total number of rpc call failed.
func grpcServerRpcErrTotal(m metrics.Metric, method string) {
m.Tagged(metrics.Tags{"method": method}).Counter("grpc_server_rpc_failed_total").Inc(1)
}
// Histogram of response latency (seconds) of gRPC that had been application-level handled by the server.
func grpcServerHandlingSecondsCount(m metrics.Metric, method string, val time.Duration) {
m.Tagged(metrics.Tags{"method": method}).
Histogram("grpc_server_handling_seconds_count", requestDurationBucket).
RecordDuration(val)
}
func New(m metrics.Metric) *MetricMiddleware {
return &MetricMiddleware{m: m}
}
var _ lava.Middleware = (*MetricMiddleware)(nil)
type MetricMiddleware struct {
m metrics.Metric
}
func (m MetricMiddleware) String() string { return "metric" }
func (m MetricMiddleware) Middleware(next lava.HandlerFunc) lava.HandlerFunc {
return func(ctx context.Context, req lava.Request) (rsp lava.Response, gErr error) {
now := time.Now()
grpcServerRpcCallTotal(m.m, req.Operation())
clientInfo := lava.GetClientInfo(ctx)
if !req.Client() && clientInfo != nil {
m.m.Tagged(metrics.Tags{
"server_name": running.Project,
"server_method": req.Operation(),
"client_name": clientInfo.GetName(),
"client_method": clientInfo.GetPath(),
}).Counter("grpc_server_info").Inc(1)
}
defer func() {
if !generic.IsNil(gErr) {
grpcServerRpcErrTotal(m.m, req.Operation())
}
grpcServerHandlingSecondsCount(m.m, req.Operation(), time.Since(now))
}()
return next(ctx, req)
}
}