forked from src-d/lookout-sdk
-
Notifications
You must be signed in to change notification settings - Fork 0
/
logger_interceptor.go
118 lines (88 loc) · 3.7 KB
/
logger_interceptor.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
package pb
import (
"context"
"path"
"time"
"google.golang.org/grpc"
)
// LogFn is the function used to log the messages
type LogFn func(fields Fields, format string, args ...interface{})
// LogUnaryServerInterceptor returns a new unary server interceptor that logs
// request/response.
func LogUnaryServerInterceptor(log LogFn) grpc.UnaryServerInterceptor {
return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
startTime := time.Now()
logCtx := buildServerRequestCtx(ctx, info.FullMethod)
log(GetLogFields(logCtx), "gRPC unary server call started")
resp, err := handler(ctx, req)
logCtx = buildResponseLoggerCtx(logCtx, startTime, err)
log(GetLogFields(logCtx), "gRPC unary server call finished")
return resp, err
}
}
// LogStreamServerInterceptor returns a new streaming server interceptor that
// logs request/response.
func LogStreamServerInterceptor(log LogFn) grpc.StreamServerInterceptor {
return func(srv interface{}, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
startTime := time.Now()
logCtx := buildServerRequestCtx(stream.Context(), info.FullMethod)
log(GetLogFields(logCtx), "gRPC streaming server call started")
err := handler(srv, stream)
logCtx = buildResponseLoggerCtx(logCtx, startTime, err)
log(GetLogFields(logCtx), "gRPC streaming server call finished")
return err
}
}
// LogUnaryClientInterceptor returns a new unary client interceptor that logs
// the execution of external gRPC calls.
func LogUnaryClientInterceptor(log LogFn) grpc.UnaryClientInterceptor {
return func(ctx context.Context, method string, req, reply interface{}, cc *grpc.ClientConn, invoker grpc.UnaryInvoker, opts ...grpc.CallOption) error {
startTime := time.Now()
logCtx := buildClientRequestCtx(ctx, method)
log(GetLogFields(logCtx), "gRPC unary client call started")
err := invoker(ctx, method, req, reply, cc, opts...)
logCtx = buildResponseLoggerCtx(logCtx, startTime, err)
log(GetLogFields(logCtx), "gRPC unary client call finished")
return err
}
}
// LogStreamClientInterceptor returns a new streaming client interceptor that
// logs the execution of external gRPC calls.
func LogStreamClientInterceptor(log LogFn) grpc.StreamClientInterceptor {
return func(ctx context.Context, desc *grpc.StreamDesc, cc *grpc.ClientConn, method string, streamer grpc.Streamer, opts ...grpc.CallOption) (grpc.ClientStream, error) {
startTime := time.Now()
logCtx := buildClientRequestCtx(ctx, method)
log(GetLogFields(logCtx), "gRPC streaming client call started")
clientStream, err := streamer(ctx, desc, cc, method, opts...)
logCtx = buildResponseLoggerCtx(ctx, startTime, err)
log(GetLogFields(logCtx), "gRPC streaming client call finished")
return clientStream, err
}
}
func buildServerRequestCtx(ctx context.Context, fullMethod string) context.Context {
return buildRequestCtx(ctx, "server", fullMethod)
}
func buildClientRequestCtx(ctx context.Context, fullMethod string) context.Context {
return buildRequestCtx(ctx, "client", fullMethod)
}
func buildRequestCtx(ctx context.Context, kind, fullMethod string) context.Context {
service := path.Dir(fullMethod)[1:]
method := path.Base(fullMethod)
return AddLogFields(ctx, Fields{
"system": "grpc",
"span.kind": kind,
"grpc.service": service,
"grpc.method": method,
})
}
func buildResponseLoggerCtx(ctx context.Context, startTime time.Time, err error) context.Context {
fields := Fields{
"grpc.start_time": startTime.Format(time.RFC3339),
"grpc.code": grpc.Code(err),
"duration": time.Now().Sub(startTime),
}
if err != nil {
fields["error"] = err
}
return AddLogFields(ctx, fields)
}