querysub 0.42.0 → 0.43.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/package.json
CHANGED
|
@@ -31,6 +31,7 @@ import { decodeNodeId, encodeNodeId, getMachineId } from "../../-a-auth/certs";
|
|
|
31
31
|
import { Button } from "../../library-components/Button";
|
|
32
32
|
import { TimeRangeSelector } from "../../library-components/TimeRangeSelector";
|
|
33
33
|
import { BrowserLargeFileCache, cacheCalls } from "./BrowserLargeFileCache";
|
|
34
|
+
import { Zip } from "../../zip";
|
|
34
35
|
|
|
35
36
|
// TODO: Realtime log mode, by reading from the previous length forward, to add buffers
|
|
36
37
|
// to what we already read.
|
|
@@ -141,6 +142,7 @@ export class DiskLoggerPage extends qreact.Component {
|
|
|
141
142
|
if (file.endTime > lastTime) lastTime = file.endTime;
|
|
142
143
|
let buffer = controller.getRemoteLogBuffer(file.nodeId, file.path);
|
|
143
144
|
if (buffer) {
|
|
145
|
+
buffer = Zip.gunzipSync(buffer);
|
|
144
146
|
buffers.push(buffer);
|
|
145
147
|
} else {
|
|
146
148
|
loadingCount++;
|
|
@@ -542,7 +544,14 @@ class DiskLoggerControllerBase {
|
|
|
542
544
|
return await getLogFiles();
|
|
543
545
|
}
|
|
544
546
|
public async getLogBuffer(path: string): Promise<Buffer | undefined> {
|
|
545
|
-
|
|
547
|
+
// Always compress it. If it is in progress it can't be compressed on disk, but
|
|
548
|
+
// the compression ratio is so high it's worth it to compress it dynamically now,
|
|
549
|
+
// to speed up the network transfer.
|
|
550
|
+
let buffer = await getLogBuffer(path);
|
|
551
|
+
if (buffer && path.endsWith(".log")) {
|
|
552
|
+
buffer = await Zip.gzip(buffer);
|
|
553
|
+
}
|
|
554
|
+
return buffer;
|
|
546
555
|
}
|
|
547
556
|
}
|
|
548
557
|
|
|
@@ -552,14 +561,11 @@ export const DiskLoggerController = SocketFunction.register(
|
|
|
552
561
|
() => ({
|
|
553
562
|
getRemoteLogFiles: {},
|
|
554
563
|
getRemoteLogBuffer: {
|
|
555
|
-
compress: true,
|
|
556
564
|
clientHooks: [cacheCalls]
|
|
557
565
|
},
|
|
558
566
|
|
|
559
567
|
getLogFiles: {},
|
|
560
|
-
getLogBuffer: {
|
|
561
|
-
compress: true,
|
|
562
|
-
},
|
|
568
|
+
getLogBuffer: {},
|
|
563
569
|
}),
|
|
564
570
|
() => ({
|
|
565
571
|
hooks: [assertIsManagementUser],
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
|
|
2
|
-
import { batchFunction, runInfinitePoll } from "socket-function/src/batching";
|
|
2
|
+
import { batchFunction, runInfinitePoll, runInfinitePollCallAtStart } from "socket-function/src/batching";
|
|
3
3
|
import { nextId, timeInDay, timeInHour } from "socket-function/src/misc";
|
|
4
4
|
import { getStorageDir, getStorageFolder } from "../../fs";
|
|
5
5
|
import fs from "fs";
|
|
@@ -8,6 +8,7 @@ import { SizeLimiter } from "../SizeLimiter";
|
|
|
8
8
|
import { SocketFunction } from "socket-function/SocketFunction";
|
|
9
9
|
import { isNode } from "typesafecss";
|
|
10
10
|
import { logGitHashes } from "./logGitHashes";
|
|
11
|
+
import { Zip } from "../../zip";
|
|
11
12
|
|
|
12
13
|
if (isNode()) {
|
|
13
14
|
// Delayed setup, as we depend on diskLogger early, and we don't want to force high level
|
|
@@ -105,6 +106,7 @@ export type LogFile = {
|
|
|
105
106
|
export async function getLogFiles(): Promise<LogFile[]> {
|
|
106
107
|
let files = await fs.promises.readdir(folder);
|
|
107
108
|
let paths = files.map(file => folder + file);
|
|
109
|
+
paths = paths.filter(x => x.endsWith(".log") || x.endsWith(".zip"));
|
|
108
110
|
let objs = paths.map(decodeLogFileName);
|
|
109
111
|
for (let obj of objs) {
|
|
110
112
|
try {
|
|
@@ -214,7 +216,8 @@ function packageLogObj(args: unknown[]): LogObj {
|
|
|
214
216
|
|
|
215
217
|
function decodeLogFileName(path: string): LogFile {
|
|
216
218
|
let name = path.split("/").pop()!;
|
|
217
|
-
let
|
|
219
|
+
let withoutExt = name.split(".").slice(0, -1).join(".");
|
|
220
|
+
let [start, end] = withoutExt.split("-").map(Number);
|
|
218
221
|
return {
|
|
219
222
|
startTime: start,
|
|
220
223
|
endTime: end,
|
|
@@ -231,7 +234,16 @@ const logBase = batchFunction({ delay: 0 }, async function logBase(logObjList: L
|
|
|
231
234
|
|
|
232
235
|
let byLogPath = new Map<string, LogObj[]>();
|
|
233
236
|
for (let log of logs) {
|
|
234
|
-
|
|
237
|
+
function createLogFileName(logObj: LogObj): LogFile {
|
|
238
|
+
let start = Math.floor(logObj.time / LOG_FILE_DURATION) * LOG_FILE_DURATION;
|
|
239
|
+
let startTime = start;
|
|
240
|
+
let endTime = start + LOG_FILE_DURATION;
|
|
241
|
+
let name = startTime + "-" + endTime + ".log";
|
|
242
|
+
let path = folder + name;
|
|
243
|
+
let logFile: LogFile = { startTime, endTime, name, path, size: 0, };
|
|
244
|
+
return logFile;
|
|
245
|
+
}
|
|
246
|
+
let logFile = createLogFileName(log);
|
|
235
247
|
let list = byLogPath.get(logFile.path);
|
|
236
248
|
if (!list) {
|
|
237
249
|
list = [];
|
|
@@ -268,18 +280,9 @@ const logBase = batchFunction({ delay: 0 }, async function logBase(logObjList: L
|
|
|
268
280
|
}
|
|
269
281
|
});
|
|
270
282
|
|
|
271
|
-
function getLogFileName(logObj: LogObj): LogFile {
|
|
272
|
-
let start = Math.floor(logObj.time / LOG_FILE_DURATION) * LOG_FILE_DURATION;
|
|
273
|
-
let startTime = start;
|
|
274
|
-
let endTime = start + LOG_FILE_DURATION;
|
|
275
|
-
let name = startTime + "-" + endTime + ".log";
|
|
276
|
-
let path = folder + name;
|
|
277
|
-
let logFile: LogFile = { startTime, endTime, name, path, size: 0, };
|
|
278
|
-
return logFile;
|
|
279
|
-
}
|
|
280
283
|
|
|
281
284
|
if (isNode()) {
|
|
282
|
-
runInfinitePoll(timeInHour, async function
|
|
285
|
+
runInfinitePoll(timeInHour, async function compressLogs() {
|
|
283
286
|
// Maintain our size restrictions
|
|
284
287
|
let logFiles = await fs.promises.readdir(folder);
|
|
285
288
|
let objs: { time: number; bytes: number; path: string; }[] = [];
|
|
@@ -293,6 +296,23 @@ if (isNode()) {
|
|
|
293
296
|
await fs.promises.unlink(file.path);
|
|
294
297
|
}
|
|
295
298
|
});
|
|
299
|
+
// Wait a random time, so we hopefully don't synchronize with any other services on this machine
|
|
300
|
+
void runInfinitePollCallAtStart(timeInHour + (1 + Math.random()), async function compressOldLogs() {
|
|
301
|
+
let logFiles = await fs.promises.readdir(folder);
|
|
302
|
+
let compressTime = Date.now() - LOG_FILE_DURATION * 2;
|
|
303
|
+
for (let file of logFiles) {
|
|
304
|
+
if (!file.endsWith(".log")) continue;
|
|
305
|
+
let path = folder + file;
|
|
306
|
+
if (decodeLogFileName(path).endTime > compressTime) continue;
|
|
307
|
+
let basePath = path.split(".").slice(0, -1).join(".");
|
|
308
|
+
let buffer = await fs.promises.readFile(path);
|
|
309
|
+
buffer = await Zip.gzip(buffer);
|
|
310
|
+
let tempPath = basePath + Math.random() + ".temp";
|
|
311
|
+
await fs.promises.writeFile(tempPath, buffer);
|
|
312
|
+
await fs.promises.rename(tempPath, basePath + ".zip");
|
|
313
|
+
await fs.promises.unlink(path);
|
|
314
|
+
}
|
|
315
|
+
});
|
|
296
316
|
}
|
|
297
317
|
|
|
298
318
|
/*
|
package/src/zip.ts
CHANGED
|
@@ -61,6 +61,14 @@ export class Zip {
|
|
|
61
61
|
}
|
|
62
62
|
}
|
|
63
63
|
|
|
64
|
+
public static gunzipSync(buffer: Buffer): Buffer {
|
|
65
|
+
if (isNode()) {
|
|
66
|
+
return Buffer.from(zlib.gunzipSync(buffer));
|
|
67
|
+
} else {
|
|
68
|
+
return Buffer.from(pako.inflate(buffer));
|
|
69
|
+
}
|
|
70
|
+
}
|
|
71
|
+
|
|
64
72
|
@measureFnc
|
|
65
73
|
public static async gunzipBatch(buffers: Buffer[]): Promise<Buffer[]> {
|
|
66
74
|
let time = Date.now();
|