@@ -50,40 +50,27 @@ func UnaryClientInterceptor(logger logger, opts ...Option) grpc.UnaryClientInter
5050 return func (ctx context.Context , method string , req , reply any , cc * grpc.ClientConn , invoker grpc.UnaryInvoker , callOpts ... grpc.CallOption ) (err error ) {
5151 t := time .Now ()
5252 o := newOpts (opts ... )
53- newCtx := ctx
54- attrs := []any {}
55- if o .logMethod {
56- attrs = append (attrs , "grpc.method" , method )
57- }
58- if o .logRequest {
59- attrs = append (attrs , "grpc.request" , req )
60- }
61- if len (attrs ) > 0 {
62- logger .Log (newCtx , slog .LevelInfo , "sent grpc request" , attrs ... )
63- }
64- if o .logResponse {
65- defer func () {
66- attrs := []any {}
67- if o .logMethod {
68- attrs = append (attrs , "grpc.method" , method )
69- }
70- attrs = append (attrs , "grpc.response" , reply )
71- attrs = append (attrs , "grpc.error" , err )
72- if o .logDuration {
73- attrs = append (attrs , "grpc.duration" , time .Since (t ).String ())
74- }
75-
76- logger .Log (newCtx , slog .LevelInfo , "received grpc response" , attrs ... )
77- }()
78- }
53+ logRequest (logger , ctx , "sent grpc request" , o , method , req )
54+ defer func () {
55+ logResponse (logger , ctx , "received grpc response" , o , method , reply , err , time .Since (t ))
56+ }()
7957 return invoker (ctx , method , req , reply , cc , callOpts ... )
8058 }
8159}
8260
61+ // StreamClientInterceptor returns a gRPC stream client interceptor that logs stream creation.
62+ // It uses the provided logger to log messages when a stream is created.
63+ // The behavior of the interceptor can be customized using options such as logging the method name and duration.
8364func StreamClientInterceptor (logger logger , opts ... Option ) grpc.StreamClientInterceptor {
84- return func (ctx context.Context , desc * grpc.StreamDesc , cc * grpc.ClientConn , method string , streamer grpc.Streamer , callOpts ... grpc.CallOption ) (grpc.ClientStream , error ) {
85- // TODO implement logging for streaming RPCs
86- return streamer (ctx , desc , cc , method , callOpts ... )
65+ return func (ctx context.Context , desc * grpc.StreamDesc , cc * grpc.ClientConn , method string , streamer grpc.Streamer , callOpts ... grpc.CallOption ) (stream grpc.ClientStream , err error ) {
66+ t := time .Now ()
67+ o := newOpts (opts ... )
68+ logRequest (logger , ctx , "creating grpc client stream" , o , method , nil )
69+ defer func () {
70+ logResponse (logger , ctx , "created grpc client stream" , o , method , nil , err , time .Since (t ))
71+ }()
72+ stream , err = streamer (ctx , desc , cc , method , callOpts ... )
73+ return stream , err
8774 }
8875}
8976
@@ -95,41 +82,29 @@ func UnaryServerInterceptor(logger logger, opts ...Option) grpc.UnaryServerInter
9582 return func (ctx context.Context , req any , info * grpc.UnaryServerInfo , handler grpc.UnaryHandler ) (res any , err error ) {
9683 t := time .Now ()
9784 o := newOpts (opts ... )
98- newCtx := ctx
99- attrs := []any {}
100- if o .logMethod {
101- attrs = append (attrs , "grpc.method" , info .FullMethod )
102- }
103- if o .logRequest {
104- attrs = append (attrs , "grpc.request" , req )
105- }
106- if len (attrs ) > 0 {
107- logger .Log (newCtx , slog .LevelInfo , "received grpc request" , attrs ... )
108- }
109- if o .logResponse {
110- defer func () {
111- attrs := []any {}
112- if o .logMethod {
113- attrs = append (attrs , "grpc.method" , info .FullMethod )
114- }
115- attrs = append (attrs , "grpc.response" , res )
116- attrs = append (attrs , "grpc.error" , err )
117- if o .logDuration {
118- attrs = append (attrs , "grpc.duration" , time .Since (t ).String ())
119- }
120-
121- logger .Log (newCtx , slog .LevelInfo , "sent grpc response" , attrs ... )
122- }()
123- }
124- res , err = handler (newCtx , req )
85+ logRequest (logger , ctx , "received grpc request" , o , info .FullMethod , req )
86+ defer func () {
87+ logResponse (logger , ctx , "sent grpc response" , o , info .FullMethod , res , err , time .Since (t ))
88+ }()
89+ res , err = handler (ctx , req )
12590 return res , err
12691 }
12792}
12893
94+ // StreamServerInterceptor returns a gRPC stream server interceptor that logs stream creation.
95+ // It uses the provided logger to log messages when a stream is created.
96+ // The behavior of the interceptor can be customized using options such as logging the method name and duration.
12997func StreamServerInterceptor (logger logger , opts ... Option ) grpc.StreamServerInterceptor {
130- return func (srv any , ss grpc.ServerStream , info * grpc.StreamServerInfo , handler grpc.StreamHandler ) error {
131- // TODO implement logging for streaming RPCs
132- return handler (srv , ss )
98+ return func (srv any , ss grpc.ServerStream , info * grpc.StreamServerInfo , handler grpc.StreamHandler ) (err error ) {
99+ t := time .Now ()
100+ o := newOpts (opts ... )
101+ ctx := ss .Context ()
102+ logRequest (logger , ctx , "creating grpc server stream" , o , info .FullMethod , nil )
103+ defer func () {
104+ logResponse (logger , ctx , "created grpc server stream" , o , info .FullMethod , nil , err , time .Since (t ))
105+ }()
106+ err = handler (srv , ss )
107+ return err
133108 }
134109}
135110
@@ -167,3 +142,29 @@ func contextLogger(appendToContext AppendToContextFunc, metaFunc func(ctx contex
167142 return newCtx , nil
168143 }
169144}
145+
146+ // logRequest logs the initial request with the specified method and request data.
147+ func logRequest (logger logger , ctx context.Context , msg string , o * options , method string , req any ) {
148+ attrs := []any {}
149+ if o .logMethod {
150+ attrs = append (attrs , "grpc.method" , method )
151+ }
152+ if o .logRequest {
153+ attrs = append (attrs , "grpc.request" , req )
154+ }
155+ logger .Log (ctx , slog .LevelInfo , msg , attrs ... )
156+ }
157+
158+ // logResponse logs the response with the specified method, response data, error, and duration.
159+ func logResponse (logger logger , ctx context.Context , msg string , o * options , method string , res any , err error , duration time.Duration ) {
160+ attrs := []any {}
161+ if o .logMethod {
162+ attrs = append (attrs , "grpc.method" , method )
163+ }
164+ attrs = append (attrs , "grpc.response" , res )
165+ attrs = append (attrs , "grpc.error" , err )
166+ if o .logDuration {
167+ attrs = append (attrs , "grpc.duration" , duration .String ())
168+ }
169+ logger .Log (ctx , slog .LevelInfo , msg , attrs ... )
170+ }
0 commit comments