gitee.com/ks-custle/core-gm@v0.0.0-20230922171213-b83bdd97b62c/go-grpc-middleware/logging/zap/server_interceptors.go (about)

     1  package grpc_zap
     2  
     3  import (
     4  	"path"
     5  	"time"
     6  
     7  	grpc_middleware "gitee.com/ks-custle/core-gm/go-grpc-middleware"
     8  	"gitee.com/ks-custle/core-gm/go-grpc-middleware/logging/zap/ctxzap"
     9  	ctx_zap "gitee.com/ks-custle/core-gm/go-grpc-middleware/tags/zap"
    10  	"gitee.com/ks-custle/core-gm/grpc"
    11  	"gitee.com/ks-custle/core-gm/net/context"
    12  	"go.uber.org/zap"
    13  	"go.uber.org/zap/zapcore"
    14  )
    15  
    16  var (
    17  	// SystemField is used in every log statement made through grpc_zap. Can be overwritten before any initialization code.
    18  	SystemField = zap.String("system", "grpc")
    19  
    20  	// ServerField is used in every server-side log statement made through grpc_zap.Can be overwritten before initialization.
    21  	ServerField = zap.String("span.kind", "server")
    22  )
    23  
    24  // UnaryServerInterceptor returns a new unary server interceptors that adds zap.Logger to the context.
    25  func UnaryServerInterceptor(logger *zap.Logger, opts ...Option) grpc.UnaryServerInterceptor {
    26  	o := evaluateServerOpt(opts)
    27  	return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
    28  		startTime := time.Now()
    29  
    30  		newCtx := newLoggerForCall(ctx, logger, info.FullMethod, startTime)
    31  
    32  		resp, err := handler(newCtx, req)
    33  		if !o.shouldLog(info.FullMethod, err) {
    34  			return resp, err
    35  		}
    36  		code := o.codeFunc(err)
    37  		level := o.levelFunc(code)
    38  
    39  		// re-extract logger from newCtx, as it may have extra fields that changed in the holder.
    40  		ctx_zap.Extract(newCtx).Check(level, "finished unary call with code "+code.String()).Write(
    41  			zap.Error(err),
    42  			zap.String("grpc.code", code.String()),
    43  			o.durationFunc(time.Since(startTime)),
    44  		)
    45  
    46  		return resp, err
    47  	}
    48  }
    49  
    50  // StreamServerInterceptor returns a new streaming server interceptor that adds zap.Logger to the context.
    51  func StreamServerInterceptor(logger *zap.Logger, opts ...Option) grpc.StreamServerInterceptor {
    52  	o := evaluateServerOpt(opts)
    53  	return func(srv interface{}, stream grpc.ServerStream, info *grpc.StreamServerInfo, handler grpc.StreamHandler) error {
    54  		startTime := time.Now()
    55  		newCtx := newLoggerForCall(stream.Context(), logger, info.FullMethod, startTime)
    56  		wrapped := grpc_middleware.WrapServerStream(stream)
    57  		wrapped.WrappedContext = newCtx
    58  
    59  		err := handler(srv, wrapped)
    60  		if !o.shouldLog(info.FullMethod, err) {
    61  			return err
    62  		}
    63  		code := o.codeFunc(err)
    64  		level := o.levelFunc(code)
    65  
    66  		// re-extract logger from newCtx, as it may have extra fields that changed in the holder.
    67  		ctx_zap.Extract(newCtx).Check(level, "finished streaming call with code "+code.String()).Write(
    68  			zap.Error(err),
    69  			zap.String("grpc.code", code.String()),
    70  			o.durationFunc(time.Since(startTime)),
    71  		)
    72  
    73  		return err
    74  	}
    75  }
    76  
    77  func serverCallFields(fullMethodString string) []zapcore.Field {
    78  	service := path.Dir(fullMethodString)[1:]
    79  	method := path.Base(fullMethodString)
    80  	return []zapcore.Field{
    81  		SystemField,
    82  		ServerField,
    83  		zap.String("grpc.service", service),
    84  		zap.String("grpc.method", method),
    85  	}
    86  }
    87  
    88  func newLoggerForCall(ctx context.Context, logger *zap.Logger, fullMethodString string, start time.Time) context.Context {
    89  	f := ctxzap.TagsToFields(ctx)
    90  	f = append(f, zap.String("grpc.start_time", start.Format(time.RFC3339)))
    91  	if d, ok := ctx.Deadline(); ok {
    92  		f = append(f, zap.String("grpc.request.deadline", d.Format(time.RFC3339)))
    93  	}
    94  	callLog := logger.With(append(f, serverCallFields(fullMethodString)...)...)
    95  	return ctxzap.ToContext(ctx, callLog)
    96  }