eagle-commits mailing list archives

Site index · List index
Message view « Date » · « Thread »
Top « Date » · « Thread »
From h..@apache.org
Subject eagle git commit: [EAGLE-855] support metric check
Date Wed, 11 Jan 2017 02:53:10 GMT
Repository: eagle
Updated Branches:
  refs/heads/master 18424b9f5 -> 0d4f109fa


[EAGLE-855] support metric check

Add metric/preview for metric checking

Author: zombieJ <smith3816@gmail.com>

Closes #770 from zombieJ/EAGLE-855.


Project: http://git-wip-us.apache.org/repos/asf/eagle/repo
Commit: http://git-wip-us.apache.org/repos/asf/eagle/commit/0d4f109f
Tree: http://git-wip-us.apache.org/repos/asf/eagle/tree/0d4f109f
Diff: http://git-wip-us.apache.org/repos/asf/eagle/diff/0d4f109f

Branch: refs/heads/master
Commit: 0d4f109fa51d2f1c409e8335f8c4e5d48a66a87b
Parents: 18424b9
Author: zombieJ <smith3816@gmail.com>
Authored: Wed Jan 11 10:52:54 2017 +0800
Committer: Hao Chen <hao@apache.org>
Committed: Wed Jan 11 10:52:54 2017 +0800

----------------------------------------------------------------------
 eagle-server/src/main/webapp/app/dev/index.html |   2 +
 .../webapp/app/dev/partials/metric/preview.html |  68 +++++++++
 .../src/main/webapp/app/dev/public/js/app.js    |   9 ++
 .../app/dev/public/js/components/chart.js       |  38 ++++-
 .../app/dev/public/js/ctrls/metricCtrl.js       |  77 ++++++++++
 .../public/js/services/compatibleEntitySrv.js   | 142 +++++++++++++++++--
 eagle-server/src/main/webapp/app/package.json   |   2 +-
 7 files changed, 326 insertions(+), 12 deletions(-)
----------------------------------------------------------------------


http://git-wip-us.apache.org/repos/asf/eagle/blob/0d4f109f/eagle-server/src/main/webapp/app/dev/index.html
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/webapp/app/dev/index.html b/eagle-server/src/main/webapp/app/dev/index.html
index ec0a76a..74d5c57 100644
--- a/eagle-server/src/main/webapp/app/dev/index.html
+++ b/eagle-server/src/main/webapp/app/dev/index.html
@@ -116,6 +116,7 @@
 									<li><a>How to install application</a></li>
 									<li><a>How to manage application</a></li>
 									<li><a>How to develop application</a></li>
+									<li><a ui-sref="metricPreview()">Preview eagle metric</a></li>
 								</ul>
 							</li>
 						</ul>
@@ -293,6 +294,7 @@
 		<script src="public/js/ctrls/alertEditCtrl.js" type="text/javascript" charset="utf-8"></script>
 		<script src="public/js/ctrls/integrationCtrl.js" type="text/javascript" charset="utf-8"></script>
 		<script src="public/js/ctrls/siteCtrl.js" type="text/javascript" charset="utf-8"></script>
+		<script src="public/js/ctrls/metricCtrl.js" type="text/javascript" charset="utf-8"></script>
 		<!-- endref -->
 	</body>
 </html>

http://git-wip-us.apache.org/repos/asf/eagle/blob/0d4f109f/eagle-server/src/main/webapp/app/dev/partials/metric/preview.html
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/webapp/app/dev/partials/metric/preview.html b/eagle-server/src/main/webapp/app/dev/partials/metric/preview.html
new file mode 100644
index 0000000..0c16ec0
--- /dev/null
+++ b/eagle-server/src/main/webapp/app/dev/partials/metric/preview.html
@@ -0,0 +1,68 @@
+<!--
+  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.
+  -->
+
+<div class="row">
+	<div class="col-sm-12 col-md-5 col-lg-3">
+		<div class="box box-primary">
+			<div class="box-header with-border">
+				<h3 class="box-title">Configure</h3>
+			</div>
+			<div class="box-body">
+				<div class="form-group">
+					<label>Site</label>
+					<select class="form-control" ng-model="site">
+						<option ng-repeat="site in Site.list track by $index" value="{{site.siteId}}">
+							{{site.siteName || site.siteId}}
+						</option>
+					</select>
+				</div>
+				<div class="form-group">
+					<label>Metric Name</label>
+					<select class="form-control" ng-model="metricName">
+						<option ng-repeat="metric in metricList track by metric">{{metric}}</option>
+					</select>
+				</div>
+				<div class="form-group">
+					<label>Groups</label>
+					<input type="text" class="form-control" ng-model="groups" placeholder="e.g. 'site'"
/>
+				</div>
+				<div class="form-group">
+					<label>Fields</label>
+					<input type="text" class="form-control" ng-model="fields" placeholder="e.g. 'avg(value),
sum(value) desc'" />
+				</div>
+				<!--div class="form-group">
+					<label>Interval Minutes</label>
+					<input type="text" class="form-control" ng-model="intervalmin" />
+				</div-->
+			</div>
+			<div class="box-footer text-right">
+				<button class="btn btn-primary" ng-click="loadSeries()">Apply</button>
+			</div>
+		</div>
+	</div>
+	<div class="col-sm-12 col-md-7 col-lg-9">
+		<div class="box box-primary">
+			<div class="box-header with-border">
+				<h3 class="box-title">Preview</h3>
+			</div>
+			<div class="box-body">
+				<div chart style="height: 400px;" series="series" option="commonOption"></div>
+			</div>
+		</div>
+	</div>
+</div>

