Эх сурвалжийг харах

HUE-8649 [frontend] Get some metrics from prometheus instead of random data

Johan Ahlen 7 жил өмнө
parent
commit
bc2cd5e

+ 35 - 73
desktop/core/src/desktop/static/desktop/js/apiHelper.js

@@ -930,88 +930,50 @@ var ApiHelper = (function () {
 
   /**
    * @param {Object} options
-   * @param {Number} options.startTime -- Time in ms
-   * @param {Number} [options.endTime] -- Time in ms
-   * @param {Number} [options.points]
-   *
-   * @param {ContextCompute} [options.computes] -- Or similar. Add when API is in place
+   * @param {Number} options.pastMs
+   * @param {Number} options.stepMs
    *
    * @return {Promise}
    */
   ApiHelper.prototype.fetchResourceStats = function (options) {
-    // TODO: Switch to real API
-
-    var data = [];
-    var currentMax = 100;
-    var currentMin = 10;
-
-    var lastCpuVal = 0;
-    var lastMemVal = 0;
-    var lastIO = 0;
-    var lastQueryCount = 0;
-    var addFakeMeasurement = function (data, time) {
-      var newQueryCount = Math.round(Math.max(Math.min(lastQueryCount + (Math.random() - 0.5) * 10, 25), 0));
-
-      var queuedQueryCount = Math.round(newQueryCount * Math.random());
-      var nonQueuedQueryCount = newQueryCount - queuedQueryCount;
-
-      var diff = newQueryCount - lastQueryCount;
-      if (diff > 0) {
-        lastCpuVal = Math.round(Math.max(Math.min(lastCpuVal + Math.random() * 15, Math.min(currentMax + (Math.random() - 0.5) * 10, 100)), Math.max(currentMin + (Math.random() - 0.5) * 10, 0)));
-        lastMemVal = Math.round(Math.max(Math.min(lastMemVal + Math.random() * 15, Math.min(currentMax + (Math.random() - 0.5) * 10, 100)), Math.max(currentMin + (Math.random() - 0.5) * 10, 0)));
-        lastIO = Math.round(Math.max(Math.min(lastIO + Math.random() * 15, Math.min(currentMax + (Math.random() - 0.5) * 10, 100)), Math.max(currentMin + (Math.random() - 0.5) * 10, 0)));
-      } else {
-        lastCpuVal = Math.round(Math.max(Math.min(lastCpuVal - Math.random() * 15, Math.min(currentMax + (Math.random() - 0.5) * 10, 100)), Math.max(currentMin + (Math.random() - 0.5) * 10, 0)));
-        lastMemVal = Math.round(Math.max(Math.min(lastMemVal - Math.random() * 15, Math.min(currentMax + (Math.random() - 0.5) * 10, 100)), Math.max(currentMin + (Math.random() - 0.5) * 10, 0)));
-        lastIO = Math.round(Math.max(Math.min(lastIO - Math.random() * 15, Math.min(currentMax + (Math.random() - 0.5) * 10, 100)), Math.max(currentMin + (Math.random() - 0.5) * 10, 0)));
-      }
-      data.push([time, lastCpuVal, lastMemVal, lastIO, nonQueuedQueryCount, queuedQueryCount]);
-    };
-
-    var generateFakeData = function (data, startTime, endTime, points) {
-      var diff = endTime - startTime;
+    var self = this;
 
-      for (var i = 1; i <= points; i++) {
-        addFakeMeasurement(data, startTime + i * diff / points )
-      }
+    var queryMetric = function (metricName) {
+      var now = Date.now();
+      return self.simplePost('/metadata/api/prometheus/query', {
+        query: '"' + metricName + '"',
+        start: Math.floor((now - options.pastMs) / 1000),
+        end:  Math.floor(now / 1000),
+        step: options.stepMs / 1000
+      })
     };
 
-    generateFakeData(data, options.startTime, options.endTime, options.points);
-    
-//    var end = new Date();
-//    var start = new Date(end);
-//    start.setDate(start.getDate() - 1);
-
-    var metrics = []
-    var start = Math.floor(options.startTime / 1000);
-    var end = Math.floor(options.endTime / 1000);
-    var step = 60 * 60; // Same as "1h"
-    
-    $.ajax({
-      type: 'POST',
-      url: "/metadata/api/prometheus/query",
-      data: {
-        "query": ko.mapping.toJSON("impala_queries"),
-        // TODO: labels of cluster
-        "start": ko.mapping.toJSON(start),
-        "end": ko.mapping.toJSON(end),
-        "step": ko.mapping.toJSON(step),
-      },
-      success: function(data) {
-        //console.log(ko.mapping.toJSON(data));
-        if (data.data.result) {
-	        data.data.result[0].values.forEach(function(point) {
-	        	metrics.push([point[0] * 1000, 0, 0, 0, point[1], 0]);
-	        });
+    var combinedDeferred = $.Deferred();
+    $.when(
+      queryMetric('round((go_memstats_alloc_bytes / go_memstats_sys_bytes) * 100)'), // CPU percentage
+      queryMetric('round((go_memstats_alloc_bytes / go_memstats_sys_bytes) * 100)'), // Memory percentage
+      queryMetric('round((go_memstats_alloc_bytes / go_memstats_sys_bytes) * 100)'), // IO percentage
+      queryMetric('process_open_fds'), // Sum of queries
+      queryMetric('round(process_open_fds * 0.5)'), // Queued queries
+    ).done(function () {
+      var result = [];
+      for (var j = 0; j < arguments.length; j++) {
+        var response = arguments[j];
+        var values = response.data.result[0].values;
+        for (var i = 0; i < values.length; i++) {
+          if (!result[i]) {
+            result[i] = [];
+            result[i].push(values[i][0] * 1000); // Adjust back to milliseconds
+            result[i].push(parseFloat(values[i][1]))
+          } else {
+            result[i].push(parseFloat(values[i][1])); // Assuming timestamp is the same for each set of values;
+          }
         }
-      },
-      async: false
-    });
+      }
+      combinedDeferred.resolve(result);
+    }).fail(combinedDeferred.reject);
 
-    console.log(data);
-    console.log(metrics);
-    
-    return $.Deferred().resolve(metrics).promise();
+    return combinedDeferred.promise();
   };
 
   /**

+ 21 - 34
desktop/core/src/desktop/templates/ko_components/ko_performance_graph.mako

@@ -62,24 +62,23 @@
           label: '${ _("1 hour") }',
           totalTime: 1000 * 60 * 60,
           initialWindow: 1000 * 60 * 10,
-          points: 720 // 5 seconds
+          step: 5 * 1000 // 5 seconds
         }, {
           label: '${ _("8 hours") }',
           totalTime: 1000 * 60 * 60 * 8,
           initialWindow: 1000 * 60 * 60 * 2,
-          points: 1920 // 15 seconds
+          step: 15 * 1000 // 15 seconds
         }, {
           label: '${ _("1 week") }',
           totalTime: 1000 * 60 * 60 * 24 * 7,
           initialWindow: 1000 * 60 * 60 * 24,
-          points: 2016 // Every 5 minutes
+          step: 5 * 60 * 1000 // Every 5 minutes
         }];
 
         self.selectedGranularity = ko.observable(self.availableGranularities[ApiHelper.getInstance().getFromTotalStorage('warehouses', 'performanceGraphGranularity', 0)]);
 
         // Load the initial data
-        var now = Date.now();
-        var initialLoadPromise = self.loadData(now - self.selectedGranularity().totalTime, now, self.selectedGranularity().points);
+        var initialLoadPromise = self.loadData();
         self.appendTimeout = -1;
 
         self.componentRendered = function (elements) {
@@ -100,7 +99,7 @@
               }
               window.clearTimeout(self.appendTimeout);
               self.data = undefined;
-              self.loadData(now - granularity.totalTime, now, granularity.points).done(function () {
+              self.loadData().done(function () {
                 self.redrawGraph();
               });
             });
@@ -245,6 +244,7 @@
                     .classed('line line-' + options.id, true)
                     .attr('d', subLine);
             subRefresh = function () {
+              subPath.datum(self.data);
               subPath.attr('d', subLine);
             }
           }
@@ -256,6 +256,7 @@
 
           return {
             refresh: function () {
+              path.datum(self.data)
               path.attr('d', line);
               if (subRefresh) {
                 subRefresh();
@@ -314,9 +315,9 @@
             subLineColor: '#DCDCDC',
             area: true,
             subLine: true,
-            tooltip: function (d) { return d[4] + d[5] + (d[4] ? ' (' + d[4] + ' ${ _("queued") })' : '') },
-            y: function (d) { return queryYScale(d[4] + d[5]) },
-            subY: function (d) { return subQueryYScale(d[4] + d[5]) },
+            tooltip: function (d) { return d[4] + (d[5] ? ' (' + d[5] + ' ${ _("queued") })' : '') },
+            y: function (d) { return queryYScale(d[4]) },
+            subY: function (d) { return subQueryYScale(d[4]) },
             stackedGraph: function () {
               return createLineGraph({
                 id: 'query-count-queued',
@@ -324,7 +325,7 @@
                 color: '#0B7FAD',
                 area: true,
                 disableHighlight: true,
-                y: function (d) { return queryYScale(d[4]) }
+                y: function (d) { return queryYScale(d[5]) }
               })
             }
           }),
@@ -453,16 +454,10 @@
                 .attr('stroke', '#787878')
                 .attr('stroke-width', 7);
 
-        ##  if (self.data[0]) {
-        ##    subGroup.append('g')
-        ##          .attr('class', 'brush')
-        ##          .call(brush)
-        ##          .call(brush.move, [mainXScale(self.data[self.data.length - 1][0] - self.selectedGranularity().initialWindow), mainXScale(self.data[self.data.length - 1][0])]);
-        ##  }
-
-        brushG.call(brush.move, [mainXScale(self.data[self.data.length - 1][0] - self.selectedGranularity().initialWindow), mainXScale(self.data[self.data.length - 1][0])]);
-
-        // TODO: Custom handles
+        brushG.call(brush.move, [
+          mainXScale(Math.max(self.data[self.data.length - 1][0] - self.selectedGranularity().initialWindow, self.data[0][0])),
+          mainXScale(self.data[self.data.length - 1][0])
+        ]);
 
         // Mouse hover overlay
         var dateBisector = d3.bisector(function (d) {
@@ -613,27 +608,19 @@
             mainGroup.select('.main-axis-x').call(mainXAxis);
             subGroup.select('.brush').call(brush);
 
-            self.appendTimeout = window.setTimeout(appendData, self.selectedGranularity().totalTime / self.selectedGranularity().points);
+            self.appendTimeout = window.setTimeout(appendData, self.selectedGranularity().step);
           });
         };
-        self.appendTimeout = window.setTimeout(appendData, self.selectedGranularity().totalTime / self.selectedGranularity().points);
+        self.appendTimeout = window.setTimeout(appendData, self.selectedGranularity().step);
       };
 
-      PerformanceGraph.prototype.loadData = function (startTime, endTime, points) {
+      PerformanceGraph.prototype.loadData = function () {
         var self = this;
         return ApiHelper.getInstance().fetchResourceStats({
-          startTime: startTime,
-          endTime: endTime,
-          points: points
+          pastMs: self.selectedGranularity().totalTime,
+          stepMs: self.selectedGranularity().step
         }).done(function (data) {
-          if (!self.data) {
-            self.data = data;
-          } else {
-            data.forEach(function (newRow) {
-              self.data.shift();
-              self.data.push(newRow);
-            })
-          }
+          self.data = data;
         });
       };