querysub 0.371.0 → 0.373.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
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "querysub",
3
- "version": "0.371.0",
3
+ "version": "0.373.0",
4
4
  "main": "index.js",
5
5
  "license": "MIT",
6
6
  "note1": "note on node-forge fork, see https://github.com/digitalbazaar/forge/issues/744 for details",
@@ -130,7 +130,7 @@ export class ServicesListPage extends qreact.Component {
130
130
  {config.parameters.key}
131
131
  </div>
132
132
  <div>
133
- {enabledMachineIds.length} configured {disabledMachines.length > 0 && `(+${disabledMachines.length} on disabled machines)`} {failingMachines.length > 0 && `(${failingMachines.length} failing)`} {missingMachines.length > 0 && `(${missingMachines.length} machine hasn't run service yet)`} {unknown > 0 && `(${unknown} unknown)`} • {totalLaunches} launches •
133
+ <span className={css.boldStyle.fontSize(14)}>{enabledMachineIds.length}</span> configured {disabledMachines.length > 0 && `(+${disabledMachines.length} on disabled machines)`} {failingMachines.length > 0 && `(${failingMachines.length} failing)`} {missingMachines.length > 0 && `(${missingMachines.length} machine hasn't run service yet)`} {unknown > 0 && `(${unknown} unknown)`} • {totalLaunches} launches •
134
134
  Deploy: {config.parameters.deploy ? "enabled" : "disabled"}
135
135
  </div>
136
136
  </div>
@@ -25,6 +25,15 @@ export type FilePathsByMachine = {
25
25
  errorCount: number;
26
26
  };
27
27
 
28
+ function getSourceColor(sourceName: string | undefined): string | undefined {
29
+ if (!sourceName) return undefined;
30
+ const lastPart = sourceName.split("/").pop()?.toLowerCase();
31
+ if (lastPart === "error") return css.colorhsl(0, 80, 40);
32
+ if (lastPart === "warn") return css.colorhsl(40, 80, 40);
33
+ if (lastPart === "info") return css.colorhsl(280, 80, 40);
34
+ if (lastPart === "log") return css.colorhsl(200, 80, 40);
35
+ return undefined;
36
+ }
28
37
 
29
38
  export class FilePathSelector extends qreact.Component<{
30
39
  paths: TimeFilePathWithSize[];
@@ -136,8 +145,6 @@ export class FilePathSelector extends qreact.Component<{
136
145
  <div>|</div>
137
146
  <div>Machines: {formatNumber(grouped.length)}</div>
138
147
  <div>|</div>
139
- <div>Threads: {formatNumber(totals.uniqueThreads)}</div>
140
- <div>|</div>
141
148
  <div>Files: {formatNumber(this.props.paths.length)}</div>
142
149
  <div>|</div>
143
150
  <div>Pending: {formatNumber(totals.totalPending)}</div>
@@ -379,7 +386,7 @@ export class FilePathSelectorModal extends qreact.Component<{
379
386
  </td>
380
387
  <td className={css.pad2(2)}>{this.props.formatBytes(file.size)}</td>
381
388
  <td className={css.pad2(2)}>{file.logCount !== undefined ? formatNumber(file.logCount) : <span className={css.colorhsl(40, 60, 40)}>pending</span>}</td>
382
- <td className={css.pad2(2)}>{file.sourceName}</td>
389
+ <td className={css.pad2(2) + (getSourceColor(file.sourceName) || "")}>{file.sourceName}</td>
383
390
  <td className={css.pad2(2)}>{file.dedupe}</td>
384
391
  <td className={css.pad2(2)}>{formatDateTime(file.startTime)}</td>
385
392
  <td className={css.pad2(2)}>
@@ -418,8 +425,7 @@ export class FilePathSelectorModal extends qreact.Component<{
418
425
  <div className={css.vbox(5)}>
419
426
  <div className={css.hbox(10)}>
420
427
  <div className={css.minWidth(120)}>Machines: {formatNumber(summary.machineCount)}</div>
421
- {/* NOTE: If the files have been merged, the thread count doesn't matter anymore, so it's deceiving to put the thread count here. */}
422
- {/* <div className={css.minWidth(110)}>Threads: {formatNumber(summary.threadCount)}</div> */}
428
+ <div className={css.minWidth(110)}>Threads: {formatNumber(summary.threadCount)}</div>
423
429
  <div className={css.minWidth(140)}>Files: {formatNumber(summary.fileCount)} ({formatNumber(summary.pendingCount)} pending)</div>
424
430
  <div className={css.minWidth(120)}>Size: {this.props.formatBytes(summary.totalSize)}</div>
425
431
  <div className={css.minWidth(100)}>Logs: {formatNumber(summary.totalLogCount)}</div>
@@ -432,7 +438,7 @@ export class FilePathSelectorModal extends qreact.Component<{
432
438
  <div className={css.vbox(5)}>
433
439
  {Array.from(bySource.entries()).map(([sourceName, stats]) => (
434
440
  <div key={sourceName} className={css.hbox(10)}>
435
- <div className={css.minWidth(240)}>{sourceName}:</div>
441
+ <div className={css.minWidth(240) + (getSourceColor(sourceName) || "")}>{sourceName}:</div>
436
442
  <div className={css.minWidth(140)}>Files: {formatNumber(stats.fileCount)} ({formatNumber(stats.pendingCount)} pending)</div>
437
443
  <div className={css.minWidth(120)}>Size: {this.props.formatBytes(stats.size)}</div>
438
444
  <div className={css.minWidth(100)}>Logs: {formatNumber(stats.logCount)}</div>
@@ -25,6 +25,7 @@ import { blue } from "socket-function/src/formatting/logColors";
25
25
  import { LimitGroup } from "../../../functional/limitProcessing";
26
26
  import { getAllNodeIds } from "../../../-f-node-discovery/NodeDiscovery";
27
27
  import { NodeCapabilitiesController } from "../../../-g-core-values/NodeCapabilities";
28
+ import { getLoggers2Async } from "../diskLogger";
28
29
 
29
30
  export type TimeFilePathWithSize = TimeFilePath & {
30
31
  size: number;
@@ -40,7 +41,6 @@ export class IndexedLogs<T> {
40
41
  name: string,
41
42
  maxSingleFileData?: number;
42
43
  maxCountPerFile?: number;
43
- forceUsePublicLogs?: boolean;
44
44
  getTime: (result: T) => number | undefined;
45
45
  }) {
46
46
  loggerByName.set(this.config.name, this as any);
@@ -48,9 +48,10 @@ export class IndexedLogs<T> {
48
48
 
49
49
 
50
50
  private static shouldRunLoop = false;
51
- public static runLogMoveLoop() {
51
+ public static async runLogMoveLoop() {
52
52
  IndexedLogs.shouldRunLoop = true;
53
- for (let indexedLogs of loggerByName.values()) {
53
+ let allLoggers = await getLoggers2Async();
54
+ for (let indexedLogs of Object.values(allLoggers)) {
54
55
  indexedLogs.runLogMoverLoop();
55
56
  }
56
57
  }
@@ -91,7 +92,7 @@ export class IndexedLogs<T> {
91
92
  let basePublic: Archives = getArchivesHome(getDomain());
92
93
  // NOTE: The local disk is so fast that reading in 10 megabytes is nothing, And if we read in too small of a value, the overhead per read ends up making this take forever.
93
94
  let extraReadSize = 1024 * 1024 * 10;
94
- if (this.config.forceUsePublicLogs || isPublic()) {
95
+ if (isPublic()) {
95
96
  basePublic = getArchivesBackblaze(getDomain());
96
97
  // NOTE: While the latency to back plays is high, now we're reading in parallel, so it shouldn't be as big of an issue.
97
98
  extraReadSize = 1024 * 1024 * 1;
@@ -274,8 +275,16 @@ export class IndexedLogs<T> {
274
275
  forceReadPublic?: boolean;
275
276
  }): Promise<TimeFilePathWithSize[]> {
276
277
  let finalPaths: TimeFilePathWithSize[] = [];
278
+ if (config.forceReadPublic && !isPublic()) {
279
+ let machineNodes = await this.getMachineNodes();
280
+ if (machineNodes.length === 0) throw new Error(`Cannot find any public nodes to read from`);
281
+ return await IndexedLogShimController.nodes[machineNodes[0]].getPaths({
282
+ ...config,
283
+ indexedLogsName: this.config.name,
284
+ });
285
+ }
277
286
 
278
- if (!config.only && (config.forceReadPublic || isPublic())) {
287
+ if (config.only !== "local" && isPublic()) {
279
288
  let machineNodes = await this.getMachineNodes();
280
289
  await Promise.all(machineNodes.map(async (machineNode) => {
281
290
  try {
@@ -291,11 +300,6 @@ export class IndexedLogs<T> {
291
300
  }));
292
301
  }
293
302
 
294
- // If we're forcefully reading from the public server, but we're not public, the code above will be the only code which adds to results
295
- if (!isPublic() && config.forceReadPublic) {
296
- return finalPaths;
297
- }
298
-
299
303
  let localLogs = this.getLocalLogs();
300
304
  let backblazeLogs = this.getPublicLogs();
301
305
  let paths: TimeFilePath[] = [];
@@ -347,6 +351,16 @@ export class IndexedLogs<T> {
347
351
  onResult: (match: T) => void;
348
352
  onResults?: (results: IndexedLogResults) => Promise<boolean>;
349
353
  }): Promise<IndexedLogResults> {
354
+
355
+ if (config.params.forceReadPublic && !isPublic()) {
356
+ let machineNodes = await this.getMachineNodes();
357
+ if (machineNodes.length === 0) throw new Error(`Cannot find any public nodes to read from`);
358
+ return await this.clientFind({
359
+ ...config,
360
+ nodeId: machineNodes[0],
361
+ });
362
+ }
363
+
350
364
  let startTime = Date.now();
351
365
  let interval: NodeJS.Timeout | undefined;
352
366
 
@@ -360,7 +374,8 @@ export class IndexedLogs<T> {
360
374
  let allResults = new Map<string, IndexedLogResults>();
361
375
  let allDone: Promise<void>[] = [];
362
376
 
363
- if (config.params.only !== "local" && (config.params.forceReadPublic || isPublic())) {
377
+ // Read other nodes if on a public server
378
+ if (config.params.only !== "local" && isPublic()) {
364
379
  let machineNodes = await this.getMachineNodes();
365
380
  allDone.push(...machineNodes.map(async (machineNode) => {
366
381
  try {
@@ -385,12 +400,6 @@ export class IndexedLogs<T> {
385
400
  }));
386
401
  }
387
402
 
388
- // If we're forcefully reading from the public server, but we're not public, the code above will be the only code which adds to results
389
- if (!isPublic() && config.params.forceReadPublic) {
390
- await Promise.all(allDone);
391
- return getFinalResults();
392
- }
393
-
394
403
 
395
404
  let results: IndexedLogResults = createEmptyIndexedLogResults();
396
405
  allResults.set("", results);
@@ -588,6 +597,7 @@ export class IndexedLogs<T> {
588
597
  }
589
598
 
590
599
  await moveLogsToPublic({
600
+ loggerName: this.config.name,
591
601
  forceAll,
592
602
  localLogs: this.getLocalLogs(),
593
603
  publicLogs: this.getPublicLogs(),
@@ -686,11 +686,23 @@ export class LogViewer3 extends qreact.Component {
686
686
  checkbox
687
687
  label="Exclude Pending Results"
688
688
  url={excludePendingResults}
689
+ onChangeValue={(newValue) => {
690
+ if (newValue) {
691
+ savedPathsURL.value = "";
692
+ void this.loadPaths();
693
+ }
694
+ }}
689
695
  />
690
696
  {!isPublic() && <InputLabelURL
691
697
  checkbox
692
698
  label="Read Public Logs"
693
699
  url={readPublicLogs}
700
+ onChangeValue={(newValue) => {
701
+ if (newValue) {
702
+ savedPathsURL.value = "";
703
+ void this.loadPaths();
704
+ }
705
+ }}
694
706
  />}
695
707
  <InputLabelURL
696
708
  label="Limit"
@@ -5,12 +5,13 @@ import { getOwnThreadId } from "../../../-f-node-discovery/NodeDiscovery";
5
5
  import { BufferIndex } from "./BufferIndex";
6
6
  import { LogStreamer } from "./LogStreamer";
7
7
  import { TimeFileTree } from "./TimeFileTree";
8
- import { green, magenta } from "socket-function/src/formatting/logColors";
8
+ import { blue, green, magenta } from "socket-function/src/formatting/logColors";
9
9
  import { formatNumber, formatTime } from "socket-function/src/formatting/format";
10
10
 
11
11
 
12
12
 
13
13
  export async function moveLogsToPublic(config: {
14
+ loggerName: string;
14
15
  publicMoveThreshold: number;
15
16
  maxSingleFileData: number;
16
17
  movingTimeout: number;
@@ -128,7 +129,7 @@ export async function moveLogsToPublic(config: {
128
129
 
129
130
  if (!await tryToGetMoveLock()) return;
130
131
 
131
- console.log(magenta(`Moving ${localPaths.length} log files to public`));
132
+ console.log(magenta(`Moving ${localPaths.length} log files to public (${blue(config.loggerName)})`), { loggerName: config.loggerName, localPaths });
132
133
 
133
134
  let byStartTime = keyByArray(localPaths, x => x.startTime);
134
135
 
@@ -20,21 +20,22 @@ IMPORTANT! Now I am properly calling shutdown, so none of the streamed logs shou
20
20
 
21
21
 
22
22
 
23
- AH, make sure force move works with force public flag!
24
-
25
- 2) Create lot of remote server logs
26
- - Via our refresh loop
27
-
28
- 3) Ensure our moveloops are working correctly
29
-
30
-
23
+ 3) Ensure our moveloops are working correctly, on both dev and public
31
24
 
32
25
 
33
26
  1) Fix missing __NAME__
34
- "Received PathValue for path" misses name?
35
- - Maybe the missing name only happens when we rate limit?
27
+ "Received PathValue for path" misses name?
28
+ - Maybe the missing name only happens when we rate limit?
36
29
 
30
+ 2) Create lot of remote server logs
31
+ - Via our refresh loop
37
32
 
33
+ 3) Verify search is still fast, and works correctly!
34
+ - Try to get a rare value in that is in the logs, but is hard to find
35
+ Good rare search. Checks for sending emails, which we do very rarely. If we pack in 10GB of logs after this, it will really stress our indexing system.
36
+ - At the moment our pending index has a good hit rate (0 false positives out of 1720). We'll see if this continues for our remote index.
37
+ https://127-0-0-1.querysubtest.com:7007/?hot&readPublicLogs&showingmanagement&machineview=services&managementpage=LogViewer3&searchText=Sending%20email&selectedFields=%7B%22path%22%3Atrue%7D
38
+
38
39
 
39
40
 
40
41
  Rewrite error notification code