Repository: ambari Updated Branches: refs/heads/trunk 98727e22c -> 4fb5f66df
AMBARI-12833. Improve alert definitions and alert definitions summary mappers (onechiporenko) Project: http://git-wip-us.apache.org/repos/asf/ambari/repo Commit: http://git-wip-us.apache.org/repos/asf/ambari/commit/4fb5f66d Tree: http://git-wip-us.apache.org/repos/asf/ambari/tree/4fb5f66d Diff: http://git-wip-us.apache.org/repos/asf/ambari/diff/4fb5f66d Branch: refs/heads/trunk Commit: 4fb5f66dff89b84fcd3ac8f1151ccc3576f7e3b1 Parents: 98727e2 Author: Oleg Nechiporenko <onechipore...@apache.org> Authored: Thu Aug 20 18:21:12 2015 +0300 Committer: Oleg Nechiporenko <onechipore...@apache.org> Committed: Thu Aug 20 18:25:56 2015 +0300 ---------------------------------------------------------------------- .../controllers/global/cluster_controller.js | 2 + .../main/alert_definitions_controller.js | 22 -------- .../mappers/alert_definition_summary_mapper.js | 56 +++++++++++++++++--- .../app/mappers/alert_definitions_mapper.js | 29 ++++++++-- ambari-web/app/mappers/alert_groups_mapper.js | 1 + .../app/mappers/alert_instances_mapper.js | 2 + ambari-web/app/models/service.js | 21 ++++---- .../app/views/main/alert_definitions_view.js | 14 +++-- 8 files changed, 102 insertions(+), 45 deletions(-) ---------------------------------------------------------------------- http://git-wip-us.apache.org/repos/asf/ambari/blob/4fb5f66d/ambari-web/app/controllers/global/cluster_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/global/cluster_controller.js b/ambari-web/app/controllers/global/cluster_controller.js index 8bb4950..b0ae730 100644 --- a/ambari-web/app/controllers/global/cluster_controller.js +++ b/ambari-web/app/controllers/global/cluster_controller.js @@ -245,10 +245,12 @@ App.ClusterController = Em.Controller.extend({ }); // alerts loading doesn't affect overall progress + console.time('Overall alerts loading time'); updater.updateAlertGroups(function () { updater.updateAlertDefinitions(function () { updater.updateAlertDefinitionSummary(function () { updater.updateUnhealthyAlertInstances(function () { + console.timeEnd('Overall alerts loading time'); self.set('isAlertsLoaded', true); }); }); http://git-wip-us.apache.org/repos/asf/ambari/blob/4fb5f66d/ambari-web/app/controllers/main/alert_definitions_controller.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/controllers/main/alert_definitions_controller.js b/ambari-web/app/controllers/main/alert_definitions_controller.js index e77ee6d..58eecf5 100644 --- a/ambari-web/app/controllers/main/alert_definitions_controller.js +++ b/ambari-web/app/controllers/main/alert_definitions_controller.js @@ -78,28 +78,6 @@ App.MainAlertDefinitionsController = Em.ArrayController.extend({ }, /** - * Calculate critical count for each service, to show up the label on services menu - * @method getCriticalAlertsCountForService - * @return {Number} - */ - getCriticalAlertsCountForService: function (service) { - return this.get('content').filterProperty('service.serviceName', service). - invoke('getWithDefault', 'summary.CRITICAL.count', 0). - reduce(Em.sum, 0); - }, - - /** - * Calculate critical/warning count for each service, to show up the label on services menu - * @method getCriticalOrWarningAlertsCountForService - * @return {Number} - */ - getCriticalOrWarningAlertsCountForService: function (service) { - return this.get('content').filterProperty('service.serviceName', service).map(function (alertDefinition) { - return alertDefinition.getWithDefault('summary.CRITICAL.count', 0) + alertDefinition.getWithDefault('summary.WARNING.count', 0); - }).reduce(Em.sum, 0); - }, - - /** * ========================== alerts popup dialog ========================= */ http://git-wip-us.apache.org/repos/asf/ambari/blob/4fb5f66d/ambari-web/app/mappers/alert_definition_summary_mapper.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/mappers/alert_definition_summary_mapper.js b/ambari-web/app/mappers/alert_definition_summary_mapper.js index 20b5ae4..04cec55 100644 --- a/ambari-web/app/mappers/alert_definition_summary_mapper.js +++ b/ambari-web/app/mappers/alert_definition_summary_mapper.js @@ -16,16 +16,24 @@ */ var App = require('app'); +var dataManipulation = require('utils/data_manipulation'); App.alertDefinitionSummaryMapper = App.QuickDataMapper.create({ config: {}, map: function(data) { + console.time('App.alertDefinitionSummaryMapper execution time'); + if (!data.alerts_summary_grouped) return; var alertDefinitions = App.AlertDefinition.find(); + var alertDefinitionsMap = {}; + alertDefinitions.forEach(function (definition) { + alertDefinitionsMap[definition.get('id')] = definition; + }); + var summaryMap = {}; data.alerts_summary_grouped.forEach(function(alertDefinitionSummary) { - var alertDefinition = alertDefinitions.findProperty('id', alertDefinitionSummary.definition_id); + var alertDefinition = alertDefinitionsMap[alertDefinitionSummary.definition_id]; if (alertDefinition) { var summary = {}, timestamp = 0; @@ -41,19 +49,53 @@ App.alertDefinitionSummaryMapper = App.QuickDataMapper.create({ timestamp = alertDefinitionSummary.summary[status].original_timestamp; } }); - alertDefinition.setProperties({ + summaryMap[alertDefinitionSummary.definition_id] = { summary: summary, lastTriggered: parseInt(timestamp) - }); + }; } }); - // clear summary for disabled alert definitions - alertDefinitions.forEach(function (definition) { - if (!definition.get('enabled')) { - definition.set('summary', {}); + alertDefinitions.forEach(function (d) { + var id = d.get('id'); + alertDefinitionsMap[id].setProperties(summaryMap[id]); + if (!alertDefinitionsMap[id].get('enabled')) { + // clear summary for disabled alert definitions + alertDefinitionsMap[id].set('summary', {}); + } + }); + // set alertsCount and hasCriticalAlerts for each service + var groupedByServiceName = dataManipulation.groupPropertyValues(alertDefinitions, 'service.serviceName'); + var services = App.Service.find(); + var servicesMap = {}; + services.forEach(function (service) { + servicesMap[service.get('id')] = service; + }); + Object.keys(groupedByServiceName).forEach(function(serviceName) { + var service = servicesMap[serviceName]; + if (service) { + var hasCriticalAlerts = false; + + var alertsCount = groupedByServiceName[serviceName].map(function (alertDefinition) { + + var criticalCount = alertDefinition.getWithDefault('summary.CRITICAL.count', 0); + var warningCount = alertDefinition.getWithDefault('summary.WARNING.count', 0); + + if (criticalCount) { + hasCriticalAlerts = true; + } + return criticalCount + warningCount; + + }).reduce(Em.sum, 0); + + service.setProperties({ + alertsCount: alertsCount, + hasCriticalAlerts: hasCriticalAlerts + }); } }); + console.timeEnd('App.alertDefinitionSummaryMapper execution time'); + } }); http://git-wip-us.apache.org/repos/asf/ambari/blob/4fb5f66d/ambari-web/app/mappers/alert_definitions_mapper.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/mappers/alert_definitions_mapper.js b/ambari-web/app/mappers/alert_definitions_mapper.js index 29c1c97..80d175e 100644 --- a/ambari-web/app/mappers/alert_definitions_mapper.js +++ b/ambari-web/app/mappers/alert_definitions_mapper.js @@ -70,8 +70,8 @@ App.alertDefinitionsMapper = App.QuickDataMapper.create({ }, map: function (json) { + console.time('App.alertDefinitionsMapper execution time'); if (json && json.items) { - var self = this, alertDefinitions = [], alertReportDefinitions = [], @@ -79,9 +79,14 @@ App.alertDefinitionsMapper = App.QuickDataMapper.create({ alertMetricsUriDefinitions = [], alertGroupsMap = App.cache['previousAlertGroupsMap'], existingAlertDefinitions = App.AlertDefinition.find(), + existingAlertDefinitionsMap = {}, alertDefinitionsToDelete = existingAlertDefinitions.mapProperty('id'), rawSourceData = {}; + existingAlertDefinitions.forEach(function (d) { + existingAlertDefinitionsMap[d.get('id')] = d; + }); + json.items.forEach(function (item) { var convertedReportDefinitions = []; var reporting = item.AlertDefinition.source.reporting; @@ -116,7 +121,7 @@ App.alertDefinitionsMapper = App.QuickDataMapper.create({ alertDefinition.groups = alertGroupsMap[alertDefinition.id]; } - var oldAlertDefinition = existingAlertDefinitions.findProperty('id', alertDefinition.id); + var oldAlertDefinition = existingAlertDefinitionsMap[alertDefinition.id]; if (oldAlertDefinition) { // new values will be parsed in the another mapper, so for now just use old values alertDefinition.summary = oldAlertDefinition.get('summary'); @@ -187,10 +192,12 @@ App.alertDefinitionsMapper = App.QuickDataMapper.create({ App.store.loadMany(this.get('metricsSourceModel'), alertMetricsSourceDefinitions); this.setMetricsSourcePropertyLists(this.get('metricsSourceModel'), alertMetricsSourceDefinitions); App.store.loadMany(this.get('metricsUriModel'), alertMetricsUriDefinitions); + // this loadMany takes too much time App.store.loadMany(this.get('model'), alertDefinitions); this.setAlertDefinitionsRawSourceData(rawSourceData); App.store.commit(); } + console.timeEnd('App.alertDefinitionsMapper execution time'); }, /** @@ -199,8 +206,15 @@ App.alertDefinitionsMapper = App.QuickDataMapper.create({ * @param data */ setMetricsSourcePropertyLists: function (model, data) { + var modelsMap = {}; + model.find().forEach(function (m) { + modelsMap[m.get('id')] = m; + }); data.forEach(function (record) { - model.find().findProperty('id', record.id).set('propertyList', record.property_list); + var m = modelsMap[record.id]; + if (m) { + m.set('propertyList', record.property_list); + } }); }, @@ -210,9 +224,16 @@ App.alertDefinitionsMapper = App.QuickDataMapper.create({ */ setAlertDefinitionsRawSourceData: function (rawSourceData) { var allDefinitions = App.AlertDefinition.find(); + var allDefinitionsMap = {}; + allDefinitions.forEach(function(d) { + allDefinitionsMap[d.get('id')] = d; + }); for (var alertDefinitionId in rawSourceData) { if (rawSourceData.hasOwnProperty(alertDefinitionId)) { - allDefinitions.findProperty('id', +alertDefinitionId).set('rawSourceData', rawSourceData[alertDefinitionId]); + var m = allDefinitionsMap[+alertDefinitionId]; + if (m) { + m.set('rawSourceData', rawSourceData[alertDefinitionId]); + } } } } http://git-wip-us.apache.org/repos/asf/ambari/blob/4fb5f66d/ambari-web/app/mappers/alert_groups_mapper.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/mappers/alert_groups_mapper.js b/ambari-web/app/mappers/alert_groups_mapper.js index fffbd2c..c079c21 100644 --- a/ambari-web/app/mappers/alert_groups_mapper.js +++ b/ambari-web/app/mappers/alert_groups_mapper.js @@ -108,6 +108,7 @@ App.alertGroupsMapper = App.QuickDataMapper.create({ App.cache['previousAlertGroupsMap'] = alertDefinitionsGroupsMap; App.cache['previousAlertGroupsFullMap'] = groupsMap; App.cache['alertNotificationsGroupsMap'] = alertNotificationsGroupsMap; + // initial load takes much more time than others, but it's OK (all data should be saved first time) App.store.loadMany(this.get('model'), alertGroups); App.store.commit(); console.timeEnd('App.alertGroupsMapper execution time'); http://git-wip-us.apache.org/repos/asf/ambari/blob/4fb5f66d/ambari-web/app/mappers/alert_instances_mapper.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/mappers/alert_instances_mapper.js b/ambari-web/app/mappers/alert_instances_mapper.js index eabc9f8..af6804f 100644 --- a/ambari-web/app/mappers/alert_instances_mapper.js +++ b/ambari-web/app/mappers/alert_instances_mapper.js @@ -41,6 +41,7 @@ App.alertInstanceMapper = App.QuickDataMapper.create({ }, map: function(json) { + console.time('App.alertInstanceMapper execution time'); if (json.items) { var alertInstances = []; var model = this.get('model'); @@ -57,6 +58,7 @@ App.alertInstanceMapper = App.QuickDataMapper.create({ } App.store.loadMany(this.get('model'), alertInstances); + console.timeEnd('App.alertInstanceMapper execution time'); } } }); http://git-wip-us.apache.org/repos/asf/ambari/blob/4fb5f66d/ambari-web/app/models/service.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/models/service.js b/ambari-web/app/models/service.js index 564cbae..250f810 100644 --- a/ambari-web/app/models/service.js +++ b/ambari-web/app/models/service.js @@ -150,15 +150,18 @@ App.Service = DS.Model.extend({ return this.t('services.service.config.restartService.TooltipMessage').format(hcCount, hostCount, hostsMsg); }.property('restartRequiredHostsAndComponents'), - hasCriticalAlerts: function () { - var controller = App.router.get('mainAlertDefinitionsController'); - return controller.getCriticalAlertsCountForService(this.get('serviceName')) > 0; - }.property('alertsCount'), - - alertsCount: function () { - var controller = App.router.get('mainAlertDefinitionsController'); - return controller.getCriticalOrWarningAlertsCountForService(this.get('serviceName')); - }.property('App.router.mainAlertDefinitionsController.content.@each.isCriticalOrWarning') + /** + * Does service have Critical Alerts + * @type {boolean} + */ + hasCriticalAlerts: false, + + /** + * Number of the Critical and Warning alerts for current service + * @type {number} + */ + alertsCount: 0 + }); App.Service.Health = { http://git-wip-us.apache.org/repos/asf/ambari/blob/4fb5f66d/ambari-web/app/views/main/alert_definitions_view.js ---------------------------------------------------------------------- diff --git a/ambari-web/app/views/main/alert_definitions_view.js b/ambari-web/app/views/main/alert_definitions_view.js index 19de504..189f71d 100644 --- a/ambari-web/app/views/main/alert_definitions_view.js +++ b/ambari-web/app/views/main/alert_definitions_view.js @@ -25,9 +25,16 @@ App.MainAlertDefinitionsView = App.TableView.extend({ templateName: require('templates/main/alerts'), - content: function() { - return this.get('controller.content') ? this.get('controller.content').toArray().sort(App.AlertDefinition.getSortDefinitionsByStatus(true)) : []; - }.property('controller.content.@each'), + content: [], + + contentObs: function () { + Em.run.once(this, this.contentObsOnce); + }.observes('controller.content.[]'), + + contentObsOnce: function() { + var content = this.get('controller.content') ? this.get('controller.content').toArray().sort(App.AlertDefinition.getSortDefinitionsByStatus(true)) : []; + this.set('content', content); + }, willInsertElement: function () { if (!this.get('controller.showFilterConditionsFirstLoad')) { @@ -40,6 +47,7 @@ App.MainAlertDefinitionsView = App.TableView.extend({ var self = this; Em.run.next(function () { self.set('isInitialRendering', false); + self.contentObsOnce(); self.tooltipsUpdater(); }); },