feat(dashboard): new Dashboard

- show providers (auto refresh: 2s)
- show health (auto refresh: 3s)
- more colors
- add font
- remove jumbotron
- javascript minified version
This commit is contained in:
Fernandez Ludovic 2015-10-05 16:11:43 +02:00
parent da3d119a43
commit ac57dda074
24 changed files with 420 additions and 0 deletions

View file

@ -0,0 +1,10 @@
(function () {
'use strict';
angular
.module('traefik.core.health', ['ngResource'])
.factory('Health', ['$resource', function ($resource) {
return $resource('/health');
}]);
})();

View file

@ -0,0 +1,10 @@
(function () {
'use strict';
angular
.module('traefik.core.provider', ['ngResource'])
.factory('Providers', ['$resource', function ($resource) {
return $resource('/api/providers');
}]);
})();

View file

@ -0,0 +1,26 @@
(function () {
'use strict';
angular.module('traefik.section.health')
.controller('HealthController', ['$scope', '$interval', '$log', 'Health', function ($scope, $interval, $log, Health) {
var vm = this;
vm.health = Health.get();
var intervalId = $interval(function () {
Health.get(function (health) {
vm.health = health;
}, function (error) {
vm.health = {};
$log.error(error);
});
}, 3000);
$scope.$on('$destroy', function () {
$interval.cancel(intervalId);
});
}]);
})();

View file

@ -0,0 +1,46 @@
<div>
<h1 class="text-danger">
<span class="glyphicon glyphicon-heart" aria-hidden="true"></span> Health
</h1>
<ul class="list-group">
<li class="list-group-item">
<span>Average response time sec :</span><span class="badge">{{healthCtrl.health.average_response_time_sec}}</span>
</li>
<li class="list-group-item">
<span>Average response time :</span><span class="badge">{{healthCtrl.health.average_response_time}}</span>
</li>
<li class="list-group-item">
<span>Total response time sec :</span><span class="badge">{{healthCtrl.health.total_response_time_sec}}</span>
</li>
<li class="list-group-item">
<span>Total response time :</span><span class="badge">{{healthCtrl.health.total_response_time}}</span>
</li>
<li class="list-group-item">
<span>Total count :</span><span class="badge">{{healthCtrl.health.total_count}}</span>
</li>
<li class="list-group-item">
<span>PID :</span><span class="badge">{{healthCtrl.health.pid}}</span>
</li>
<li class="list-group-item">
<span>Uptime :</span><span class="badge">{{healthCtrl.health.uptime}}</span>
</li>
<li class="list-group-item">
<span>Uptime sec :</span><span class="badge">{{healthCtrl.health.uptime_sec}}</span>
</li>
<li class="list-group-item">
<span>Time :</span><span class="badge">{{healthCtrl.health.time}}</span>
</li>
<li class="list-group-item">
<span>Unixtime :</span><span class="badge">{{healthCtrl.health.unixtime}}</span>
</li>
<li class="list-group-item">
<span>Status code count :</span><span class="badge">{{healthCtrl.health.status_code_count}}</span>
</li>
<li class="list-group-item">
<span>Total status code count :</span><span class="badge">{{healthCtrl.health.total_status_code_count}}</span>
</li>
<li class="list-group-item">
<span>Count :</span><span class="badge">{{healthCtrl.health.count}}</span>
</li>
</ul>
</div>

View file

@ -0,0 +1,16 @@
(function () {
'use strict';
angular.module('traefik.section.health', ['traefik.core.health'])
.config(['$stateProvider', function ($stateProvider) {
$stateProvider.state('health', {
url: '/health',
templateUrl: 'app/sections/health/health.html',
controller: 'HealthController',
controllerAs: 'healthCtrl'
});
}]);
})();

View file

@ -0,0 +1,10 @@
(function () {
'use strict';
angular
.module('traefik.section.providers.backend-monitor')
.controller('BackendMonitorController', function () {
});
})();

View file

@ -0,0 +1,21 @@
(function () {
'use strict';
angular
.module('traefik.section.providers.backend-monitor')
.directive('backendMonitor', function () {
return {
restrict: 'EA',
templateUrl: 'app/sections/providers/backend-monitor/backend-monitor.html',
controller: 'BackendMonitorController',
controllerAs: 'backendCtrl',
bindToController: true,
scope: {
backend: '=',
backendId: '=',
providerId: '='
}
};
});
})();

View file

