9
9
"go.opentelemetry.io/otel/attribute"
10
10
"go.opentelemetry.io/otel/metric/global"
11
11
"go.opentelemetry.io/otel/metric/instrument"
12
+ "go.opentelemetry.io/otel/metric/instrument/syncint64"
12
13
"go.opentelemetry.io/otel/metric/unit"
13
14
semconv "go.opentelemetry.io/otel/semconv/v1.7.0"
14
15
"google.golang.org/grpc"
@@ -20,6 +21,7 @@ import (
20
21
// See:
21
22
// https://github.com/open-telemetry/opentelemetry-specification/blob/main/specification/metrics
22
23
const (
24
+ serverRequestDurationMetricName = "rpc.server.duration"
23
25
clientRequestDurationMetricName = "rpc.client.duration"
24
26
25
27
// there is no rpc_count equivalent int OTEL semantic conventions yet.
@@ -30,23 +32,31 @@ const (
30
32
func NewMetricMiddleware () (MetricMiddleware , error ) {
31
33
meter := global .MeterProvider ().Meter ("cloudrunner-go/cloudmonitoring" )
32
34
33
- serverRequestCount , err := meter .Int64Counter (
35
+ serverRequestCount , err := meter .SyncInt64 (). Counter (
34
36
serverRequestCountMetricName ,
35
37
instrument .WithUnit (unit .Dimensionless ),
36
38
instrument .WithDescription ("Count of RPCs received by a gRPC server." ),
37
39
)
38
40
if err != nil {
39
41
return MetricMiddleware {}, fmt .Errorf ("create server request count counter: %w" , err )
40
42
}
41
- clientRequestCount , err := meter .Int64Counter (
43
+ serverRequestDuration , err := meter .SyncInt64 ().Histogram (
44
+ serverRequestDurationMetricName ,
45
+ instrument .WithUnit (unit .Milliseconds ),
46
+ instrument .WithDescription ("Duration of RPCs received by a gRPC server." ),
47
+ )
48
+ if err != nil {
49
+ return MetricMiddleware {}, fmt .Errorf ("create server request duration histogram: %w" , err )
50
+ }
51
+ clientRequestCount , err := meter .SyncInt64 ().Counter (
42
52
clientRequestCountMetricName ,
43
53
instrument .WithUnit (unit .Dimensionless ),
44
54
instrument .WithDescription ("Count of RPCs sent by a gRPC client." ),
45
55
)
46
56
if err != nil {
47
57
return MetricMiddleware {}, fmt .Errorf ("create client request count counter: %w" , err )
48
58
}
49
- clientRequestDuration , err := meter .Int64Histogram (
59
+ clientRequestDuration , err := meter .SyncInt64 (). Histogram (
50
60
clientRequestDurationMetricName ,
51
61
instrument .WithUnit (unit .Milliseconds ),
52
62
instrument .WithDescription ("Duration of RPCs sent by a gRPC client." ),
@@ -56,15 +66,17 @@ func NewMetricMiddleware() (MetricMiddleware, error) {
56
66
}
57
67
return MetricMiddleware {
58
68
serverRequestCount : serverRequestCount ,
69
+ serverRequestDuration : serverRequestDuration ,
59
70
clientRequestCount : clientRequestCount ,
60
71
clientRequestDuration : clientRequestDuration ,
61
72
}, nil
62
73
}
63
74
64
75
type MetricMiddleware struct {
65
- serverRequestCount instrument.Int64Counter
66
- clientRequestCount instrument.Int64Counter
67
- clientRequestDuration instrument.Int64Histogram
76
+ serverRequestCount syncint64.Counter
77
+ serverRequestDuration syncint64.Histogram
78
+ clientRequestCount syncint64.Counter
79
+ clientRequestDuration syncint64.Histogram
68
80
}
69
81
70
82
// GRPCUnaryServerInterceptor implements grpc.UnaryServerInterceptor and
@@ -76,11 +88,14 @@ func (m *MetricMiddleware) GRPCUnaryServerInterceptor(
76
88
info * grpc.UnaryServerInfo ,
77
89
handler grpc.UnaryHandler ,
78
90
) (resp interface {}, err error ) {
91
+ startTime := time .Now ()
79
92
response , err := handler (ctx , request )
93
+ duration := time .Since (startTime )
80
94
code := status .Code (err )
81
95
82
96
attrs := rpcAttrs (info .FullMethod , code )
83
97
m .serverRequestCount .Add (ctx , 1 , attrs ... )
98
+ m .serverRequestDuration .Record (ctx , duration .Milliseconds (), attrs ... )
84
99
return response , err
85
100
}
86
101
0 commit comments