Browse Source

began work on inspection console to visualize metric requests, and other useful troubleshooting info and inspection

Torkel Ödegaard 11 years ago
parent
commit
eb9a7267bd

+ 1 - 0
package.json

@@ -26,6 +26,7 @@
     "grunt-contrib-less": "~0.7.0",
     "grunt-contrib-requirejs": "~0.4.1",
     "grunt-contrib-uglify": "~0.2.4",
+    "grunt-contrib-watch": "^0.6.1",
     "grunt-filerev": "^0.2.1",
     "grunt-git-describe": "~2.3.2",
     "grunt-karma": "~0.8.3",

+ 1 - 1
src/app/app.js

@@ -51,13 +51,13 @@ function (angular, $, _, appLevelRequire, config) {
   app.config(function ($routeProvider, $controllerProvider, $compileProvider, $filterProvider, $provide) {
 
     $routeProvider.otherwise({ redirectTo: config.default_route });
-
     // this is how the internet told me to dynamically add modules :/
     register_fns.controller = $controllerProvider.register;
     register_fns.directive  = $compileProvider.directive;
     register_fns.factory    = $provide.factory;
     register_fns.service    = $provide.service;
     register_fns.filter     = $filterProvider.register;
+
   });
 
   var apps_deps = [

+ 1 - 0
src/app/controllers/all.js

@@ -13,4 +13,5 @@ define([
   './playlistCtrl',
   './inspectCtrl',
   './opentsdbTargetCtrl',
+  './console-ctrl',
 ], function () {});

+ 59 - 0
src/app/controllers/console-ctrl.js

@@ -0,0 +1,59 @@
+define([
+  'angular',
+  'moment',
+],
+function (angular, moment) {
+  'use strict';
+
+  var module = angular.module('grafana.controllers');
+  var consoleEnabled = window.localStorage && window.localStorage.grafanaConsole === 'true';
+
+  if (!consoleEnabled) {
+    return;
+  }
+
+  var events = [];
+
+  function ConsoleEvent(type, title, data) {
+    this.type = type;
+    this.title = title;
+    this.data = data;
+    this.time = moment().format('hh:mm:ss');
+
+    if (data.config) {
+      this.title = data.config.method + ' ' + this.title;
+      this.elapsed = new Date().getTime() - data.config.$grafana_timestamp;
+      this.title = this.title + ' (' + this.elapsed + ' ms)';
+      if (data.config.params && data.config.params.q) {
+        this.query = data.config.params.q;
+      }
+    }
+  }
+
+  module.config(function($httpProvider) {
+    $httpProvider.interceptors.push(function() {
+      return {
+        'request': function(config) {
+          if (config.inspect) {
+            config.$grafana_timestamp = new Date().getTime();
+          }
+          return config;
+        },
+        'response': function(response) {
+          if (response.config.inspect) {
+            events.push(new ConsoleEvent(response.config.inspect.type, response.config.url, response));
+            console.log(response);
+          }
+          return response;
+        }
+      };
+    });
+  });
+
+  module.controller('ConsoleCtrl', function($scope) {
+
+    $scope.events = events;
+
+  });
+
+});

+ 7 - 0
src/app/controllers/grafanaCtrl.js

@@ -18,6 +18,13 @@ function (angular, config, _) {
       $scope.grafana = {
         style: 'dark'
       };
+
+      $scope.consoleEnabled = (window.localStorage && window.localStorage.grafanaConsole === 'true');
+    };
+
+    $scope.toggleConsole = function() {
+      $scope.consoleEnabled = !$scope.consoleEnabled;
+      window.localStorage.grafanaConsole = $scope.consoleEnabled ? 'true' : 'false';
     };
 
     $rootScope.onAppEvent = function(name, callback) {

+ 14 - 0
src/app/partials/console.html

@@ -0,0 +1,14 @@
+<div class="grafana-console" ng-controller="ConsoleCtrl">
+	<div class="grafana-console-header">
+		<span class="grafana-console-title large"><i class="icon-terminal"></i></span>
+	</div>
+	<div class="grafana-console-body">
+		<div class="grafana-console-item" ng-repeat="item in events">
+			<span class="grafana-console-time" ng-bind="item.time"></span>
+			<span class="grafana-console-type">
+				<span class="label label-info" ng-bind="item.type"></span>
+			</span>
+			<span class="grafana-console-title" ng-bind="item.title"></span>
+		</div>
+	</div>
+</div>

+ 3 - 0
src/app/partials/dashboard.html

@@ -121,4 +121,7 @@
     </div>
   </div>
 
+	<div ng-include="'app/partials/console.html'" ng-if="consoleEnabled">
+	</div>
+
 </div>

+ 2 - 1
src/app/partials/dasheditor.html

@@ -25,7 +25,7 @@
           <label class="small">Hide controls (CTRL+H)</label>
           <input type="checkbox" ng-model="dashboard.hideControls" ng-checked="dashboard.hideControls">
         </div>
-      </div>
+     </div>
     </div>
      <div class="editor-row">
       <div class="section">
@@ -98,6 +98,7 @@
     <span class="editor-option small">
       Grafana version: {{grafanaVersion}}
     </span>
+		<span> | <a ng-click="toggleConsole()" ng-show="!consoleEnabled">enable console</a> <a ng-click="toggleConsole()" ng-show="consoleEnabled">disable console</a></span>
     <div class="small" grafana-version-check>
     </div>
   </div>

+ 1 - 0
src/app/services/graphite/graphiteDatasource.js

@@ -205,6 +205,7 @@ function (angular, _, $, config, kbn, moment) {
       }
 
       options.url = this.url + options.url;
+      options.inspect = { type: 'graphite' };
 
       return $http(options);
     };

+ 2 - 1
src/app/services/influxdb/influxdbDatasource.js

@@ -223,7 +223,8 @@ function (angular, _, kbn, InfluxSeries) {
           method: method,
           url:    currentUrl + url,
           params: params,
-          data:   data
+          data:   data,
+          inspect: { type: 'influxdb' },
         };
 
         return $http(options).success(function (data) {

+ 48 - 0
src/css/less/console.less

@@ -0,0 +1,48 @@
+.grafana-console {
+  position: fixed;
+  width: 100%;
+  bottom: 0px;
+  height: 300px;
+  background: @grafanaPanelBackground;
+  border-top: 1px solid @fullEditBorder;
+}
+
+.grafana-console-header {
+  background: @fullEditTabsBackground;
+  border-top: @fullEditTabsBorder;
+  padding: 2px 5px;
+}
+
+.grafana-console-item {
+  .icon-caret-right {
+    font-size: 14px;
+    color: @blue;
+  }
+  margin: 2px 0;
+}
+
+.grafana-console-body {
+  overflow-y: auto;
+  padding-left: 3px;
+}
+
+.grafana-console-type {
+  margin: 0 3px;
+  min-width: 75px;
+  display: inline-block;
+}
+
+.grafana-console-time:before {
+  content: '(';
+  color: rgb(106, 253, 81);
+}
+
+.grafana-console-time:after {
+  content: ')';
+  color: rgb(106, 253, 81);
+}
+
+.grafana-console-time {
+  color: rgb(162, 196, 253);
+}
+

+ 1 - 0
src/css/less/grafana.less

@@ -1,5 +1,6 @@
 @import "submenu.less";
 @import "graph.less";
+@import "console.less";
 @import "bootstrap-tagsinput.less";
 
 .hide-controls {

+ 2 - 1
tasks/default_task.js

@@ -1,5 +1,6 @@
 // Lint and build CSS
 module.exports = function(grunt) {
-  grunt.registerTask('default', ['jscs', 'jshint', 'less:src', 'concat:cssDark', 'concat:cssLight']);
+  grunt.registerTask('css', ['less:src', 'concat:cssDark', 'concat:cssLight']);
+  grunt.registerTask('default', ['jscs', 'jshint', 'css']);
   grunt.registerTask('test', ['default', 'karma:test']);
 };

+ 11 - 0
tasks/options/watch.js

@@ -0,0 +1,11 @@
+module.exports = function(config) {
+  return {
+    css: {
+      files: [ '<%= srcDir %>/css/**/*.less' ],
+      tasks: ['css'],
+      options: {
+        spawn: false
+      }
+    }
+  };
+};