浏览代码

HUE-8523 [jb] Display Impala backends & instances

jdesjean 7 年之前
父节点
当前提交
e201177

+ 30 - 0
apps/impala/src/impala/server.py

@@ -251,3 +251,33 @@ class ImpalaDaemonApi(object):
         return resp
     except ValueError, e:
       raise ImpalaDaemonApiException('ImpalaDaemonApi kill did not return valid JSON: %s' % e)
+
+  def get_query_backends(self, query_id):
+    params = {
+      'query_id': query_id,
+      'json': 'true'
+    }
+
+    resp = self._root.get('query_backends', params=params)
+    try:
+      if isinstance(resp, basestring):
+        return json.loads(resp)
+      else:
+        return resp
+    except ValueError, e:
+      raise ImpalaDaemonApiException('ImpalaDaemonApi query_backends did not return valid JSON: %s' % e)
+
+  def get_query_finstances(self, query_id):
+    params = {
+      'query_id': query_id,
+      'json': 'true'
+    }
+
+    resp = self._root.get('query_finstances', params=params)
+    try:
+      if isinstance(resp, basestring):
+        return json.loads(resp)
+      else:
+        return resp
+    except ValueError, e:
+      raise ImpalaDaemonApiException('ImpalaDaemonApi query_finstances did not return valid JSON: %s' % e)

+ 13 - 2
apps/jobbrowser/src/jobbrowser/apis/query_api.py

@@ -122,13 +122,14 @@ class QueryApi(Api):
       'properties': {
         'memory': '',
         'profile': '',
-        'plan': ''
+        'plan': '',
+        'backends': '',
+        'finstances': ''
       }
     })
 
     return app
 
-
   def action(self, appid, action):
     message = {'message': '', 'status': 0}
 
@@ -153,6 +154,10 @@ class QueryApi(Api):
       return self._memory(appid, app_type, app_property, app_filters)
     elif app_property == 'profile':
       return self._query_profile(appid)
+    elif app_property == 'backends':
+      return self._query_backends(appid)
+    elif app_property == 'finstances':
+      return self._query_finstances(appid)
     else:
       return self._query(appid)
 
@@ -168,6 +173,12 @@ class QueryApi(Api):
   def _query_profile(self, appid):
     return self.api.get_query_profile(query_id=appid)
 
+  def _query_backends(self, appid):
+    return self.api.get_query_backends(query_id=appid)
+
+  def _query_finstances(self, appid):
+    return self.api.get_query_finstances(query_id=appid)
+
   def _api_status_filter(self, status):
     if status == 'FINISHED':
       return 'COMPLETED'

+ 1 - 1
apps/jobbrowser/src/jobbrowser/static/jobbrowser/css/jobbrowser-embeddable.css

@@ -14,4 +14,4 @@ distributed under the License is distributed on an "AS IS" BASIS,
 WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
 See the License for the specific language governing permissions and
 limitations under the License.
