Skip to content

Commit

Permalink
Support customization of timestamp format (v2 branch) (#399)
Browse files Browse the repository at this point in the history
This ports #398 to the v2 branch.
  • Loading branch information
stanhu authored Apr 23, 2021
1 parent f60016a commit b81999a
Show file tree
Hide file tree
Showing 4 changed files with 33 additions and 23 deletions.
4 changes: 2 additions & 2 deletions interceptors/logging/interceptors.go
Original file line number Diff line number Diff line change
Expand Up @@ -90,9 +90,9 @@ func (r *reportable) ClientReporter(ctx context.Context, _ interface{}, typ inte

func (r *reportable) reporter(ctx context.Context, typ interceptors.GRPCType, service string, method string, kind string) (interceptors.Reporter, context.Context) {
fields := commonFields(kind, typ, service, method)
fields = append(fields, "grpc.start_time", time.Now().Format(time.RFC3339))
fields = append(fields, "grpc.start_time", time.Now().Format(r.opts.timestampFormat))
if d, ok := ctx.Deadline(); ok {
fields = append(fields, "grpc.request.deadline", d.Format(time.RFC3339))
fields = append(fields, "grpc.request.deadline", d.Format(r.opts.timestampFormat))
}
return &reporter{
ctx: ctx,
Expand Down
11 changes: 10 additions & 1 deletion interceptors/logging/options.go
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ var (
codeFunc: DefaultErrorToCode,
durationFieldFunc: DefaultDurationToFields,
// levelFunc depends if it's client or server.
levelFunc: nil,
levelFunc: nil,
timestampFormat: time.RFC3339,
}
)

Expand All @@ -20,6 +21,7 @@ type options struct {
shouldLog Decider
codeFunc ErrorToCode
durationFieldFunc DurationToFields
timestampFormat string
}

type Option func(*options)
Expand Down Expand Up @@ -92,3 +94,10 @@ func DurationToDurationField(duration time.Duration) Fields {
func durationToMilliseconds(duration time.Duration) float32 {
return float32(duration.Nanoseconds()/1000) / 1000
}

// WithTimestampFormat customizes the timestamps emitted in the log fields.
func WithTimestampFormat(format string) Option {
return func(o *options) {
o.timestampFormat = format
}
}
33 changes: 17 additions & 16 deletions interceptors/logging/payload.go
Original file line number Diff line number Diff line change
Expand Up @@ -89,19 +89,20 @@ func (c *clientPayloadReporter) PostMsgReceive(reply interface{}, err error, dur
}

type payloadReportable struct {
clientDecider ClientPayloadLoggingDecider
serverDecider ServerPayloadLoggingDecider
logger Logger
clientDecider ClientPayloadLoggingDecider
serverDecider ServerPayloadLoggingDecider
logger Logger
timestampFormat string
}

func (r *payloadReportable) ServerReporter(ctx context.Context, req interface{}, typ interceptors.GRPCType, service string, method string) (interceptors.Reporter, context.Context) {
if !r.serverDecider(ctx, interceptors.FullMethod(service, method), req) {
return interceptors.NoopReporter{}, ctx
}
fields := commonFields(KindServerFieldValue, typ, service, method)
fields = append(fields, "grpc.start_time", time.Now().Format(time.RFC3339))
fields = append(fields, "grpc.start_time", time.Now().Format(r.timestampFormat))
if d, ok := ctx.Deadline(); ok {
fields = append(fields, "grpc.request.deadline", d.Format(time.RFC3339))
fields = append(fields, "grpc.request.deadline", d.Format(r.timestampFormat))
}
return &serverPayloadReporter{
ctx: ctx,
Expand All @@ -113,9 +114,9 @@ func (r *payloadReportable) ClientReporter(ctx context.Context, _ interface{}, t
return interceptors.NoopReporter{}, ctx
}
fields := commonFields(KindClientFieldValue, typ, service, method)
fields = append(fields, "grpc.start_time", time.Now().Format(time.RFC3339))
fields = append(fields, "grpc.start_time", time.Now().Format(r.timestampFormat))
if d, ok := ctx.Deadline(); ok {
fields = append(fields, "grpc.request.deadline", d.Format(time.RFC3339))
fields = append(fields, "grpc.request.deadline", d.Format(r.timestampFormat))
}
return &clientPayloadReporter{
ctx: ctx,
Expand All @@ -125,26 +126,26 @@ func (r *payloadReportable) ClientReporter(ctx context.Context, _ interface{}, t

// PayloadUnaryServerInterceptor returns a new unary server interceptors that logs the payloads of requests on INFO level.
// Logger tags will be used from tags context.
func PayloadUnaryServerInterceptor(logger Logger, decider ServerPayloadLoggingDecider) grpc.UnaryServerInterceptor {
return interceptors.UnaryServerInterceptor(&payloadReportable{logger: logger, serverDecider: decider})
func PayloadUnaryServerInterceptor(logger Logger, decider ServerPayloadLoggingDecider, timestampFormat string) grpc.UnaryServerInterceptor {
return interceptors.UnaryServerInterceptor(&payloadReportable{logger: logger, serverDecider: decider, timestampFormat: timestampFormat})
}

// PayloadStreamServerInterceptor returns a new server server interceptors that logs the payloads of requests on INFO level.
// Logger tags will be used from tags context.
func PayloadStreamServerInterceptor(logger Logger, decider ServerPayloadLoggingDecider) grpc.StreamServerInterceptor {
return interceptors.StreamServerInterceptor(&payloadReportable{logger: logger, serverDecider: decider})
func PayloadStreamServerInterceptor(logger Logger, decider ServerPayloadLoggingDecider, timestampFormat string) grpc.StreamServerInterceptor {
return interceptors.StreamServerInterceptor(&payloadReportable{logger: logger, serverDecider: decider, timestampFormat: timestampFormat})
}

// PayloadUnaryClientInterceptor returns a new unary client interceptor that logs the paylods of requests and responses on INFO level.
// PayloadUnaryClientInterceptor returns a new unary client interceptor that logs the payloads of requests and responses on INFO level.
// Logger tags will be used from tags context.
func PayloadUnaryClientInterceptor(logger Logger, decider ClientPayloadLoggingDecider) grpc.UnaryClientInterceptor {
return interceptors.UnaryClientInterceptor(&payloadReportable{logger: logger, clientDecider: decider})
func PayloadUnaryClientInterceptor(logger Logger, decider ClientPayloadLoggingDecider, timestampFormat string) grpc.UnaryClientInterceptor {
return interceptors.UnaryClientInterceptor(&payloadReportable{logger: logger, clientDecider: decider, timestampFormat: timestampFormat})
}

// PayloadStreamClientInterceptor returns a new streaming client interceptor that logs the paylods of requests and responses on INFO level.
// Logger tags will be used from tags context.
func PayloadStreamClientInterceptor(logger Logger, decider ClientPayloadLoggingDecider) grpc.StreamClientInterceptor {
return interceptors.StreamClientInterceptor(&payloadReportable{logger: logger, clientDecider: decider})
func PayloadStreamClientInterceptor(logger Logger, decider ClientPayloadLoggingDecider, timestampFormat string) grpc.StreamClientInterceptor {
return interceptors.StreamClientInterceptor(&payloadReportable{logger: logger, clientDecider: decider, timestampFormat: timestampFormat})
}

func logProtoMessageAsJson(logger Logger, pbMsg proto.Message, key string, msg string) {
Expand Down
8 changes: 4 additions & 4 deletions interceptors/logging/payload_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -36,16 +36,16 @@ func TestPayloadSuite(t *testing.T) {
},
}
s.InterceptorTestSuite.ClientOpts = []grpc.DialOption{
grpc.WithUnaryInterceptor(logging.PayloadUnaryClientInterceptor(s.logger, alwaysLoggingDeciderClient)),
grpc.WithStreamInterceptor(logging.PayloadStreamClientInterceptor(s.logger, alwaysLoggingDeciderClient)),
grpc.WithUnaryInterceptor(logging.PayloadUnaryClientInterceptor(s.logger, alwaysLoggingDeciderClient, time.RFC3339)),
grpc.WithStreamInterceptor(logging.PayloadStreamClientInterceptor(s.logger, alwaysLoggingDeciderClient, time.RFC3339)),
}
s.InterceptorTestSuite.ServerOpts = []grpc.ServerOption{
grpc.ChainStreamInterceptor(
tags.StreamServerInterceptor(tags.WithFieldExtractor(tags.CodeGenRequestFieldExtractor)),
logging.PayloadStreamServerInterceptor(s.logger, alwaysLoggingDeciderServer)),
logging.PayloadStreamServerInterceptor(s.logger, alwaysLoggingDeciderServer, time.RFC3339)),
grpc.ChainUnaryInterceptor(
tags.UnaryServerInterceptor(tags.WithFieldExtractor(tags.CodeGenRequestFieldExtractor)),
logging.PayloadUnaryServerInterceptor(s.logger, alwaysLoggingDeciderServer)),
logging.PayloadUnaryServerInterceptor(s.logger, alwaysLoggingDeciderServer, time.RFC3339)),
}
suite.Run(t, s)
}
Expand Down

0 comments on commit b81999a

Please sign in to comment.