diff --git a/app/app.js b/app/app.js index bba4ad835..b81cb3a5a 100644 --- a/app/app.js +++ b/app/app.js @@ -25,6 +25,7 @@ angular.module('portainer', [ 'container', 'containerConsole', 'containerLogs', + 'serviceLogs', 'containers', 'createContainer', 'createNetwork', @@ -166,7 +167,7 @@ angular.module('portainer', [ } } }) - .state('logs', { + .state('containerlogs', { url: '^/containers/:id/logs', views: { 'content@': { @@ -179,6 +180,19 @@ angular.module('portainer', [ } } }) + .state('servicelogs', { + url: '^/services/:id/logs', + views: { + 'content@': { + templateUrl: 'app/components/serviceLogs/servicelogs.html', + controller: 'ServiceLogsController' + }, + 'sidebar@': { + templateUrl: 'app/components/sidebar/sidebar.html', + controller: 'SidebarController' + } + } + }) .state('console', { url: '^/containers/:id/console', views: { diff --git a/app/components/container/container.html b/app/components/container/container.html index 5961a3c89..f2ee6c857 100644 --- a/app/components/container/container.html +++ b/app/components/container/container.html @@ -75,7 +75,7 @@
Stats - Logs + Logs Console
diff --git a/app/components/service/service.html b/app/components/service/service.html index 8d89268a2..4d15c6045 100644 --- a/app/components/service/service.html +++ b/app/components/service/service.html @@ -72,6 +72,13 @@ + + +
+ Logs +
+ + diff --git a/app/components/serviceLogs/serviceLogsController.js b/app/components/serviceLogs/serviceLogsController.js new file mode 100644 index 000000000..9895bbb6e --- /dev/null +++ b/app/components/serviceLogs/serviceLogsController.js @@ -0,0 +1,83 @@ +angular.module('serviceLogs', []) +.controller('ServiceLogsController', ['$scope', '$stateParams', '$anchorScroll', 'ServiceLogs', 'Service', +function ($scope, $stateParams, $anchorScroll, ServiceLogs, Service) { + $scope.state = {}; + $scope.state.displayTimestampsOut = false; + $scope.state.displayTimestampsErr = false; + $scope.stdout = ''; + $scope.stderr = ''; + $scope.tailLines = 2000; + + function getLogs() { + $('#loadingViewSpinner').show(); + getLogsStdout(); + getLogsStderr(); + $('#loadingViewSpinner').hide(); + } + + function getLogsStderr() { + ServiceLogs.get($stateParams.id, { + stdout: 0, + stderr: 1, + timestamps: $scope.state.displayTimestampsErr, + tail: $scope.tailLines + }, function (data, status, headers, config) { + // Replace carriage returns with newlines to clean up output + data = data.replace(/[\r]/g, '\n'); + // Strip 8 byte header from each line of output + data = data.substring(8); + data = data.replace(/\n(.{8})/g, '\n'); + $scope.stderr = data; + }); + } + + function getLogsStdout() { + ServiceLogs.get($stateParams.id, { + stdout: 1, + stderr: 0, + timestamps: $scope.state.displayTimestampsOut, + tail: $scope.tailLines + }, function (data, status, headers, config) { + // Replace carriage returns with newlines to clean up output + data = data.replace(/[\r]/g, '\n'); + // Strip 8 byte header from each line of output + data = data.substring(8); + data = data.replace(/\n(.{8})/g, '\n'); + $scope.stdout = data; + }); + } + + function getService() { + $('#loadingViewSpinner').show(); + Service.get({id: $stateParams.id}, function (d) { + $scope.service = d; + $('#loadingViewSpinner').hide(); + }, function (e) { + Notifications.error('Failure', e, 'Unable to retrieve service info'); + $('#loadingViewSpinner').hide(); + }); + } + + function initView() { + getService(); + getLogs(); + + var logIntervalId = window.setInterval(getLogs, 5000); + + $scope.$on('$destroy', function () { + // clearing interval when view changes + clearInterval(logIntervalId); + }); + + $scope.toggleTimestampsOut = function () { + getLogsStdout(); + }; + + $scope.toggleTimestampsErr = function () { + getLogsStderr(); + }; + } + + initView(); + +}]); diff --git a/app/components/serviceLogs/servicelogs.html b/app/components/serviceLogs/servicelogs.html new file mode 100644 index 000000000..3bbe090e2 --- /dev/null +++ b/app/components/serviceLogs/servicelogs.html @@ -0,0 +1,56 @@ + + + + + + Services > {{ service.Spec.Name }} > Logs + + + +
+
+ + +
+ +
+
{{ service.Spec.Name }}
+
Name
+
+
+
+
+ +
+
+ + + + + + + +
+
{{stdout}}
+
+
+
+
+
+ +
+
+ + + + + + + +
+
{{stderr}}
+
+
+
+
+
diff --git a/app/rest/docker/serviceLogs.js b/app/rest/docker/serviceLogs.js new file mode 100644 index 000000000..b165b2542 --- /dev/null +++ b/app/rest/docker/serviceLogs.js @@ -0,0 +1,20 @@ +angular.module('portainer.rest') +.factory('ServiceLogs', ['$http', 'DOCKER_ENDPOINT', 'EndpointProvider', function ServiceLogsFactory($http, DOCKER_ENDPOINT, EndpointProvider) { + 'use strict'; + return { + get: function (id, params, callback) { + $http({ + method: 'GET', + url: DOCKER_ENDPOINT + '/' + EndpointProvider.endpointID() + '/services/' + id + '/logs', + params: { + 'stdout': params.stdout || 0, + 'stderr': params.stderr || 0, + 'timestamps': params.timestamps || 0, + 'tail': params.tail || 'all' + } + }).success(callback).error(function (data, status, headers, config) { + console.log(error, data); + }); + } + }; +}]);