Skip to content

Commit 274df59

Browse files
authored
v2:interceptors/logging: add payload decision to separate request response payload logging (#442)
1 parent 7d56e76 commit 274df59

File tree

3 files changed

+87
-25
lines changed

3 files changed

+87
-25
lines changed

interceptors/logging/logging.go

Lines changed: 17 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -67,15 +67,29 @@ func DefaultDeciderMethod(_ string, _ error) Decision {
6767
return LogStartAndFinishCall
6868
}
6969

70+
// PayloadDecision defines rules for enabling payload logging of request and responses.
71+
type PayloadDecision int
72+
73+
const (
74+
// NoPayloadLogging - Payload logging is disabled.
75+
NoPayloadLogging PayloadDecision = iota
76+
// LogPayloadRequest - Only logging of requests is enabled.
77+
LogPayloadRequest
78+
// LogPayloadResponse - Only logging of responses is enabled.
79+
LogPayloadResponse
80+
// LogPayloadRequestAndResponse - Logging of both requests and responses is enabled.
81+
LogPayloadRequestAndResponse
82+
)
83+
7084
// ServerPayloadLoggingDecider is a user-provided function for deciding whether to log the server-side
7185
// request/response payloads
72-
type ServerPayloadLoggingDecider func(ctx context.Context, fullMethodName string, servingObject interface{}) bool
86+
type ServerPayloadLoggingDecider func(ctx context.Context, fullMethodName string, servingObject interface{}) PayloadDecision
7387

7488
// ClientPayloadLoggingDecider is a user-provided function for deciding whether to log the client-side
7589
// request/response payloads
76-
type ClientPayloadLoggingDecider func(ctx context.Context, fullMethodName string) bool
90+
type ClientPayloadLoggingDecider func(ctx context.Context, fullMethodName string) PayloadDecision
7791

78-
// JsonPbMarshaller is a marshaller that serializes protobuf messages.
92+
// JsonPbMarshaler is a marshaller that serializes protobuf messages.
7993
type JsonPbMarshaler interface {
8094
Marshal(pb proto.Message) ([]byte, error)
8195
}

interceptors/logging/payload.go

Lines changed: 64 additions & 20 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,9 @@ import (
1818
)
1919

2020
type serverPayloadReporter struct {
21-
ctx context.Context
22-
logger Logger
21+
ctx context.Context
22+
logger Logger
23+
decision PayloadDecision
2324
}
2425

2526
func (c *serverPayloadReporter) PostCall(error, time.Duration) {}
@@ -28,6 +29,11 @@ func (c *serverPayloadReporter) PostMsgSend(req interface{}, err error, duration
2829
if err != nil {
2930
return
3031
}
32+
switch c.decision {
33+
case LogPayloadResponse, LogPayloadRequestAndResponse:
34+
default:
35+
return
36+
}
3137

3238
logger := c.logger.With(extractFields(tags.Extract(c.ctx))...)
3339
p, ok := req.(proto.Message)
@@ -44,6 +50,11 @@ func (c *serverPayloadReporter) PostMsgReceive(reply interface{}, err error, dur
4450
if err != nil {
4551
return
4652
}
53+
switch c.decision {
54+
case LogPayloadRequest, LogPayloadRequestAndResponse:
55+
default:
56+
return
57+
}
4758

4859
logger := c.logger.With(extractFields(tags.Extract(c.ctx))...)
4960

@@ -57,8 +68,9 @@ func (c *serverPayloadReporter) PostMsgReceive(reply interface{}, err error, dur
5768
}
5869

5970
type clientPayloadReporter struct {
60-
ctx context.Context
61-
logger Logger
71+
ctx context.Context
72+
logger Logger
73+
decision PayloadDecision
6274
}
6375

6476
func (c *clientPayloadReporter) PostCall(error, time.Duration) {}
@@ -67,6 +79,11 @@ func (c *clientPayloadReporter) PostMsgSend(req interface{}, err error, duration
6779
if err != nil {
6880
return
6981
}
82+
switch c.decision {
83+
case LogPayloadRequest, LogPayloadRequestAndResponse:
84+
default:
85+
return
86+
}
7087

7188
logger := c.logger.With(extractFields(tags.Extract(c.ctx))...)
7289
p, ok := req.(proto.Message)
@@ -81,6 +98,11 @@ func (c *clientPayloadReporter) PostMsgReceive(reply interface{}, err error, dur
8198
if err != nil {
8299
return
83100
}
101+
switch c.decision {
102+
case LogPayloadResponse, LogPayloadRequestAndResponse:
103+
default:
104+
return
105+
}
84106

85107
logger := c.logger.With(extractFields(tags.Extract(c.ctx))...)
86108
p, ok := reply.(proto.Message)
@@ -98,8 +120,10 @@ type payloadReportable struct {
98120
timestampFormat string
99121
}
100122

101-
func (r *payloadReportable) ServerReporter(ctx context.Context, req interface{}, typ interceptors.GRPCType, service string, method string) (interceptors.Reporter, context.Context) {
102-
if !r.serverDecider(ctx, interceptors.FullMethod(service, method), req) {
123+
func (r *payloadReportable) ServerReporter(ctx context.Context, req interface{}, typ interceptors.GRPCType,
124+
service string, method string) (interceptors.Reporter, context.Context) {
125+
decision := r.serverDecider(ctx, interceptors.FullMethod(service, method), req)
126+
if decision == NoPayloadLogging {
103127
return interceptors.NoopReporter{}, ctx
104128
}
105129
fields := commonFields(KindServerFieldValue, typ, service, method)
@@ -108,12 +132,15 @@ func (r *payloadReportable) ServerReporter(ctx context.Context, req interface{},
108132
fields = append(fields, "grpc.request.deadline", d.Format(r.timestampFormat))
109133
}
110134
return &serverPayloadReporter{
111-
ctx: ctx,
112-
logger: r.logger.With(fields...),
135+
ctx: ctx,
136+
logger: r.logger.With(fields...),
137+
decision: decision,
113138
}, ctx
114139
}
115-
func (r *payloadReportable) ClientReporter(ctx context.Context, _ interface{}, typ interceptors.GRPCType, service string, method string) (interceptors.Reporter, context.Context) {
116-
if !r.clientDecider(ctx, interceptors.FullMethod(service, method)) {
140+
func (r *payloadReportable) ClientReporter(ctx context.Context, _ interface{}, typ interceptors.GRPCType,
141+
service string, method string) (interceptors.Reporter, context.Context) {
142+
decision := r.clientDecider(ctx, interceptors.FullMethod(service, method))
143+
if decision == NoPayloadLogging {
117144
return interceptors.NoopReporter{}, ctx
118145
}
119146
fields := commonFields(KindClientFieldValue, typ, service, method)
@@ -122,33 +149,50 @@ func (r *payloadReportable) ClientReporter(ctx context.Context, _ interface{}, t
122149
fields = append(fields, "grpc.request.deadline", d.Format(r.timestampFormat))
123150
}
124151
return &clientPayloadReporter{
125-
ctx: ctx,
126-
logger: r.logger.With(fields...),
152+
ctx: ctx,
153+
logger: r.logger.With(fields...),
154+
decision: decision,
127155
}, ctx
128156
}
129157

130158
// PayloadUnaryServerInterceptor returns a new unary server interceptors that logs the payloads of requests on INFO level.
131159
// Logger tags will be used from tags context.
132-
func PayloadUnaryServerInterceptor(logger Logger, decider ServerPayloadLoggingDecider, timestampFormat string) grpc.UnaryServerInterceptor {
133-
return interceptors.UnaryServerInterceptor(&payloadReportable{logger: logger, serverDecider: decider, timestampFormat: timestampFormat})
160+
func PayloadUnaryServerInterceptor(logger Logger, decider ServerPayloadLoggingDecider,
161+
timestampFormat string) grpc.UnaryServerInterceptor {
162+
return interceptors.UnaryServerInterceptor(&payloadReportable{
163+
logger: logger,
164+
serverDecider: decider,
165+
timestampFormat: timestampFormat})
134166
}
135167

136168
// PayloadStreamServerInterceptor returns a new server server interceptors that logs the payloads of requests on INFO level.
137169
// Logger tags will be used from tags context.
138-
func PayloadStreamServerInterceptor(logger Logger, decider ServerPayloadLoggingDecider, timestampFormat string) grpc.StreamServerInterceptor {
139-
return interceptors.StreamServerInterceptor(&payloadReportable{logger: logger, serverDecider: decider, timestampFormat: timestampFormat})
170+
func PayloadStreamServerInterceptor(logger Logger, decider ServerPayloadLoggingDecider,
171+
timestampFormat string) grpc.StreamServerInterceptor {
172+
return interceptors.StreamServerInterceptor(&payloadReportable{
173+
logger: logger,
174+
serverDecider: decider,
175+
timestampFormat: timestampFormat})
140176
}
141177

142178
// PayloadUnaryClientInterceptor returns a new unary client interceptor that logs the payloads of requests and responses on INFO level.
143179
// Logger tags will be used from tags context.
144-
func PayloadUnaryClientInterceptor(logger Logger, decider ClientPayloadLoggingDecider, timestampFormat string) grpc.UnaryClientInterceptor {
145-
return interceptors.UnaryClientInterceptor(&payloadReportable{logger: logger, clientDecider: decider, timestampFormat: timestampFormat})
180+
func PayloadUnaryClientInterceptor(logger Logger, decider ClientPayloadLoggingDecider,
181+
timestampFormat string) grpc.UnaryClientInterceptor {
182+
return interceptors.UnaryClientInterceptor(&payloadReportable{
183+
logger: logger,
184+
clientDecider: decider,
185+
timestampFormat: timestampFormat})
146186
}
147187

148188
// PayloadStreamClientInterceptor returns a new streaming client interceptor that logs the paylods of requests and responses on INFO level.
149189
// Logger tags will be used from tags context.
150-
func PayloadStreamClientInterceptor(logger Logger, decider ClientPayloadLoggingDecider, timestampFormat string) grpc.StreamClientInterceptor {
151-
return interceptors.StreamClientInterceptor(&payloadReportable{logger: logger, clientDecider: decider, timestampFormat: timestampFormat})
190+
func PayloadStreamClientInterceptor(logger Logger, decider ClientPayloadLoggingDecider,
191+
timestampFormat string) grpc.StreamClientInterceptor {
192+
return interceptors.StreamClientInterceptor(&payloadReportable{
193+
logger: logger,
194+
clientDecider: decider,
195+
timestampFormat: timestampFormat})
152196
}
153197

154198
func logProtoMessageAsJson(logger Logger, pbMsg proto.Message, key string, msg string) {

interceptors/logging/payload_test.go

Lines changed: 6 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,12 @@ type loggingPayloadSuite struct {
2727
}
2828

2929
func TestPayloadSuite(t *testing.T) {
30-
alwaysLoggingDeciderServer := func(ctx context.Context, fullMethodName string, servingObject interface{}) bool { return true }
31-
alwaysLoggingDeciderClient := func(ctx context.Context, fullMethodName string) bool { return true }
30+
alwaysLoggingDeciderServer := func(context.Context, string, interface{}) logging.PayloadDecision {
31+
return logging.LogPayloadRequestAndResponse
32+
}
33+
alwaysLoggingDeciderClient := func(context.Context, string) logging.PayloadDecision {
34+
return logging.LogPayloadRequestAndResponse
35+
}
3236

3337
s := &loggingPayloadSuite{
3438
baseLoggingSuite: &baseLoggingSuite{

0 commit comments

Comments
 (0)