소스 검색

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]);
             });
           }
         });

이 변경점에서 너무 많은 파일들이 변경되어 몇몇 파일들은 표시되지 않았습니다.