http://git-wip-us.apache.org/repos/asf/eagle/blob/0d4f109f/eagle-server/src/main/webapp/app/dev/public/js/app.js
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/webapp/app/dev/public/js/app.js b/eagle-server/src/main/webapp/app/dev/public/js/app.js
index e1f5b77..79c2df5 100644
--- a/eagle-server/src/main/webapp/app/dev/public/js/app.js
+++ b/eagle-server/src/main/webapp/app/dev/public/js/app.js
@@ -192,6 +192,15 @@ var app = {};
 					resolve: routeResolve({ application: false })
 				})
 
+				// ================================= Metric =================================
+				.state('metricPreview', {
+					url: "/metric/preview?startTime&endTime&site&metric&groups&fields",
+					templateUrl: "partials/metric/preview.html?_=" + window._TRS(),
+					controller: "metricPreviewCtrl",
+					reloadOnSearch: false,
+					resolve: routeResolve({ application: false, time: true })
+				})
+
 				// ================================== Site ==================================
 				.state('site', {
 					url: "/site/:siteId",

http://git-wip-us.apache.org/repos/asf/eagle/blob/0d4f109f/eagle-server/src/main/webapp/app/dev/public/js/components/chart.js
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/webapp/app/dev/public/js/components/chart.js b/eagle-server/src/main/webapp/app/dev/public/js/components/chart.js
index 99f74d5..63855b6 100644
--- a/eagle-server/src/main/webapp/app/dev/public/js/components/chart.js
+++ b/eagle-server/src/main/webapp/app/dev/public/js/components/chart.js
@@ -29,6 +29,10 @@
 		};
 	});
 