@ -0,0 +1,23 @@
<div class="panel panel-success">
<div class="panel-heading">
<strong><span class="glyphicon glyphicon-tasks" aria-hidden="true"></span> {{backendCtrl.backendId}}</strong> [{{backendCtrl.providerId}}]
</div>
<div class="panel-body">
<table class="panel-table__servers table table-striped table-hover">
<tr>
<td><em>Server</em></td>
<td><em>URL</em></td>
<td><em>Weight</em></td>
</tr>
<tr data-ng-repeat="(serverId, server) in backendCtrl.backend.Servers">
<td>{{serverId}}</td>
<td><code><a data-ng-href="{{server.url}}">{{server.URL}}</a></code></td>
<td>{{server.Weight}}</td>
</tr>
</table>
</div>
<div class="panel-footer" data-ng-show="backendCtrl.backend.LoadBalancer || backendCtrl.backend.CircuitBreaker">
<span data-ng-show="backendCtrl.backend.LoadBalancer" class="label label-success">Load Balancer: {{backendCtrl.backend.LoadBalancer.Method}}</span>
<span data-ng-show="backendCtrl.backend.CircuitBreaker" class="label label-success">Circuit Breaker: {{backendCtrl.backend.CircuitBreaker.Expression}}</span>
</div>
</div>

View file

@ -0,0 +1,7 @@
(function () {
'use strict';
angular
.module('traefik.section.providers.backend-monitor', []);
})();

View file

@ -0,0 +1,10 @@
(function () {
'use strict';
angular
.module('traefik.section.providers.frontend-monitor')
.controller('FrontendMonitorController', function () {
});
})();

View file

@ -0,0 +1,21 @@
(function () {
'use strict';
angular
.module('traefik.section.providers.frontend-monitor')
.directive('frontendMonitor', function () {
return {
restrict: 'EA',
templateUrl: 'app/sections/providers/frontend-monitor/frontend-monitor.html',
controller: 'FrontendMonitorController',
controllerAs: 'frontendCtrl',
bindToController: true,
scope: {
frontend: '=',
frontendId: '=',
providerId: '='
}
};
});
})();

View file

@ -0,0 +1,22 @@
<div class="panel panel-warning">
<div class="panel-heading">
<strong><span class="glyphicon glyphicon-globe" aria-hidden="true"></span> {{frontendCtrl.frontendId}}</strong> [{{frontendCtrl.providerId}}]
</div>
<div class="panel-body">
<table class="panel-table__routes table table-striped table-hover">
<tr>
<td><em>Route</em></td>
<td><em>Rule</em></td>
<td><em>Value</em></td>
</tr>
<tr data-ng-repeat="(routeId, route) in frontendCtrl.frontend.Routes">
<td>{{routeId}}</td>
<td>{{route.Rule}}</td>
<td><code>{{route.Value}}</code></td>
</tr>
</table>
</div>
<div data-bg-show="frontendCtrl.frontend.Backend" class="panel-footer">
<span class="label label-warning" role="button" data-toggle="collapse" href="#{{frontendCtrl.frontend.Backend}}" aria-expanded="false">{{frontendCtrl.frontend.Backend}}</span>
</div>
</div>

View file

@ -0,0 +1,6 @@
(function () {
'use strict';
angular.module('traefik.section.providers.frontend-monitor', []);
})();

View file

@ -0,0 +1,27 @@
(function () {
'use strict';
angular
.module('traefik.section.providers')
.controller('ProvidersController', ['$scope', '$interval', '$log', 'Providers', function ($scope, $interval, $log, Providers) {
var vm = this;
vm.providers = Providers.get();
var intervalId = $interval(function () {
Providers.get(function (providers) {
vm.providers = providers;
}, function (error) {
vm.providers = {};
$log.error(error);
});
}, 2000);
$scope.$on('$destroy', function () {
$interval.cancel(intervalId);
});
}]);
})();

View file

@ -0,0 +1,14 @@
<!--{{providersCtrl.providers}}-->
<div class="row" data-ng-repeat="(providerId, provider) in providersCtrl.providers">
<div class="col-md-6">
<div data-ng-repeat="(frontendId, frontend) in provider.Frontends">
<frontend-monitor data-provider-id="providerId" data-frontend-id="frontendId" data-frontend="frontend"></frontend-monitor>
</div>
</div>
<div class="col-md-6">
<div data-ng-repeat="(backendId, backend) in provider.Backends">
<backend-monitor data-provider-id="providerId" data-backend-id="backendId" data-backend="backend"></backend-monitor>
</div>
</div>
</div>

View file

