Closes #220: background tasks count

This commit is contained in:
Benjamin Gamard 2018-04-22 11:12:09 +02:00
parent dd1c06013b
commit 763f91fd4c
11 changed files with 74 additions and 43 deletions

View File

@ -68,7 +68,7 @@ public class AppContext {
/** /**
* Asynchronous executors. * Asynchronous executors.
*/ */
private List<ExecutorService> asyncExecutorList; private List<ThreadPoolExecutor> asyncExecutorList;
/** /**
* Start the application context. * Start the application context.
@ -181,6 +181,19 @@ public class AppContext {
} }
} }
/**
* Return the current number of queued tasks waiting to be processed.
*
* @return Number of queued tasks
*/
public int getQueuedTaskCount() {
int queueSize = 0;
for (ThreadPoolExecutor executor : asyncExecutorList) {
queueSize += executor.getQueue().size();
}
return queueSize;
}
public EventBus getAsyncEventBus() { public EventBus getAsyncEventBus() {
return asyncEventBus; return asyncEventBus;
} }

View File

@ -66,6 +66,8 @@ public class AppResource extends BaseResource {
* @apiSuccess {String} current_version API current version * @apiSuccess {String} current_version API current version
* @apiSuccess {String} min_version API minimum version * @apiSuccess {String} min_version API minimum version
* @apiSuccess {Boolean} guest_login True if guest login is enabled * @apiSuccess {Boolean} guest_login True if guest login is enabled
* @apiSuccess {String} default_language Default platform language
* @apiSuccess {Number} queued_tasks Number of queued tasks waiting to be processed
* @apiSuccess {String} total_memory Allocated JVM memory (in bytes) * @apiSuccess {String} total_memory Allocated JVM memory (in bytes)
* @apiSuccess {String} free_memory Free JVM memory (in bytes) * @apiSuccess {String} free_memory Free JVM memory (in bytes)
* @apiSuccess {String} document_count Number of documents * @apiSuccess {String} document_count Number of documents
@ -97,6 +99,7 @@ public class AppResource extends BaseResource {
.add("min_version", minVersion) .add("min_version", minVersion)
.add("guest_login", guestLogin) .add("guest_login", guestLogin)
.add("default_language", defaultLanguage) .add("default_language", defaultLanguage)
.add("queued_tasks", AppContext.getInstance().getQueuedTaskCount())
.add("total_memory", Runtime.getRuntime().totalMemory()) .add("total_memory", Runtime.getRuntime().totalMemory())
.add("free_memory", Runtime.getRuntime().freeMemory()) .add("free_memory", Runtime.getRuntime().freeMemory())
.add("document_count", documentDao.getDocumentCount()) .add("document_count", documentDao.getDocumentCount())

View File

@ -118,12 +118,12 @@ angular.module('docs',
} }
} }
}) })
.state('settings.log', { .state('settings.monitoring', {
url: '/log', url: '/monitoring',
views: { views: {
'settings': { 'settings': {
templateUrl: 'partial/docs/settings.log.html', templateUrl: 'partial/docs/settings.monitoring.html',
controller: 'SettingsLog' controller: 'SettingsMonitoring'
} }
} }
}) })

View File

@ -1,12 +0,0 @@
'use strict';
/**
* Settings logs controller.
*/
angular.module('docs').controller('SettingsLog', function($scope, Restangular) {
Restangular.one('app/log').get({
limit: 100
}).then(function(data) {
$scope.logs = data.logs;
});
});

View File

@ -0,0 +1,16 @@
'use strict';
/**
* Settings monitoring controller.
*/
angular.module('docs').controller('SettingsMonitoring', function($scope, Restangular) {
Restangular.one('app').get().then(function(data) {
$scope.app = data;
});
Restangular.one('app/log').get({
limit: 100
}).then(function(data) {
$scope.logs = data.logs;
});
});

View File

@ -82,7 +82,7 @@
<script src="app/docs/controller/settings/SettingsSecurity.js" type="text/javascript"></script> <script src="app/docs/controller/settings/SettingsSecurity.js" type="text/javascript"></script>
<script src="app/docs/controller/settings/SettingsSecurityModalDisableTotp.js" type="text/javascript"></script> <script src="app/docs/controller/settings/SettingsSecurityModalDisableTotp.js" type="text/javascript"></script>
<script src="app/docs/controller/settings/SettingsSession.js" type="text/javascript"></script> <script src="app/docs/controller/settings/SettingsSession.js" type="text/javascript"></script>
<script src="app/docs/controller/settings/SettingsLog.js" type="text/javascript"></script> <script src="app/docs/controller/settings/SettingsMonitoring.js" type="text/javascript"></script>
<script src="app/docs/controller/settings/SettingsWorkflow.js" type="text/javascript"></script> <script src="app/docs/controller/settings/SettingsWorkflow.js" type="text/javascript"></script>
<script src="app/docs/controller/settings/SettingsWorkflowEdit.js" type="text/javascript"></script> <script src="app/docs/controller/settings/SettingsWorkflowEdit.js" type="text/javascript"></script>
<script src="app/docs/controller/settings/SettingsUser.js" type="text/javascript"></script> <script src="app/docs/controller/settings/SettingsUser.js" type="text/javascript"></script>

View File

