code: func UnaryServerInterceptor(logger *zap.Logger, opts ...Option) grpc.UnaryServerInterceptor {
  	o := evaluateServerOpt(opts)
  	return func(ctx context.Context, req interface{}, info *grpc.UnaryServerInfo, handler grpc.UnaryHandler) (interface{}, error) {
  		startTime := time.Now()
  
  		newCtx := newLoggerForCall(ctx, logger, info.FullMethod, startTime)
  
  		resp, err := handler(newCtx, req)
  		if !o.shouldLog(info.FullMethod, err) {
  			return resp, err
  		}
  		code := o.codeFunc(err)
  		level := o.levelFunc(code)
  
  		// re-extract logger from newCtx, as it may have extra fields that changed in the holder.
  		ctx_zap.Extract(newCtx).Check(level, "finished unary call with code "+code.String()).Write(
  			zap.Error(err),
  			zap.String("grpc.code", code.String()),
  			o.durationFunc(time.Since(startTime)),
  		)
  
  		return resp, err
  	}
  }
docs: // UnaryServerInterceptor returns a new unary server interceptors that adds zap.Logger to the context.