- */.jobbrowser-mini .span12.no-margin{margin-left:0 !important}.jobbrowser-full .content-panel-inner{padding:10px}.jobbrowser-full .jb-breadcrumbs{margin-bottom:0}.jobbrowser-full .jb-panel{padding-left:10px;padding-right:10px}.jobbrowser-components .hue-uncheck::before{padding-left:2px}.jobbrowser-components .tab-content{padding:10px;border:none !important}.jobbrowser-components .hue-breadcrumbs-bar{padding:0}.jobbrowser-components .hue-breadcrumbs-bar li{padding:12px}.jobbrowser-components .hue-breadcrumbs-bar li:first-child{padding-left:0;padding-right:0}.jobbrowser-components .hue-breadcrumbs-bar a{color:#0B7FAD !important;display:inline !important}.jobbrowser-components .divider{color:#C8C8C8;padding-right:12px}.jobbrowser-components .app-icon{vertical-align:text-top}.jobbrowser-components .sidebar-nav .progress{margin-bottom:0}.jobbrowser-components .sidebar-nav .nav-list>li>a{margin-top:0 !important;margin-bottom:0 !important}.jobbrowser-components .sidebar-nav .nav-list li:not(.nav-header){text-overflow:ellipsis;overflow-x:hidden;white-space:nowrap}.jobbrowser-components .query-plan{border:1px solid #DCDCDC}.jobbrowser-components .node rect{stroke:#DCDCDC;fill:#FFFFFF}.jobbrowser-components .edgePath path{stroke:#424242;fill:#424242;stroke-width:1.5px}
+ */.jobbrowser-mini .span12.no-margin{margin-left:0 !important}.jobbrowser-full .content-panel-inner{padding:10px}.jobbrowser-full .jb-breadcrumbs{margin-bottom:0}.jobbrowser-full .jb-panel{padding-left:10px;padding-right:10px}.jobbrowser-components .hue-uncheck::before{padding-left:2px}.jobbrowser-components .tab-content{padding:10px;border:none !important}.jobbrowser-components .hue-breadcrumbs-bar{padding:0}.jobbrowser-components .hue-breadcrumbs-bar li{padding:12px}.jobbrowser-components .hue-breadcrumbs-bar li:first-child{padding-left:0;padding-right:0}.jobbrowser-components .hue-breadcrumbs-bar a{color:#0B7FAD !important;display:inline !important}.jobbrowser-components .divider{color:#C8C8C8;padding-right:12px}.jobbrowser-components .app-icon{vertical-align:text-top}.jobbrowser-components .sidebar-nav .progress{margin-bottom:0}.jobbrowser-components .sidebar-nav .nav-list>li>a{margin-top:0 !important;margin-bottom:0 !important}.jobbrowser-components .sidebar-nav .nav-list li:not(.nav-header){text-overflow:ellipsis;overflow-x:hidden;white-space:nowrap}.jobbrowser-components .query-plan{border:1px solid #DCDCDC}.jobbrowser-components .node rect{stroke:#DCDCDC;fill:#FFFFFF}.jobbrowser-components .edgePath path{stroke:#424242;fill:#424242;stroke-width:1.5px}.jobbrowser-components div[data-jobType="queries"] pre{overflow-x:auto;white-space:pre}

+ 5 - 0
apps/jobbrowser/src/jobbrowser/static/jobbrowser/less/jobbrowser-embeddable.less

@@ -103,4 +103,9 @@
     fill: @cui-gray-800;
     stroke-width: 1.5px;
   }
+
+  div[data-jobType="queries"] pre {
+    overflow-x: auto;
+    white-space: pre;
+  }
 }

+ 58 - 0
apps/jobbrowser/src/jobbrowser/templates/job_browser.mako

@@ -1181,6 +1181,14 @@ ${ commonheader("Job Browser", "jobbrowser", user, request) | n,unicode }
           <a href="#queries-page-memory${ SUFFIX }" data-bind="click: function(){ $('a[href=\'#queries-page-memory${ SUFFIX }\']').tab('show'); }, event: {'shown': function () { if (!properties.memory || !properties.memory().mem_usage) { fetchProfile('memory'); } } }">
             ${ _('Memory') }</a>
         </li>
+        <li>
+          <a href="#queries-page-backends${ SUFFIX }" data-bind="click: function(){ $('a[href=\'#queries-page-backends${ SUFFIX }\']').tab('show'); }, event: {'shown': function () { if (!properties.backends || !properties.backends().backend_states) { fetchProfile('backends'); } } }">
+            ${ _('Backends') }</a>
+        </li>
+        <li>
+          <a href="#queries-page-finstances${ SUFFIX }" data-bind="click: function(){ $('a[href=\'#queries-page-finstances${ SUFFIX }\']').tab('show'); }, event: {'shown': function () { if (!properties.finstances || !properties.finstances().backend_instances) { fetchProfile('finstances'); } } }">
+            ${ _('Instances') }</a>
+        </li>
       </ul>
 
       <div class="clearfix"></div>
@@ -1211,6 +1219,56 @@ ${ commonheader("Job Browser", "jobbrowser", user, request) | n,unicode }
         <div class="tab-pane" id="queries-page-memory${ SUFFIX }" data-profile="mem_usage">
           <pre data-bind="text: (properties.memory && properties.memory().mem_usage) || _('The selected tab has no data')"/>
         </div>