+	/**
+	 * @param {{}?} chart Set chart reference
+	 * @param {function} chart.refresh Refresh current chart
+	 */
 	eagleComponents.directive('chart', function(Chart) {
 		var charts = Chart.charts;
 
@@ -61,14 +65,43 @@
 			},
 			controller: function ($scope, $element, $attrs, Time) {
 				var i;
+				var lastSeriesCount = 0;
 				var lastTooltipEvent;
 				var chart = echarts.init($element[0]);
 				charts[chart.id] = chart;
 
+				function wrapChart() {
+					chart.refresh = function () {
+						refreshChart();
+					};
+
+					chart.forceRefresh = function () {
+						delete charts[chart.id];
+						chart.dispose();
+
+						chart = echarts.init($element[0]);
+						charts[chart.id] = chart;
+						lastSeriesCount = 0;
+
+						refreshChart();
+
+						wrapChart();
+					};
+				}
+
 				function refreshChart() {
 					var maxYAxis = 0;
 					var legendList = [];
 					var categoryList = $scope.category ? $scope.category : [];
+					var currentSeriesCount = ($scope.series || []).length;
+
+					if (lastSeriesCount > currentSeriesCount && chart.forceRefresh) {
+						console.log('Force refresh!');
+						// TODO: echart series bug. Need rebuild the chart. Ref: https://github.com/ecomfe/echarts/issues/4033
+						chart.forceRefresh();
+						return;
+					}
+					lastSeriesCount = currentSeriesCount;
 
 					var seriesList = $.map($scope.series || [], function (series, id) {
 						if(id === 0 && !$scope.category) {
@@ -166,13 +199,12 @@
 					$scope.$parent.$parent[$attrs.chart] = chart;
 				}
 
-				chart.refresh = function () {
-					refreshChart();
-				};
+				wrapChart();
 
 				// Render
 				refreshChart();
 				$scope.$watch("series", refreshChart);
+				$scope.$watch("series.length", refreshChart);
 
 				$scope.$on('$destroy', function() {
 					delete charts[chart.id];

http://git-wip-us.apache.org/repos/asf/eagle/blob/0d4f109f/eagle-server/src/main/webapp/app/dev/public/js/ctrls/metricCtrl.js
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/webapp/app/dev/public/js/ctrls/metricCtrl.js b/eagle-server/src/main/webapp/app/dev/public/js/ctrls/metricCtrl.js
new file mode 100644
index 0000000..e0f0f15
--- /dev/null
+++ b/eagle-server/src/main/webapp/app/dev/public/js/ctrls/metricCtrl.js
@@ -0,0 +1,77 @@
+/*
+ * 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.
+ */
+
+(function() {
+	'use strict';
+
+	var eagleControllers = angular.module('eagleControllers');
+
+	// ======================================================================================
+	// =                                        Alert                                      
=
+	// ======================================================================================
+	eagleControllers.controller('metricPreviewCtrl', function ($scope, $wrapState, PageConfig,
CompatibleEntity, Time, Site) {
+		PageConfig.title = "Metric Preview";
+
+		$scope.series = [];
+		$scope.loading = false;
+
+		$scope.site = $wrapState.param.site || Site.list[0].siteId;
+		$scope.metricName = $wrapState.param.metric;
+		$scope.groups = $wrapState.param.groups;
+		$scope.fields = $wrapState.param.fields;
+
+		$scope.commonOption = {};
+
+		$scope.metricList = [$scope.metricName];
+		CompatibleEntity.groups({
+			query: 'MetricSchemaService',
+			groups: 'metricName',
+			fields: 'count',
+			limit: 9999,
+		})._promise.then(function (res) {
+			$scope.metricList = $.map(res.data.obj, function (obj) {
+				return obj.key[0];
+			}).sort();
+		});
+
+		$scope.loadSeries = function() {
+			$scope.series = CompatibleEntity.timeSeries({
+				condition: { site: $scope.site },
+				groups: $scope.groups,
+				fields: $scope.fields,
+				top: 10,
+				metric: $scope.metricName,
+				limit: 100000,
+			});
+
+			// Update URL
+			$wrapState.go(".", {
+				site: $scope.site,
+				metric: $scope.metricName,
+				groups: $scope.groups,
+				fields: $scope.fields,
+			});
+		};
+
+		if ($scope.metricName && $scope.groups && $scope.fields) {
+			$scope.loadSeries();
+		}
+
+		Time.onReload($scope.loadSeries, $scope);
+	});
+}());

http://git-wip-us.apache.org/repos/asf/eagle/blob/0d4f109f/eagle-server/src/main/webapp/app/dev/public/js/services/compatibleEntitySrv.js
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/webapp/app/dev/public/js/services/compatibleEntitySrv.js
b/eagle-server/src/main/webapp/app/dev/public/js/services/compatibleEntitySrv.js
index d9d4ce7..8296451 100644
--- a/eagle-server/src/main/webapp/app/dev/public/js/services/compatibleEntitySrv.js
+++ b/eagle-server/src/main/webapp/app/dev/public/js/services/compatibleEntitySrv.js
@@ -55,15 +55,61 @@
 		}
 
 		function parseFields(fields) {
-			fields = fields || [];
-			if(fields.length === 0) return '*';
+			fields = $.isArray(fields) ? fields : (
+				fields && fields !== '*' ? fields.split(/\s*,\s*/) : []
+			);
+			if(fields.length === 0) return {
+				fieldStr: '*',
+				fields: [],
+				order: ''
+			};
+
+			var fieldList = [];
+			var fieldEntities = [];
+			var orderId = -1;
+			var fieldStr = $.map(fields, function (field, index) {
+				var matches = field.match(/^([^\s]*)(\s+.*)?$/);
+				var fieldName = matches[1];
+				if(matches[2]) {
+					orderId = index;
+				}
+				var fieldMatches = fieldName.match(/^(.+)\((.+)\)$/);
+				if (fieldName === 'count') {
+					fieldEntities.push({
+						method: 'count',
+						name: 'count',
+					});
+					fieldList.push('count');
+					return fieldName;
+				}
+				else if (fieldMatches) {
+					fieldEntities.push({
+						method: fieldMatches[1],
+						name: fieldMatches[2],
+					});
+					fieldList.push(fieldName);
+					return fieldName;
+				} else {
+					fieldEntities.push({
+						method: '',
+						name: fieldName,
+					});
+					fieldList.push('@' + fieldName);
+					return '@' + fieldName;
+				}
+			}).join(", ");
 
-			return $.map(fields, function (field) {
-				return '@' + field;
-			}).join(',');
+			return {
+				fieldStr: fieldStr,
+				fields: fieldList,
+				fieldEntities: fieldEntities,
+				order: orderId === -1 ? "" : ".{" + fields[orderId] + "}"
+			};
 		}
 
-		CompatibleEntity.QUERY_LIST = '/rest/entities?query=${query}[${condition}]{${fields}}&pageSize=${size}';
+		CompatibleEntity.QUERY_LIST = '/rest/entities?query=${query}[${condition}]{${fields}}&pageSize=${limit}';
+		CompatibleEntity.QUERY_GROUPS = '/rest/entities?query=${query}[${condition}]<${groups}>{${fields}}&pageSize=${limit}';
+		CompatibleEntity.QUERY_METRICS_INTERVAL = '/rest/entities?query=GenericMetricService[${condition}]<${groups}>{${fields}}${order}${top}&metricName=${metric}&pageSize=${limit}&startTime=${startTime}&endTime=${endTime}&intervalmin=${intervalMin}&timeSeries=true';
 
 		CompatibleEntity.query = function (queryName, param) {
 			var list = [];
@@ -71,10 +117,10 @@
 
 			list._refresh = function () {
 				var myParam = $.extend({
-					size: 10000,
+					limit: 10000,
 				}, param || {}, {
 					condition: parseCondition(param.condition),
-					fields: parseFields(param.fields),
+					fields: parseFields(param.fields).fieldStr,
 					startTime: Time.format(param.startTime),
 					endTime: Time.format(param.endTime)
 				});
@@ -91,6 +137,86 @@
 			return list._refresh();
 		};
 
+		/**
+		 *
+		 * @param {string} queryName
+		 * @param {string} param.query
+		 * @param {{}?} param.condition
+		 * @param {string|[]} param.groups
+		 * @param {string|[]} param.fields
+		 * @param {number?} param.limit
+		 */
+		CompatibleEntity.groups = function (param) {
+			return CompatibleEntity.query('GROUPS', $.extend({}, param, {
+				groups: parseFields(param.groups).fields,
+			}));
+		};
+
+		/**
+		 *
+		 * @param {string} queryName
+		 * @param {{}?} param.condition
+		 * @param {string|[]} param.groups
+		 * @param {string|[]} param.fields
+		 * @param {string} param.metric
+		 * @param {{}} param.startTime
+		 * @param {{}} param.endTime
+		 * @param {number?} param.top
+		 * @param {number?} param.limit
+		 * @param {number?} param.intervalMin
+		 */
+		CompatibleEntity.timeSeries = function (param) {
+			param = param || {};
+			var fields = parseFields(param.fields);
+			var startTime = new Time(param.startTime || 'startTime');
+			var endTime = new Time(param.endTime || 'endTime');
+
+			var startTimestamp = startTime.valueOf();
+			var intervalMin = param.intervalMin ? param.intervalMin : Time.diffInterval(startTime,
endTime) / 1000 / 60;
+			var interval = intervalMin * 1000 * 60;
+
+			var innerList = CompatibleEntity.query('METRICS_INTERVAL', $.extend({}, param, {
+				groups: parseFields(param.groups).fields,
+				order: fields.order,
+				top: param.top ? "&top=" + param.top : "",
+				startTime: startTime,
+				endTime: endTime,
+				intervalMin: intervalMin,
+			}));
+
+			var list = [];
+			list._done = false;
+			list._promise = innerList._promise;
+
+			innerList._promise.then(function () {
+				var displayKey = innerList.length > 1;
+
+				// Generate series
+				var series = $.map(innerList, function (group) {
+					return $.map(fields.fieldEntities, function (entity, i) {
+						var data = group.value[i];
+						return {
+							name: (displayKey ? group.key.join(',') + '-' : '') + (entity.method || entity.name),
+							type: 'line',
+							showSymbol: false,
+							data: $.map(data, function (value, index) {
+								return {
+									x: startTimestamp + interval * index,
+									y: value
+								};
+							})
+						};
+					});
+				});
+
+				list.splice(0);
+				Array.prototype.push.apply(list, series);
+				list._done = true;
+			});
+
+			return list;
+		};
+
 		return CompatibleEntity;
 	});
 })();

http://git-wip-us.apache.org/repos/asf/eagle/blob/0d4f109f/eagle-server/src/main/webapp/app/package.json
----------------------------------------------------------------------
diff --git a/eagle-server/src/main/webapp/app/package.json b/eagle-server/src/main/webapp/app/package.json
index c1c652e..4ee3eda 100644
--- a/eagle-server/src/main/webapp/app/package.json
+++ b/eagle-server/src/main/webapp/app/package.json
@@ -23,7 +23,7 @@
     "angular-ui-router": "0.3.1",
     "bootstrap": "3.3.6",
     "d3": "3.5.16",
-    "echarts": "^3.2.3",
+    "echarts": "^3.3.2",
     "font-awesome": "4.7.0",
     "jquery": "2.2.4",
     "jquery-slimscroll": "1.3.6",


Mime
View raw message