浏览代码

AMBARI-2799. YARN service summary additional information. (onechiporenko via srimanth)

Srimanth Gunturi 12 年之前
父节点
当前提交
3728dedd62

+ 24 - 0
ambari-web/app/mappers/service_mapper.js

@@ -105,6 +105,10 @@ App.servicesMapper = App.QuickDataMapper.create({
     node_managers_count_unhealthy: 'resourceManagerComponent.ServiceComponentInfo.rm_metrics.cluster.unhealthyNMcount',
     node_managers_count_rebooted: 'resourceManagerComponent.ServiceComponentInfo.rm_metrics.cluster.rebootedNMcount',
     node_managers_count_decommissioned: 'resourceManagerComponent.ServiceComponentInfo.rm_metrics.cluster.decommissionedNMcount',
+    allocated_memory: 'resourceManagerComponent.host_components[0].metrics.yarn.Queue.root.AllocatedMB',
+    reserved_memory: 'resourceManagerComponent.host_components[0].metrics.yarn.Queue.root.ReservedMB',
+    available_memory: 'resourceManagerComponent.host_components[0].metrics.yarn.Queue.root.AvailableMB',
+    queue: 'resourceManagerComponent.queue'
   },
   mapReduce2Config: {
     version: 'jobHistoryServerComponent.ServiceComponentInfo.Version',
@@ -370,6 +374,7 @@ App.servicesMapper = App.QuickDataMapper.create({
   },
   yarnMapper: function (item) {
     var result = [];
+    var self = this;
     var finalConfig = jQuery.extend({}, this.config);
     // Change the JSON so that it is easy to map
     var yarnConfig = this.yarnConfig;
@@ -389,6 +394,12 @@ App.servicesMapper = App.QuickDataMapper.create({
             item.node_manager_live_nodes.push(nm.HostName);
           }
         });
+
+        var root = component.host_components[0].metrics.yarn.Queue.root;
+        var queue = JSON.stringify({
+          'root': self.parseObject(root)
+        });
+        component.queue = queue;
         // extend config
         finalConfig = jQuery.extend(finalConfig, yarnConfig);
       }
@@ -419,6 +430,19 @@ App.servicesMapper = App.QuickDataMapper.create({
 
     return finalJson;
   },
+
+  parseObject: function(obj) {
+    var res = {};
+    for (var p in obj) {
+      if (obj.hasOwnProperty(p)) {
+        if (obj[p] instanceof Object) {
+          res[p] = this.parseObject(obj[p]);
+        }
+      }
+    }
+    return res;
+  },
+
   mapreduce2Mapper: function (item) {
     var result = [];
     var finalConfig = jQuery.extend({}, this.config);

+ 4 - 0
ambari-web/app/messages.js

@@ -1213,6 +1213,10 @@ Em.I18n.translations = {
   'dashboard.services.yarn.containers.msg': '{0} allocated / {1} pending / {2} reserved',
   'dashboard.services.yarn.apps': 'Applications',
   'dashboard.services.yarn.apps.msg': '{0} submitted / {1} running / {2} pending / {3} completed / {4} killed / {5} failed',
+  'dashboard.services.yarn.memory': 'Memory',
+  'dashboard.services.yarn.memory.msg': '{0} used / {1} reserved / {2} total',
+  'dashboard.services.yarn.queues': 'Queues',
+  'dashboard.services.yarn.queues.msg': '{0} Queues',
 
   'dashboard.services.mapreduce.summary':'{0} of {1} trackers live, {2} jobs running, {3} jobs waiting',
   'dashboard.services.mapreduce.taskTrackers':'TaskTrackers',

+ 14 - 1
ambari-web/app/models/service/yarn.js

@@ -16,6 +16,7 @@
  */
 
 var App = require('app');
+var objectUtils = require('utils/object_utils');
 
 App.YARNService = App.Service.extend({
   version: DS.attr('string'),
@@ -39,7 +40,19 @@ App.YARNService = App.Service.extend({
   yarnClientNodes: DS.hasMany('App.Host'),
   resourceManagerStartTime: DS.attr('number'),
   jvmMemoryHeapUsed: DS.attr('number'),
-  jvmMemoryHeapCommitted: DS.attr('number')
+  jvmMemoryHeapCommitted: DS.attr('number'),
+  allocatedMemory: DS.attr('number'),
+  reservedMemory: DS.attr('number'),
+  availableMemory: DS.attr('number'),
+  queue: DS.attr('string'),
+  queueFormatted: function() {
+    var queue = JSON.parse(this.get('queue'));
+    return objectUtils.recursiveTree(queue);
+  }.property('queue'),
+  queuesCount: function() {
+    var queue = JSON.parse(this.get('queue'));
+    return objectUtils.recursiveKeysCount(queue);
+  }.property('queue')
 });
 
 App.YARNService.FIXTURES = [];

+ 10 - 0
ambari-web/app/templates/main/dashboard/service/yarn.hbs

@@ -96,6 +96,16 @@
         <td>{{t dashboard.services.yarn.apps}}</td>
         <td>{{view.apps}}</td>
       </tr>
+      <!-- Memory -->
+      <tr>
+          <td>{{t dashboard.services.yarn.memory}}</td>
+          <td>{{view.memory}}</td>
+      </tr>
+      <!-- Queues -->
+      <tr>
+          <td>{{t dashboard.services.yarn.queues}}</td>
+          <td><a href="#" {{action showQueues target="view"}}>{{view.queues}}</a></td>
+      </tr>
     {{#unless view.showOnlyRows}}
       </tbody>
     </table>

+ 63 - 0
ambari-web/app/utils/object_utils.js

@@ -0,0 +1,63 @@
+/**
+ * Licensed to the Apache Software Foundation (ASF) under one
+ * or more contributor license agreements.  See the NOTICE file
+ * distributed with this work for additional information
+ * regarding copyright ownership.  The ASF licenses this file
+ * to you under the Apache License, Version 2.0 (the
+ * "License"); you may not use this file except in compliance
+ * with the License.  You may obtain a copy of the License at
+ *
+ *     http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * 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.
+ */
+
+var stringUtils = require('utils/string_utils');
+
+module.exports = {
+
+  recursiveKeysCount: function(obj) {
+    if (!(obj instanceof Object)) {
+      return null;
+    }
+
+    function r(obj) {
+      var count = 0;
+      for (var k in obj) {
+        if (obj.hasOwnProperty(k)) {
+          if (obj[k] instanceof Object) {
+            count += 1 + r(obj[k]);
+          }
+        }
+      }
+      return count;
+    }
+
+    return r(obj);
+  },
+
+  recursiveTree: function(obj) {
+    if (!(obj instanceof Object)) {
+      return null;
+    }
+    function r(obj, indx) {
+      var str = '';
+      for (var k in obj) {
+        if (obj.hasOwnProperty(k)) {
+          if (obj[k] instanceof Object) {
+            var spaces = (new Array(indx + 1).join('&nbsp;'));
+            var bull = (indx != 0 ? '&bull; ' : ' '); // empty for "root" element
+            str += spaces + bull + k + '<br />' + r(obj[k], indx + 1);
+          }
+        }
+      }
+      return str;
+    }
+    return r(obj, 0);
+  }
+
+};

+ 24 - 0
ambari-web/app/views/main/dashboard/service/yarn.js

@@ -105,4 +105,28 @@ App.MainDashboardServiceYARNView = App.MainDashboardServiceView.extend({
     return this.t('dashboard.services.yarn.apps.msg').format(appsSubmitted, appsRunning, appsPending, appsCompleted, appsKilled, appsFailed);
   }.property('service.appsSubmitted', 'service.appsRunning', 'service.appsPending', 'service.appsCompleted', 'service.appsKilled', 'service.appsFailed'),
 
+  memory: function() {
+    return Em.I18n.t('dashboard.services.yarn.memory.msg').format(
+      this.get('service.allocatedMemory').bytesToSize(1, 'parseFloat'),
+      this.get('service.reservedMemory').bytesToSize(1, 'parseFloat'),
+      this.get('service.availableMemory').bytesToSize(1, 'parseFloat')
+    );
+  }.property('service.allocatedMemory', 'service.reservedMemory', 'service.availableMemory'),
+
+  queues: function() {
+    return Em.I18n.t('dashboard.services.yarn.queues.msg').format(this.get('service.queuesCount'));
+  }.property('service.queuesCount'),
+
+  showQueues: function() {
+    var self = this;
+    return App.ModalPopup.show({
+      secondary: null,
+      header: Em.I18n.t('dashboard.services.yarn.queues'),
+      bodyClass: Em.View.extend({
+        template: Em.Handlebars.compile('{{{view.queues}}}'),
+        queues: self.get('service.queueFormatted')
+      })
+    });
+  }
+
 });