feat(log-viewer): change line count default to 100 and add a since parameter (#2377)

* chore(log-viewer): add the ability to use`since` parameter #1942

https://github.com/portainer/portainer/issues/1942#issuecomment-430246378

* chore(log-viewer): change lineCount to 100 #1942

https://github.com/portainer/portainer/issues/1942#issuecomment-430246378

* fix(log-viewer): js syntax typo for `;` and `'`

forget to lint the code, reported by codeclimate

* fix(log-viewer): use mementjs to format timestamp

1. use moment lib instead of define a function in filter.js(not the right place for this function, removed)
2. set sinceTimestamp init value to `24 hours ago`, as we just need to focus on the relative latest logs after the log-viewer loading, not all the logs(to speedup the process)
3. use moment().unix() to convert the `sinceTimestamp`  to local unix timestamp(not utc)

* chore(log-viewer): add the ability to select the datetime for `since`

* chore(log-viewer): add the ability to fetch logs from specific time
pull/2419/head
pc 2018-10-29 12:49:35 +08:00 committed by Anthony Lapenna
parent a61654a35d
commit 8df64031e8
12 changed files with 39 additions and 15 deletions

View File

@ -5,6 +5,7 @@ angular.module('portainer.docker').component('logViewer', {
data: '=', data: '=',
displayTimestamps: '=', displayTimestamps: '=',
logCollectionChange: '<', logCollectionChange: '<',
sinceTimestamp: '=',
lineCount: '=' lineCount: '='
} }
}); });

View File

@ -35,6 +35,17 @@
</label> </label>
</div> </div>
</div> </div>
<div class="form-group">
<label for="logs_since" class="col-sm-1 control-label text-left">
Fetch
</label>
<div class="col-sm-2">
<select class="form-control" ng-model="$ctrl.sinceTimestamp" id="logs_since">
<option selected value="">All logs</option>
<option ng-repeat="dt in $ctrl.state.availableSinceDatetime" ng-value="dt.value" title="{{ dt.value }}">{{ dt.desc }}</option>
</select>
</div>
</div>
<div class="form-group"> <div class="form-group">
<label for="logs_search" class="col-sm-1 control-label text-left"> <label for="logs_search" class="col-sm-1 control-label text-left">
Search Search

View File

