querysub 0.46.0 → 0.50.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 +2 -2
- package/src/-0-hooks/hooks.ts +83 -0
- package/src/-a-archives/archivesBackBlaze.ts +1 -1
- package/src/0-path-value-core/NodePathAuthorities.ts +5 -0
- package/src/0-path-value-core/archiveLocks/ArchiveLocks2.ts +12 -12
- package/src/0-path-value-core/debugLogs.ts +6 -15
- package/src/0-path-value-core/pathValueCore.ts +53 -17
- package/src/2-proxy/PathValueProxyWatcher.ts +18 -10
- package/src/2-proxy/archiveMoveHarness.ts +7 -7
- package/src/2-proxy/garbageCollection.ts +6 -6
- package/src/4-dom/qreact.tsx +8 -1
- package/src/4-querysub/Querysub.ts +9 -4
- package/src/5-diagnostics/GenericFormat.tsx +92 -1
- package/src/5-diagnostics/Table.tsx +7 -12
- package/src/5-diagnostics/TimeGrouper.tsx +24 -15
- package/src/5-diagnostics/memoryValueAudit.ts +7 -10
- package/src/5-diagnostics/nodeMetadata.ts +92 -44
- package/src/5-diagnostics/synchronousLagTracking.ts +1 -1
- package/src/diagnostics/NodeViewer.tsx +3 -4
- package/src/diagnostics/logs/DiskLoggerPage.tsx +27 -12
- package/src/diagnostics/logs/diskLogger.ts +9 -0
- package/src/diagnostics/trackResources.ts +2 -2
- package/src/diagnostics/watchdog.ts +19 -8
- package/src/library-components/TimeRangeSelector.tsx +1 -1
|
@@ -119,14 +119,14 @@ export class DiskLoggerPage extends qreact.Component {
|
|
|
119
119
|
let startTime = Number(startTimeURL.value) || (Date.now() - timeInDay);
|
|
120
120
|
let endTime = Number(endTimeURL.value) || (Date.now() + timeInDay);
|
|
121
121
|
const controller = diskLoggerController(getBrowserUrlNode());
|
|
122
|
-
let
|
|
122
|
+
let allFiles: (LogFile & { nodeId: string })[] = [];
|
|
123
123
|
let loadingCount = 0;
|
|
124
124
|
|
|
125
125
|
for (let nodeId of selectedNodesIds) {
|
|
126
126
|
try {
|
|
127
127
|
let newFiles = controller.getRemoteLogFiles(nodeId);
|
|
128
128
|
if (newFiles) {
|
|
129
|
-
|
|
129
|
+
allFiles.push(...newFiles.map(x => ({ ...x, nodeId })));
|
|
130
130
|
} else {
|
|
131
131
|
loadingCount++;
|
|
132
132
|
}
|
|
@@ -134,19 +134,29 @@ export class DiskLoggerPage extends qreact.Component {
|
|
|
134
134
|
console.log("Error reading files", nodeId, e);
|
|
135
135
|
}
|
|
136
136
|
}
|
|
137
|
-
|
|
138
|
-
|
|
137
|
+
//files = files.filter(file => file.startTime <= endTime && file.endTime >= startTime);
|
|
138
|
+
// File to fix some broken files
|
|
139
|
+
allFiles = allFiles.filter(file => file.startTime >= +new Date("1980"));
|
|
139
140
|
let buffers: Buffer[] = [];
|
|
140
141
|
|
|
141
142
|
let firstTime = Number.MAX_SAFE_INTEGER;
|
|
142
143
|
let lastTime = Number.MIN_SAFE_INTEGER;
|
|
143
144
|
|
|
144
|
-
let filesHash = JSON.stringify(
|
|
145
|
+
let filesHash = JSON.stringify(allFiles.map(x => x.path));
|
|
146
|
+
let fileSizeSum = 0;
|
|
147
|
+
let fileCount = 0;
|
|
145
148
|
|
|
146
|
-
|
|
149
|
+
let selectedFiles: (LogFile & { nodeId: string })[] = [];
|
|
150
|
+
|
|
151
|
+
for (let file of allFiles) {
|
|
147
152
|
try {
|
|
148
153
|
if (file.startTime < firstTime) firstTime = file.startTime;
|
|
149
154
|
if (file.endTime > lastTime) lastTime = file.endTime;
|
|
155
|
+
if (file.startTime > endTime) continue;
|
|
156
|
+
if (file.endTime < startTime) continue;
|
|
157
|
+
selectedFiles.push(file);
|
|
158
|
+
fileCount++;
|
|
159
|
+
fileSizeSum += file.size;
|
|
150
160
|
if (filesHash !== this.state.downloadFilesHash) {
|
|
151
161
|
loadingCount++;
|
|
152
162
|
continue;
|
|
@@ -165,7 +175,7 @@ export class DiskLoggerPage extends qreact.Component {
|
|
|
165
175
|
if (firstTime === Number.MAX_SAFE_INTEGER) firstTime = startTime;
|
|
166
176
|
if (lastTime === Number.MIN_SAFE_INTEGER) lastTime = endTime;
|
|
167
177
|
|
|
168
|
-
let logs: LogObj[] = loadingCount ? [] : parseLogBufferCached(JSON.stringify(
|
|
178
|
+
let logs: LogObj[] = loadingCount ? [] : parseLogBufferCached(JSON.stringify(allFiles), buffers);
|
|
169
179
|
|
|
170
180
|
const defaultFields = ["time", "type", "actions", "param0"];
|
|
171
181
|
let selectedValues = selectedFields.value.split("|").filter(x => x);
|
|
@@ -293,11 +303,11 @@ export class DiskLoggerPage extends qreact.Component {
|
|
|
293
303
|
options={nodeIds.map(({ nodeId, entryPoint }) => ({ value: nodeId, label: `${nodeId} (${entryPoint.replaceAll("\\", "/").split("/").pop()})` }))}
|
|
294
304
|
/>
|
|
295
305
|
<div className={css.fontSize(28).boldStyle}>
|
|
296
|
-
{selectedNodesIds.length} nodes, {
|
|
306
|
+
{selectedNodesIds.length} nodes, {fileCount}/{allFiles.length} files, filtered logs {formatNumber(filteredCount)} / {formatNumber(totalCount)}
|
|
297
307
|
</div>
|
|
298
308
|
<ShowMore maxHeight={40}>
|
|
299
309
|
<div class={css.vbox(4)}>
|
|
300
|
-
{
|
|
310
|
+
{selectedFiles.map(file =>
|
|
301
311
|
<div class={css.hbox(4)}>
|
|
302
312
|
<span>{formatNumber(file.size)}B</span>
|
|
303
313
|
<span>{formatDateTime(file.startTime)} - {formatDateTime(file.endTime)}</span>
|
|
@@ -310,9 +320,11 @@ export class DiskLoggerPage extends qreact.Component {
|
|
|
310
320
|
<button onClick={() => {
|
|
311
321
|
this.state.downloadFilesHash = filesHash;
|
|
312
322
|
}}>
|
|
313
|
-
Download Files
|
|
323
|
+
Download Files ({formatNumber(fileSizeSum)}B)
|
|
314
324
|
</button>
|
|
315
|
-
</div>
|
|
325
|
+
</div>
|
|
326
|
+
|| loadingCount > 0 && <h1 className={css.hsl(210, 75, 75).pad2(10, 2)}>Downloading {loadingCount} file(s)</h1>
|
|
327
|
+
}
|
|
316
328
|
{!inspectTime && <>
|
|
317
329
|
<TimeRangeSelector
|
|
318
330
|
start={startTimeURL} end={endTimeURL}
|
|
@@ -368,7 +380,6 @@ export class DiskLoggerPage extends qreact.Component {
|
|
|
368
380
|
number
|
|
369
381
|
/>
|
|
370
382
|
)}
|
|
371
|
-
{loadingCount > 0 && <h1>Loading {loadingCount} files</h1>}
|
|
372
383
|
<Table {...table} initialLimit={30} />
|
|
373
384
|
{!!inspectTime && (
|
|
374
385
|
<InputLabel
|
|
@@ -399,6 +410,7 @@ const parseLogBufferCached = measureWrap(function parseLogBufferCached(hash: str
|
|
|
399
410
|
cached.lastAccess = Date.now();
|
|
400
411
|
return cached.logs;
|
|
401
412
|
}
|
|
413
|
+
console.log(`Parsing buffers ${buffers.length}`);
|
|
402
414
|
let logs = buffers.map(x => parseLogBuffer(x)).flat();
|
|
403
415
|
let size = buffers.map(x => x.length).reduce((a, b) => a + b, 0);
|
|
404
416
|
remainingCacheSize -= size;
|
|
@@ -412,6 +424,7 @@ const parseLogBufferCached = measureWrap(function parseLogBufferCached(hash: str
|
|
|
412
424
|
logs,
|
|
413
425
|
lastAccess: Date.now()
|
|
414
426
|
});
|
|
427
|
+
console.log(`Parsed buffers ${buffers.length} into logs ${logs.length}`);
|
|
415
428
|
return logs;
|
|
416
429
|
});
|
|
417
430
|
|
|
@@ -431,6 +444,7 @@ const processLogs = cacheShallowConfigArgEqual((config: {
|
|
|
431
444
|
filteredCount: number;
|
|
432
445
|
} => {
|
|
433
446
|
return measureBlock(function processLogs() {
|
|
447
|
+
console.log(`Processing logs ${config.logs.length}`);
|
|
434
448
|
let { logs, order, filter, startTime, endTime, inspectTime, selectedFields } = config;
|
|
435
449
|
logs = logs.slice();
|
|
436
450
|
let totalCount = logs.length;
|
|
@@ -544,6 +558,7 @@ const processLogs = cacheShallowConfigArgEqual((config: {
|
|
|
544
558
|
table.columns[key] = {};
|
|
545
559
|
}
|
|
546
560
|
|
|
561
|
+
console.log(`Processed logs ${logs.length}`);
|
|
547
562
|
return { table, allFields: fields, totalCount, filteredCount };
|
|
548
563
|
});
|
|
549
564
|
}, 10);
|
|
@@ -126,9 +126,12 @@ export async function getLogBuffer(path: string): Promise<Buffer | undefined> {
|
|
|
126
126
|
return buffer;
|
|
127
127
|
}
|
|
128
128
|
export function parseLogBuffer(buffer: Buffer): LogObj[] {
|
|
129
|
+
let time = Date.now();
|
|
130
|
+
console.log(`Parsing buffer ${buffer.length}`);
|
|
129
131
|
let pos = 0;
|
|
130
132
|
let logs: LogObj[] = [];
|
|
131
133
|
const newLine = "\n".charCodeAt(0);
|
|
134
|
+
let lastLoggedPos = 0;
|
|
132
135
|
while (pos < buffer.length) {
|
|
133
136
|
let end = buffer.indexOf(newLine, pos);
|
|
134
137
|
if (end === -1) {
|
|
@@ -139,7 +142,13 @@ export function parseLogBuffer(buffer: Buffer): LogObj[] {
|
|
|
139
142
|
logs.push(JSON.parse(line));
|
|
140
143
|
} catch { }
|
|
141
144
|
pos = end + 1;
|
|
145
|
+
if (pos - lastLoggedPos > 1_000_000) {
|
|
146
|
+
console.log(`Parsed ${pos} of ${buffer.length}`);
|
|
147
|
+
lastLoggedPos = pos;
|
|
148
|
+
}
|
|
142
149
|
}
|
|
150
|
+
time = Date.now() - time;
|
|
151
|
+
console.log(`Parsed ${pos} of ${buffer.length} ${formatNumber(time)}`);
|
|
143
152
|
return logs;
|
|
144
153
|
}
|
|
145
154
|
|
|
@@ -5,7 +5,7 @@ import { blue } from "socket-function/src/formatting/logColors";
|
|
|
5
5
|
import { isNode } from "socket-function/src/misc";
|
|
6
6
|
import { registerPeriodic } from "./periodic";
|
|
7
7
|
import { registerMeasureInfo } from "socket-function/src/profiling/measure";
|
|
8
|
-
import { logNodeStateStats } from "
|
|
8
|
+
import { logNodeStateStats } from "../-0-hooks/hooks";
|
|
9
9
|
|
|
10
10
|
let resources: {
|
|
11
11
|
name: string;
|
|
@@ -80,7 +80,7 @@ function logResourcesNow() {
|
|
|
80
80
|
} else {
|
|
81
81
|
for (let resource of resourcesWithCounts) {
|
|
82
82
|
if (resource.count === 0) continue;
|
|
83
|
-
logNodeStateStats(resource.name, formatNumber
|
|
83
|
+
logNodeStateStats(resource.name, formatNumber, resource.count);
|
|
84
84
|
}
|
|
85
85
|
}
|
|
86
86
|
}
|
|
@@ -7,23 +7,25 @@ import { registerPeriodic } from "./periodic";
|
|
|
7
7
|
import { getOwnMachineId } from "../-a-auth/certs";
|
|
8
8
|
import { SocketFunction } from "socket-function/SocketFunction";
|
|
9
9
|
import { logDisk } from "./logs/diskLogger";
|
|
10
|
-
import { addStatPeriodic, addStatSumPeriodic, addTimeProfileDistribution, registerNodeMetadata } from "../5-diagnostics/nodeMetadata";
|
|
11
10
|
import { formatPercent, formatTime } from "socket-function/src/formatting/format";
|
|
11
|
+
import { pathWatcher } from "../0-path-value-core/pathValueCore";
|
|
12
|
+
import { addStatPeriodic, addStatSumPeriodic, addTimeProfileDistribution, registerNodeMetadata } from "../-0-hooks/hooks";
|
|
12
13
|
|
|
13
14
|
let lastProfile: MeasureProfile | undefined;
|
|
14
15
|
|
|
15
|
-
addStatPeriodic(
|
|
16
|
-
"% Profiled",
|
|
17
|
-
() => {
|
|
16
|
+
addStatPeriodic({
|
|
17
|
+
title: "% Profiled",
|
|
18
|
+
getValue: () => {
|
|
18
19
|
if (!lastProfile) return 0;
|
|
19
20
|
let entries = Object.values(lastProfile.entries);
|
|
20
21
|
if (entries.length === 0) return 0;
|
|
21
22
|
const timeProfiled = lastProfile.endTime - lastProfile.startTime;
|
|
23
|
+
|
|
22
24
|
let timeActive = entries.map(x => x.ownTime.sum).reduce((a, b) => a + b, 0);
|
|
23
25
|
return timeActive / timeProfiled;
|
|
24
26
|
},
|
|
25
|
-
formatPercent,
|
|
26
|
-
);
|
|
27
|
+
format: formatPercent,
|
|
28
|
+
});
|
|
27
29
|
registerNodeMetadata({
|
|
28
30
|
columnName: "Top Profiled",
|
|
29
31
|
getValue() {
|
|
@@ -31,6 +33,7 @@ registerNodeMetadata({
|
|
|
31
33
|
let entries = Object.values(lastProfile.entries);
|
|
32
34
|
if (entries.length === 0) return "";
|
|
33
35
|
const timeProfiled = lastProfile.endTime - lastProfile.startTime;
|
|
36
|
+
|
|
34
37
|
let rootSums = new Map<string, number>();
|
|
35
38
|
for (let entry of entries) {
|
|
36
39
|
let name = entry.name.split("|")[0];
|
|
@@ -42,8 +45,16 @@ registerNodeMetadata({
|
|
|
42
45
|
},
|
|
43
46
|
});
|
|
44
47
|
addTimeProfileDistribution("Network Calls", () => SocketFunction.harvestCallTimes());
|
|
45
|
-
addStatPeriodic(
|
|
46
|
-
|
|
48
|
+
addStatPeriodic({
|
|
49
|
+
title: "Pending Net Calls",
|
|
50
|
+
getValue: () => SocketFunction.getPendingCallCount(),
|
|
51
|
+
});
|
|
52
|
+
addStatSumPeriodic({
|
|
53
|
+
title: "Failed Net Calls",
|
|
54
|
+
getValue: () => SocketFunction.harvestFailedCallCount(),
|
|
55
|
+
});
|
|
56
|
+
addTimeProfileDistribution("Syncing", () => pathWatcher.debug_harvestSyncTimes());
|
|
57
|
+
|
|
47
58
|
|
|
48
59
|
function endEllipsis(str: string, maxLength: number) {
|
|
49
60
|
if (str.length <= maxLength) return str;
|