@ -262,7 +262,7 @@
"menu_vocabularies": "Vocabularies", "menu_vocabularies": "Vocabularies",
"menu_configuration": "Configuration", "menu_configuration": "Configuration",
"menu_inbox": "Inbox scanning", "menu_inbox": "Inbox scanning",
"menu_server_logs": "Server logs", "menu_monitoring": "Monitoring",
"user": { "user": {
"title": "Users management", "title": "Users management",
"add_user": "Add a user", "add_user": "Add a user",
@ -393,11 +393,14 @@
"test_success": "The connection to the inbox is successful ({{ count }} <strong>unread</strong> message{{ count > 1 ? 's' : '' }})", "test_success": "The connection to the inbox is successful ({{ count }} <strong>unread</strong> message{{ count > 1 ? 's' : '' }})",
"test_fail": "An error occurred while connecting to the inbox, please check the parameters" "test_fail": "An error occurred while connecting to the inbox, please check the parameters"
}, },
"log": { "monitoring": {
"title": "Server logs", "background_tasks": "Background tasks",
"date": "Date", "queued_tasks": "There is currently {{ count }} queued tasks.",
"tag": "Tag", "queued_tasks_explain": "File processing, thumbnail creation, index update, optical character recognition are background tasks. A large amount of unprocessed tasks will result in incomplete search results.",
"message": "Message" "server_logs": "Server logs",
"log_date": "Date",
"log_tag": "Tag",
"log_message": "Message"
}, },
"session": { "session": {
"title": "Opened sessions", "title": "Opened sessions",

View File

@ -19,7 +19,7 @@
<a class="list-group-item" ui-sref-active="{ active: 'settings.inbox.**' }" href="#/settings/inbox">{{ 'settings.menu_inbox' | translate }}</a> <a class="list-group-item" ui-sref-active="{ active: 'settings.inbox.**' }" href="#/settings/inbox">{{ 'settings.menu_inbox' | translate }}</a>
<a class="list-group-item" ui-sref-active="{ active: 'settings.vocabulary.**' }" href="#/settings/vocabulary">{{ 'settings.menu_vocabularies' | translate }}</a> <a class="list-group-item" ui-sref-active="{ active: 'settings.vocabulary.**' }" href="#/settings/vocabulary">{{ 'settings.menu_vocabularies' | translate }}</a>
<a class="list-group-item" ui-sref-active="{ active: 'settings.config.**' }" href="#/settings/config">{{ 'settings.menu_configuration' | translate }}</a> <a class="list-group-item" ui-sref-active="{ active: 'settings.config.**' }" href="#/settings/config">{{ 'settings.menu_configuration' | translate }}</a>
<a class="list-group-item" ui-sref-active="{ active: 'settings.log.**' }" href="#/settings/log">{{ 'settings.menu_server_logs' | translate }}</a> <a class="list-group-item" ui-sref-active="{ active: 'settings.monitoring.**' }" href="#/settings/monitoring">{{ 'settings.menu_monitoring' | translate }}</a>
</ul> </ul>
</div> </div>
</div> </div>

View File

@ -1,18 +0,0 @@
<h1 translate="settings.log.title"></h1>
<table class="table table-hover table-logs">
<thead>
<tr>
<th>{{ 'settings.log.date' | translate }}</th>
<th>{{ 'settings.log.tag' | translate }}</th>
<th>{{ 'settings.log.message' | translate }}</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="log in logs"
ng-class="{ info: log.level == 'INFO' || log.level == 'DEBUG', warning: log.level == 'WARN', danger: log.level == 'ERROR' || log.level == 'FATAL' }">
<td>{{ log.date | date: dateTimeFormat }}</td>
<td>{{ log.tag }}</td>
<td class="cell-message">{{ log.message }}</td>
</tr>
</tbody>
</table>

View File

@ -0,0 +1,25 @@
<h2 translate="settings.monitoring.background_tasks"></h2>
<p>
<strong>{{ 'settings.monitoring.queued_tasks' | translate: { count: app.queued_tasks } }}</strong>
<span class="fas fa-check text-success" ng-if="app.queued_tasks == 0"></span>
<span class="fas fa-circle-notch text-warning fa-spin" ng-if="app.queued_tasks > 0"></span>
</p>
<p>{{ 'settings.monitoring.queued_tasks_explain' | translate }}</p>
<h2 translate="settings.monitoring.server_logs"></h2>
<table class="table table-hover table-logs">
<thead>
<tr>
<th>{{ 'settings.monitoring.log_date' | translate }}</th>
<th>{{ 'settings.monitoring.log_tag' | translate }}</th>
<th>{{ 'settings.monitoring.log_message' | translate }}</th>
</tr>
</thead>
<tbody>
<tr ng-repeat="log in logs"
ng-class="{ info: log.level == 'INFO' || log.level == 'DEBUG', warning: log.level == 'WARN', danger: log.level == 'ERROR' || log.level == 'FATAL' }">
<td>{{ log.date | date: dateTimeFormat }}</td>
<td>{{ log.tag }}</td>
<td class="cell-message">{{ log.message }}</td>
</tr>
</tbody>
</table>

View File

@ -39,6 +39,7 @@ public class TestAppResource extends BaseJerseyTest {
Assert.assertTrue(freeMemory > 0); Assert.assertTrue(freeMemory > 0);
Long totalMemory = json.getJsonNumber("total_memory").longValue(); Long totalMemory = json.getJsonNumber("total_memory").longValue();
Assert.assertTrue(totalMemory > 0 && totalMemory > freeMemory); Assert.assertTrue(totalMemory > 0 && totalMemory > freeMemory);
Assert.assertEquals(0, json.getJsonNumber("queued_tasks").intValue());
Assert.assertFalse(json.getBoolean("guest_login")); Assert.assertFalse(json.getBoolean("guest_login"));
Assert.assertEquals("eng", json.getString("default_language")); Assert.assertEquals("eng", json.getString("default_language"));
Assert.assertTrue(json.containsKey("global_storage_current")); Assert.assertTrue(json.containsKey("global_storage_current"));