diff --git a/app/app.js b/app/app.js
index 48fcc4075..e1ae120f4 100644
--- a/app/app.js
+++ b/app/app.js
@@ -1,10 +1,11 @@
'use strict';
-angular.module('dockerui', ['ngRoute', 'dockerui.services', 'dockerui.filters', 'masthead', 'footer', 'dashboard', 'container', 'containers', 'images', 'image', 'startContainer', 'sidebar', 'settings', 'builder'])
+angular.module('dockerui', ['ngRoute', 'dockerui.services', 'dockerui.filters', 'masthead', 'footer', 'dashboard', 'container', 'containers', 'images', 'image', 'startContainer', 'sidebar', 'settings', 'builder', 'containerLogs'])
.config(['$routeProvider', function ($routeProvider) {
$routeProvider.when('/', {templateUrl: 'app/components/dashboard/dashboard.html', controller: 'DashboardController'});
$routeProvider.when('/containers/', {templateUrl: 'app/components/containers/containers.html', controller: 'ContainersController'});
$routeProvider.when('/containers/:id/', {templateUrl: 'app/components/container/container.html', controller: 'ContainerController'});
+ $routeProvider.when('/containers/:id/logs/', {templateUrl: 'app/components/containerLogs/containerlogs.html', controller: 'ContainerLogsController'});
$routeProvider.when('/images/', {templateUrl: 'app/components/images/images.html', controller: 'ImagesController'});
$routeProvider.when('/images/:id/', {templateUrl: 'app/components/image/image.html', controller: 'ImageController'});
$routeProvider.when('/settings', {templateUrl: 'app/components/settings/settings.html', controller: 'SettingsController'});
diff --git a/app/components/container/container.html b/app/components/container/container.html
index 3b4ec9969..82edb403a 100644
--- a/app/components/container/container.html
+++ b/app/components/container/container.html
@@ -99,6 +99,10 @@
State: |
{{ container.State|getstatetext }} |
+
+ Logs: |
+ stdout/stderr |
+
diff --git a/app/components/container/containerController.js b/app/components/container/containerController.js
index 8ec9cb1e2..852da8cbb 100644
--- a/app/components/container/containerController.js
+++ b/app/components/container/containerController.js
@@ -4,6 +4,7 @@ function($scope, $routeParams, $location, Container, Messages, ViewSpinner) {
$scope.changes = [];
var update = function() {
+ ViewSpinner.spin();
Container.get({id: $routeParams.id}, function(d) {
$scope.container = d;
ViewSpinner.stop();
diff --git a/app/components/containerLogs/containerLogsController.js b/app/components/containerLogs/containerLogsController.js
new file mode 100644
index 000000000..2b1bd3c87
--- /dev/null
+++ b/app/components/containerLogs/containerLogsController.js
@@ -0,0 +1,48 @@
+angular.module('containerLogs', [])
+.controller('ContainerLogsController', ['$scope', '$routeParams', '$location', '$anchorScroll', 'ContainerLogs', 'Container', 'ViewSpinner',
+function($scope, $routeParams, $location, $anchorScroll, ContainerLogs, Container, ViewSpinner) {
+ $scope.stdout = '';
+ $scope.stderr = '';
+ $scope.showTimestamps = false;
+
+ ViewSpinner.spin();
+ Container.get({id: $routeParams.id}, function(d) {
+ $scope.container = d;
+ ViewSpinner.stop();
+ }, function(e) {
+ if (e.status === 404) {
+ Messages.error("Not found", "Container not found.");
+ } else {
+ Messages.error("Failure", e.data);
+ }
+ ViewSpinner.stop();
+ });
+
+ function getLogs() {
+ ContainerLogs.get($routeParams.id, {stdout: 1, stderr: 0, timestamps: $scope.showTimestamps}, function(data, status, headers, config) {
+ // Replace carriage returns twith newlines to clean up output
+ $scope.stdout = data.replace(/[\r]/g, '\n');
+ });
+ ContainerLogs.get($routeParams.id, {stdout: 0, stderr: 1}, function(data, status, headers, config) {
+ $scope.stderr = data.replace(/[\r]/g, '\n');
+ });
+ }
+
+ // initial call
+ getLogs();
+ var logIntervalId = window.setInterval(getLogs, 5000);
+
+ $scope.$on("$destroy", function(){
+ // clearing interval when view changes
+ clearInterval(logIntervalId);
+ });
+
+ $scope.scrollTo = function(id) {
+ $location.hash(id);
+ $anchorScroll();
+ }
+
+ $scope.toggleTimestamps = function() {
+ getLogs();
+ }
+}]);
diff --git a/app/components/containerLogs/containerlogs.html b/app/components/containerLogs/containerlogs.html
new file mode 100644
index 000000000..ea81ad08e
--- /dev/null
+++ b/app/components/containerLogs/containerlogs.html
@@ -0,0 +1,34 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/app/shared/services.js b/app/shared/services.js
index a8876f32c..57fd14e83 100644
--- a/app/shared/services.js
+++ b/app/shared/services.js
@@ -20,6 +20,19 @@ angular.module('dockerui.services', ['ngResource'])
remove: {method: 'DELETE', params: {id: '@id', v:0}}
});
})
+ .factory('ContainerLogs', function($resource, $http, Settings) {
+ return {
+ get: function(id, params, callback) {
+ $http({
+ method: 'GET',
+ url: Settings.url + '/containers/'+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);
+ });
+ }
+ }
+ })
.factory('Image', function($resource, Settings) {
// Resource for docker images
// http://docs.docker.io/en/latest/api/docker_remote_api.html#images
diff --git a/assets/css/app.css b/assets/css/app.css
index 281b45f61..5fe8e24a8 100644
--- a/assets/css/app.css
+++ b/assets/css/app.css
@@ -36,6 +36,7 @@ body {
.masthead .nav {
margin: 0;
+ margin: 0 0 2em 0;
width: 100%;
}
@@ -120,3 +121,9 @@ body {
border-width: 0 0 0 1em;
padding: 0 0.3em;
}
+
+pre.pre-x-scrollable {
+ max-height: 700px;
+ word-wrap: normal;
+ white-space: pre;
+}
diff --git a/index.html b/index.html
index 6307d2771..1492f4953 100644
--- a/index.html
+++ b/index.html
@@ -41,6 +41,7 @@
+