@ -3,6 +3,12 @@ angular.module('portainer.docker')
function (clipboard) { function (clipboard) {
this.state = { this.state = {
availableSinceDatetime: [
{ desc: 'Last day', value: moment().subtract(1, 'days').format() },
{ desc: 'Last 4 hours', value: moment().subtract(4, 'hours').format() },
{ desc: 'Last hour', value: moment().subtract(1, 'hours').format() },
{ desc: 'Last 10 minutes', value: moment().subtract(10, 'minutes').format() }
],
copySupported: clipboard.supported, copySupported: clipboard.supported,
logCollection: true, logCollection: true,
autoScroll: true, autoScroll: true,

View File

@ -140,7 +140,7 @@ function ContainerServiceFactory($q, Container, ResourceControlService, LogHelpe
return deferred.promise; return deferred.promise;
}; };
service.logs = function(id, stdout, stderr, timestamps, tail, stripHeaders) { service.logs = function(id, stdout, stderr, timestamps, since, tail, stripHeaders) {
var deferred = $q.defer(); var deferred = $q.defer();
var parameters = { var parameters = {
@ -148,6 +148,7 @@ function ContainerServiceFactory($q, Container, ResourceControlService, LogHelpe
stdout: stdout || 0, stdout: stdout || 0,
stderr: stderr || 0, stderr: stderr || 0,
timestamps: timestamps || 0, timestamps: timestamps || 0,
since: since || 0,
tail: tail || 'all' tail: tail || 'all'
}; };

View File

@ -59,7 +59,7 @@ function ServiceServiceFactory($q, Service, ServiceHelper, TaskService, Resource
return Service.update({ id: service.Id, version: service.Version }, config).$promise; return Service.update({ id: service.Id, version: service.Version }, config).$promise;
}; };
service.logs = function(id, stdout, stderr, timestamps, tail) { service.logs = function(id, stdout, stderr, timestamps, since, tail) {
var deferred = $q.defer(); var deferred = $q.defer();
var parameters = { var parameters = {
@ -67,6 +67,7 @@ function ServiceServiceFactory($q, Service, ServiceHelper, TaskService, Resource
stdout: stdout || 0, stdout: stdout || 0,
stderr: stderr || 0, stderr: stderr || 0,
timestamps: timestamps || 0, timestamps: timestamps || 0,
since: since || 0,
tail: tail || 'all' tail: tail || 'all'
}; };

View File

@ -36,7 +36,7 @@ function TaskServiceFactory($q, Task, LogHelper) {
return deferred.promise; return deferred.promise;
}; };
service.logs = function(id, stdout, stderr, timestamps, tail) { service.logs = function(id, stdout, stderr, timestamps, since, tail) {
var deferred = $q.defer(); var deferred = $q.defer();
var parameters = { var parameters = {
@ -44,6 +44,7 @@ function TaskServiceFactory($q, Task, LogHelper) {
stdout: stdout || 0, stdout: stdout || 0,
stderr: stderr || 0, stderr: stderr || 0,
timestamps: timestamps || 0, timestamps: timestamps || 0,
since: since || 0,
tail: tail || 'all' tail: tail || 'all'
}; };

View File

@ -3,7 +3,8 @@ angular.module('portainer.docker')
function ($scope, $transition$, $interval, ContainerService, Notifications, HttpRequestHelper) { function ($scope, $transition$, $interval, ContainerService, Notifications, HttpRequestHelper) {
$scope.state = { $scope.state = {
refreshRate: 3, refreshRate: 3,
lineCount: 2000, lineCount: 100,
sinceTimestamp: '',
displayTimestamps: false displayTimestamps: false
}; };
@ -30,7 +31,7 @@ function ($scope, $transition$, $interval, ContainerService, Notifications, Http
function setUpdateRepeater(skipHeaders) { function setUpdateRepeater(skipHeaders) {
var refreshRate = $scope.state.refreshRate; var refreshRate = $scope.state.refreshRate;
$scope.repeater = $interval(function() { $scope.repeater = $interval(function() {
ContainerService.logs($transition$.params().id, 1, 1, $scope.state.displayTimestamps ? 1 : 0, $scope.state.lineCount, skipHeaders) ContainerService.logs($transition$.params().id, 1, 1, $scope.state.displayTimestamps ? 1 : 0, moment($scope.state.sinceTimestamp).unix(), $scope.state.lineCount, skipHeaders)
.then(function success(data) { .then(function success(data) {
$scope.logs = data; $scope.logs = data;
}) })
@ -42,7 +43,7 @@ function ($scope, $transition$, $interval, ContainerService, Notifications, Http
} }
function startLogPolling(skipHeaders) { function startLogPolling(skipHeaders) {
ContainerService.logs($transition$.params().id, 1, 1, $scope.state.displayTimestamps ? 1 : 0, $scope.state.lineCount, skipHeaders) ContainerService.logs($transition$.params().id, 1, 1, $scope.state.displayTimestamps ? 1 : 0, moment($scope.state.sinceTimestamp).unix(), $scope.state.lineCount, skipHeaders)
.then(function success(data) { .then(function success(data) {
$scope.logs = data; $scope.logs = data;
setUpdateRepeater(skipHeaders); setUpdateRepeater(skipHeaders);

View File

@ -6,5 +6,5 @@
</rd-header> </rd-header>
<log-viewer <log-viewer
data="logs" ng-if="logs" log-collection-change="changeLogCollection" display-timestamps="state.displayTimestamps" line-count="state.lineCount" data="logs" ng-if="logs" log-collection-change="changeLogCollection" display-timestamps="state.displayTimestamps" line-count="state.lineCount" since-timestamp="state.sinceTimestamp"
></log-viewer> ></log-viewer>

View File

@ -3,7 +3,8 @@ angular.module('portainer.docker')
function ($scope, $transition$, $interval, ServiceService, Notifications) { function ($scope, $transition$, $interval, ServiceService, Notifications) {
$scope.state = { $scope.state = {
refreshRate: 3, refreshRate: 3,
lineCount: 2000, lineCount: 100,
sinceTimestamp: '',
displayTimestamps: false displayTimestamps: false
}; };
@ -30,7 +31,7 @@ function ($scope, $transition$, $interval, ServiceService, Notifications) {
function setUpdateRepeater() { function setUpdateRepeater() {
var refreshRate = $scope.state.refreshRate; var refreshRate = $scope.state.refreshRate;
$scope.repeater = $interval(function() { $scope.repeater = $interval(function() {
ServiceService.logs($transition$.params().id, 1, 1, $scope.state.displayTimestamps ? 1 : 0, $scope.state.lineCount) ServiceService.logs($transition$.params().id, 1, 1, $scope.state.displayTimestamps ? 1 : 0, moment($scope.state.sinceTimestamp).unix(), $scope.state.lineCount)
.then(function success(data) { .then(function success(data) {
$scope.logs = data; $scope.logs = data;
}) })
@ -42,7 +43,7 @@ function ($scope, $transition$, $interval, ServiceService, Notifications) {
} }
function startLogPolling() { function startLogPolling() {
ServiceService.logs($transition$.params().id, 1, 1, $scope.state.displayTimestamps ? 1 : 0, $scope.state.lineCount) ServiceService.logs($transition$.params().id, 1, 1, $scope.state.displayTimestamps ? 1 : 0, moment($scope.state.sinceTimestamp).unix(), $scope.state.lineCount)
.then(function success(data) { .then(function success(data) {
$scope.logs = data; $scope.logs = data;
setUpdateRepeater(); setUpdateRepeater();

View File

@ -6,5 +6,5 @@
</rd-header> </rd-header>
<log-viewer <log-viewer
data="logs" ng-if="logs" log-collection-change="changeLogCollection" display-timestamps="state.displayTimestamps" line-count="state.lineCount" data="logs" ng-if="logs" log-collection-change="changeLogCollection" display-timestamps="state.displayTimestamps" line-count="state.lineCount" since-timestamp="state.sinceTimestamp"
></log-viewer> ></log-viewer>

View File

@ -3,7 +3,8 @@ angular.module('portainer.docker')
function ($scope, $transition$, $interval, TaskService, ServiceService, Notifications) { function ($scope, $transition$, $interval, TaskService, ServiceService, Notifications) {
$scope.state = { $scope.state = {
refreshRate: 3, refreshRate: 3,
lineCount: 2000, lineCount: 100,
sinceTimestamp: '',
displayTimestamps: false displayTimestamps: false
}; };
@ -30,7 +31,7 @@ function ($scope, $transition$, $interval, TaskService, ServiceService, Notifica
function setUpdateRepeater() { function setUpdateRepeater() {
var refreshRate = $scope.state.refreshRate; var refreshRate = $scope.state.refreshRate;
$scope.repeater = $interval(function() { $scope.repeater = $interval(function() {
TaskService.logs($transition$.params().id, 1, 1, $scope.state.displayTimestamps ? 1 : 0, $scope.state.lineCount) TaskService.logs($transition$.params().id, 1, 1, $scope.state.displayTimestamps ? 1 : 0, moment($scope.state.sinceTimestamp).unix(), $scope.state.lineCount)
.then(function success(data) { .then(function success(data) {
$scope.logs = data; $scope.logs = data;
}) })
@ -42,7 +43,7 @@ function ($scope, $transition$, $interval, TaskService, ServiceService, Notifica
} }
function startLogPolling() { function startLogPolling() {
TaskService.logs($transition$.params().id, 1, 1, $scope.state.displayTimestamps ? 1 : 0, $scope.state.lineCount) TaskService.logs($transition$.params().id, 1, 1, $scope.state.displayTimestamps ? 1 : 0, moment($scope.state.sinceTimestamp).unix(), $scope.state.lineCount)
.then(function success(data) { .then(function success(data) {
$scope.logs = data; $scope.logs = data;
setUpdateRepeater(); setUpdateRepeater();

View File

@ -6,5 +6,5 @@
</rd-header> </rd-header>
<log-viewer <log-viewer
data="logs" ng-if="logs" log-collection-change="changeLogCollection" display-timestamps="state.displayTimestamps" line-count="state.lineCount" data="logs" ng-if="logs" log-collection-change="changeLogCollection" display-timestamps="state.displayTimestamps" line-count="state.lineCount" since-timestamp="state.sinceTimestamp"
></log-viewer> ></log-viewer>