From e3d8aa1a9b76b8edbb8d87869fb149aa96933c0f Mon Sep 17 00:00:00 2001 From: Hornwitser Date: Sat, 11 Sep 2021 19:11:30 +0200 Subject: [PATCH] Add limit and order to query log request Add optional limit to the number of log records to return in the log query request to avoid having the web interface instance console download the entire log for only to show a few hundred lines from it. To make it possible to query the end of the log instead of just the start add an order option as well. --- packages/ctl/ctl.js | 8 +++++ packages/lib/link/messages.js | 2 ++ packages/master/src/ControlConnection.js | 5 ++- .../web_ui/src/components/InstanceConsole.jsx | 4 ++- test/integration/clusterio.js | 36 +++++++++++++++++++ 5 files changed, 53 insertions(+), 2 deletions(-) diff --git a/packages/ctl/ctl.js b/packages/ctl/ctl.js index 39fe0122..6cdff8b5 100755 --- a/packages/ctl/ctl.js +++ b/packages/ctl/ctl.js @@ -819,6 +819,8 @@ logCommands.add(new libCommand.Command({ "slave": { describe: "Query log of given slave", nargs: 1, type: "string", default: null }, "instance": { describe: "Query log of given instance", nargs: 1, type: "string", default: null }, "max-level": { describe: "Maximum log level to return", nargs: 1, type: "string", default: null }, + "limit": { describe: "Max number of entries to return", nargs: 1, type: "number", default: 1000 }, + "start": { describe: "Limit from the start instead of the end", nargs: 0, type: "boolean", default: false }, }); }], handler: async function(args, control) { @@ -835,8 +837,14 @@ logCommands.add(new libCommand.Command({ slave_ids, instance_ids, max_level: args.maxLevel, + limit: args.limit, + order: args.start ? "asc" : "desc", }); + if (!args.start) { + result.log.reverse(); + } + let stdoutLogger = winston.createLogger({ level: "verbose", levels, diff --git a/packages/lib/link/messages.js b/packages/lib/link/messages.js index dbb84455..5cc260d2 100644 --- a/packages/lib/link/messages.js +++ b/packages/lib/link/messages.js @@ -859,6 +859,8 @@ messages.queryLog = new Request({ items: { type: "integer" }, }, "max_level": { type: ["string", "null"] }, + "limit": { type: "integer" }, + "order": { enum: ["asc", "desc"] }, }, responseProperties: { "log": { diff --git a/packages/master/src/ControlConnection.js b/packages/master/src/ControlConnection.js index bf9fecf3..1d2efd49 100644 --- a/packages/master/src/ControlConnection.js +++ b/packages/master/src/ControlConnection.js @@ -456,12 +456,15 @@ class ControlConnection extends BaseConnection { // - The log file is read starting from the beginning let setDuration = lastQueryLogTime.startTimer(); let log = await query({ - order: "asc", + order: message.data.order, limit: Infinity, from: new Date(0), }); log = log.filter(this.constructor.logFilter(message.data)); + if (message.data.limit) { + log = log.slice(0, message.data.limit); + } setDuration(); return { log }; } diff --git a/packages/web_ui/src/components/InstanceConsole.jsx b/packages/web_ui/src/components/InstanceConsole.jsx index fdc0c7f2..30e8f76f 100644 --- a/packages/web_ui/src/components/InstanceConsole.jsx +++ b/packages/web_ui/src/components/InstanceConsole.jsx @@ -65,8 +65,10 @@ export default function InstanceConsole(props) { slave_ids: [], instance_ids: [props.id], max_level: null, + limit: 400, + order: "desc", }).then(result => { - setPastLines(result.log.slice(-400).map((info, index) => formatLog(info, index))); + setPastLines(result.log.map((info, index) => formatLog(info, index)).reverse()); }).catch(err => { setPastLines([{`Error loading log: ${err.message}`}
]); }); diff --git a/test/integration/clusterio.js b/test/integration/clusterio.js index ea92fd4d..072f0180 100644 --- a/test/integration/clusterio.js +++ b/test/integration/clusterio.js @@ -62,6 +62,42 @@ describe("Integration of Clusterio", function() { await connectorB.close(1000, ""); }); }); + + describe("queryLogRequestHandler", function() { + it("should honnor the limit", async function() { + let result = await libLink.messages.queryLog.send(getControl(), { + all: true, + master: false, + slave_ids: [], + instance_ids: [], + max_level: null, + limit: 10, + order: "asc", + }); + assert.equal(result.log.length, 10); + }); + it("should return entries by order", async function() { + let first = await libLink.messages.queryLog.send(getControl(), { + all: true, + master: false, + slave_ids: [], + instance_ids: [], + max_level: null, + limit: 1, + order: "asc", + }); + let last = await libLink.messages.queryLog.send(getControl(), { + all: true, + master: false, + slave_ids: [], + instance_ids: [], + max_level: null, + limit: 1, + order: "desc", + }); + assert(first.log[0].timestamp < last.log[0].timestamp, "first log entry happened after last"); + }); + }); }); describe("clusterioslave", function() {