@ -0,0 +1,21 @@
(function () {
'use strict';
angular
.module('traefik.section.providers', [
'traefik.core.provider',
'traefik.section.providers.backend-monitor',
'traefik.section.providers.frontend-monitor'
])
.config(['$stateProvider', function ($stateProvider) {
$stateProvider.state('provider', {
url: '/',
templateUrl: 'app/sections/providers/providers.html',
controller: 'ProvidersController',
controllerAs: 'providersCtrl'
});
}]);
})();

View file

@ -0,0 +1,12 @@
(function () {
'use strict';
angular
.module('traefik.section')
.config(['$urlRouterProvider', function ($urlRouterProvider) {
$urlRouterProvider.otherwise('/');
}]);
})();

View file

@ -0,0 +1,11 @@
(function () {
'use strict';
angular
.module('traefik.section', [
'ui.router',
'traefik.section.providers',
'traefik.section.health'
]);
})();

6
static/app/traefik.js Normal file
View file

@ -0,0 +1,6 @@
(function () {
'use strict';
angular.module('traefik', ['traefik.section']);
})();

Binary file not shown.

Binary file not shown.

Binary file not shown.

79
static/index.html Normal file
View file

@ -0,0 +1,79 @@
<!doctype html>
<html lang="en" data-ng-app="traefik">
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0, maximum-scale=1.0, user-scalable=no">
<title>/ˈTræfɪk/</title>
<link rel="icon" type="image/png" href="favicon.png">
<!-- Bootstrap -->
<link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap.min.css">
<link rel="stylesheet" href="bower_components/bootstrap/dist/css/bootstrap-theme.min.css">
<link rel="stylesheet" href="style.css">
</head>
<body>
<div class="container">
<header>
<nav class="navbar navbar-default">
<div class="container-fluid">
<div class="navbar-header">
<a class="navbar-brand traefik-texttraefik-text" ui-sref="provider">/ˈTr<span class="traefik-blue">æ</span>fɪk/</a>
</div>
<div class="collapse navbar-collapse">
<ul class="nav navbar-nav">
<li><a ui-sref="provider" class="active">Providers</a></li>
<li><a ui-sref="health">Health</a></li>
</ul>
<ul class="nav navbar-nav navbar-right">
<li>
<a href="https://github.com/EmileVauge/traefik/blob/master/docs/index.md" target="_blank">Documentation</a>
</li>
<li>
<a href="http://traefik.io" target="_blank"><span class="traefik-blue">traefik.io</span></a>
</li>
</ul>
</div>
</div>
</nav>
</header>
<main class="main">
<div data-ui-view></div>
</main>
</div>
<!-- vendors -->
<script src="bower_components/jquery/dist/jquery.min.js"></script>
<script src="bower_components/bootstrap/dist/js/bootstrap.min.js"></script>
<script src="bower_components/angular/angular.min.js"></script>
<script src="bower_components/angular-resource/angular-resource.min.js"></script>
<script src="bower_components/angular-ui-router/release/angular-ui-router.min.js"></script>
<!-- end vendors -->
<script src="app/traefik.js"></script>
<script src="app/core/providers.resource.js"></script>
<script src="app/core/health.resource.js"></script>
<script src="app/sections/providers/backend-monitor/backend-monitor.module.js"></script>
<script src="app/sections/providers/backend-monitor/backend-monitor.controller.js"></script>
<script src="app/sections/providers/backend-monitor/backend-monitor.directive.js"></script>
<script src="app/sections/providers/frontend-monitor/frontend-monitor.module.js"></script>
<script src="app/sections/providers/frontend-monitor/frontend-monitor.controller.js"></script>
<script src="app/sections/providers/frontend-monitor/frontend-monitor.directive.js"></script>
<script src="app/sections/providers/providers.module.js"></script>
<script src="app/sections/providers/providers.controller.js"></script>
<script src="app/sections/health/health.module.js"></script>
<script src="app/sections/health/health.controller.js"></script>
<script src="app/sections/sections.module.js"></script>
<script src="app/sections/sections.config.js"></script>
</body>
</html>

22
static/style.css Normal file
View file

@ -0,0 +1,22 @@
@font-face {
font-family: 'charterregular';
src: url('fontss/charter_regular-webfont.eot');
src: url('fontss/charter_regular-webfont.eot?#iefix') format('embedded-opentype'),
url('fontss/charter_regular-webfont.woff') format('woff');
font-weight: normal;
font-style: normal;
}
.traefik-blue {
color: #00B1FF;
}
.traefik-text {
font-family: 'WebFont', Arial, sans-serif;
}
.panel-body .panel-table__servers,
.panel-body .panel-table__routes {
margin-bottom: 0;
}