From 12bbdba82ccf8453d08536a4c9fbac3bcb8402ea Mon Sep 17 00:00:00 2001 From: Julien Fontanet Date: Wed, 30 Jan 2019 14:35:40 +0100 Subject: [PATCH] feat(xo-server/backupNg.getLogs): extract a subset of logs (#3914) Related to xoa-support#1024 --- packages/xo-server/src/api/backup-ng.js | 18 +++++-- .../src/xo-mixins/backups-ng-logs.js | 51 ++++++++++++++++++- 2 files changed, 64 insertions(+), 5 deletions(-) diff --git a/packages/xo-server/src/api/backup-ng.js b/packages/xo-server/src/api/backup-ng.js index e4c5aaee3..d14c9b72d 100644 --- a/packages/xo-server/src/api/backup-ng.js +++ b/packages/xo-server/src/api/backup-ng.js @@ -1,5 +1,4 @@ import { basename } from 'path' -import { isEmpty, pickBy } from 'lodash' import { safeDateFormat } from '../utils' @@ -151,13 +150,24 @@ runJob.params = { // ----------------------------------------------------------------------------- -export async function getAllLogs(filter) { - const logs = await this.getBackupNgLogs() - return isEmpty(filter) ? logs : pickBy(logs, filter) +export function getAllLogs() { + return this.getBackupNgLogs() } getAllLogs.permission = 'admin' +export function getLogs({ after, before, limit, ...filter }) { + return this.getBackupNgLogsSorted({ after, before, limit, filter }) +} + +getLogs.permission = 'admin' + +getLogs.params = { + after: { type: ['number', 'string'], optional: true }, + before: { type: ['number', 'string'], optional: true }, + limit: { type: 'number', optional: true }, +} + // ----------------------------------------------------------------------------- export function deleteVmBackup({ id }) { diff --git a/packages/xo-server/src/xo-mixins/backups-ng-logs.js b/packages/xo-server/src/xo-mixins/backups-ng-logs.js index 6da4ea2dc..c0c701646 100644 --- a/packages/xo-server/src/xo-mixins/backups-ng-logs.js +++ b/packages/xo-server/src/xo-mixins/backups-ng-logs.js @@ -1,4 +1,5 @@ -import { forEach } from 'lodash' +import ms from 'ms' +import { forEach, isEmpty, iteratee, sortedIndexBy } from 'lodash' import { noSuchObject } from 'xo-common/api-errors' const isSkippedError = error => @@ -32,6 +33,10 @@ const computeStatusAndSortTasks = (status, tasks) => { return status } +function getPropertyValue(key) { + return this[key] +} + const taskTimeComparator = ({ start: s1, end: e1 }, { start: s2, end: e2 }) => { if (e1 !== undefined) { if (e2 !== undefined) { @@ -170,4 +175,48 @@ export default { return runId === undefined ? consolidated : consolidated[runId] }, + + async getBackupNgLogsSorted({ after, before, filter, limit }) { + let logs = await this.getBackupNgLogs() + + // convert to array + logs = Object.keys(logs).map(getPropertyValue, logs) + + if (!isEmpty(filter)) { + logs = logs.filter(iteratee(filter)) + } + + logs.sort((a, b) => a.start - b.start) + + // only extract the range we are interested in + const i = + after === undefined + ? 0 + : sortedIndexBy( + logs, + { + start: typeof after === 'number' ? after : Date.now() - ms(after), + }, + 'start' + ) + let j = + before === undefined + ? logs.length + : sortedIndexBy( + logs, + { + start: + typeof before === 'number' ? before : Date.now() - ms(before), + }, + 'start' + ) + + limit += i + if (limit < j) { + j = limit + } + logs = logs.slice(i, j) + + return logs + }, }