+        <div class="tab-pane" id="queries-page-backends${ SUFFIX }" data-profile="backends">
+          <!-- ko if: properties.backends && properties.backends().backend_states -->
+          <div id="queries-page-memory-backends-template${ SUFFIX }" style="overflow-x: scroll;">
+            <table class="table table-condensed">
+              <thead>
+              <tr>
+                <!-- ko foreach: Object.keys(properties.backends().backend_states[0]).sort() -->
+                <th data-bind="text: $data"></th>
+                <!-- /ko -->
+              </tr>
+              </thead>
+              <tbody data-bind="foreach: { data: $data.properties.backends().backend_states, minHeight: 20, container: '#queries-page-memory-backends-template${ SUFFIX }'}">
+                <tr>
+                  <!-- ko foreach: Object.keys($data).sort() -->
+                  <td data-bind="text: $parent[$data]"></td>
+                  <!-- /ko -->
+                </tr>
+              </tbody>
+            </table>
+          </div>
+          <!-- /ko -->
+          <!-- ko if: !properties.backends || !properties.backends().backend_states -->
+          <pre data-bind="text: _('The selected tab has no data')"/>
+          <!-- /ko -->
+        </div>
+        <div class="tab-pane" id="queries-page-finstances${ SUFFIX }" data-profile="finstances">
+          <!-- ko if: properties.finstances && properties.finstances().backend_instances -->
+          <div id="queries-page-memory-finstances-template${ SUFFIX }" style="overflow-x: scroll;">
+            <table class="table table-condensed">
+              <thead>
+              <tr>
+                <!-- ko foreach: [_('host')].concat(Object.keys($data.properties.finstances().backend_instances[0].instance_stats[0])).sort() -->
+                <th data-bind="text: $data"></th>
+                <!-- /ko -->
+              </tr>
+              </thead>
+              <tbody data-bind="foreach: { data: $data.properties.finstances().backend_instances.reduce( function(arr, instance) { instance.instance_stats.forEach(function(stats) { stats.host = instance.host; }); return arr.concat(instance.instance_stats); }, []), minHeight: 20, container: '#queries-page-memory-finstances-template${ SUFFIX }'}">
+                <tr>
+                  <!-- ko foreach: Object.keys($data).sort() -->
+                  <td data-bind="text: $parent[$data]"></td>
+                  <!-- /ko -->
+                </tr>
+              </tbody>
+            </table>
+          </div>
+          <!-- /ko -->
+          <!-- ko if: !properties.finstances || !properties.finstances().backend_instances -->
+          <pre data-bind="text: _('The selected tab has no data')"/>
+          <!-- /ko -->
+        </div>
       </div>
     </div>
     <!-- /ko -->

文件差异内容过多而无法显示
+ 0 - 0
desktop/core/src/desktop/static/desktop/css/hue-embedded.css


文件差异内容过多而无法显示
+ 0 - 0
desktop/core/src/desktop/static/desktop/css/hue.css


+ 5 - 1
desktop/core/src/desktop/static/desktop/less/hue4.less

@@ -709,7 +709,7 @@ a:visited {
 }
 
 #mini_jobbrowser {
-  overflow-y: auto;
+  overflow-y: hidden;
   height: 550px;
   max-height: 550px;
   input.search-query {
@@ -730,6 +730,10 @@ a:visited {
   }
 }
 
+#mini_jobbrowser:hover {
+  overflow-y: overlay;
+}
+
 .uploadstatus {
   border: 1px solid @cui-gray-300;
   border-bottom: none;

+ 1 - 1
desktop/core/src/desktop/templates/ko_components/ko_job_browser_links.mako

@@ -155,7 +155,7 @@ from desktop.views import _ko
           success: function (response) {
             params.onePageViewModel.processHeaders(response).done(function (rawHtml) {
               $('#mini_jobbrowser').html(rawHtml);
-              ko.bindingHandlers.delayedOverflow.init($('#mini_jobbrowser')[0]);
+              //ko.bindingHandlers.delayedOverflow.init($('#mini_jobbrowser')[0]);
             });
           }
         });

部分文件因为文件数量过多而无法显示