@nxtedition/lib 13.0.9 → 13.1.1
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/app.js +207 -153
- package/package.json +1 -1
package/app.js
CHANGED
|
@@ -331,6 +331,74 @@ module.exports = function (appConfig, onTerminate) {
|
|
|
331
331
|
|
|
332
332
|
const monitorProviders = {}
|
|
333
333
|
|
|
334
|
+
let stats$
|
|
335
|
+
if (appConfig.stats) {
|
|
336
|
+
const v8 = require('v8')
|
|
337
|
+
const rxjs = require('rxjs')
|
|
338
|
+
const rx = require('rxjs/operators')
|
|
339
|
+
const { eventLoopUtilization } = require('perf_hooks').performance
|
|
340
|
+
|
|
341
|
+
if (typeof appConfig.stats.subscribe === 'function') {
|
|
342
|
+
stats$ = appConfig.stats
|
|
343
|
+
} else if (typeof appConfig.stats === 'function') {
|
|
344
|
+
stats$ = rxjs.timer(0, 10e3).pipe(
|
|
345
|
+
rx.exhaustMap(() => {
|
|
346
|
+
const ret = appConfig.stats({ ds, couch, logger })
|
|
347
|
+
return ret?.then || ret?.subscribe ? ret : rxjs.of(ret)
|
|
348
|
+
})
|
|
349
|
+
)
|
|
350
|
+
} else if (typeof appConfig.stats === 'object') {
|
|
351
|
+
stats$ = rxjs.timer(0, 10e3).pipe(rx.map(() => appConfig.stats))
|
|
352
|
+
} else {
|
|
353
|
+
stats$ = rxjs.timer(0, 10e3).pipe(rx.map(() => ({})))
|
|
354
|
+
}
|
|
355
|
+
|
|
356
|
+
stats$ = stats$.pipe(
|
|
357
|
+
rx.map((x) => ({
|
|
358
|
+
...x,
|
|
359
|
+
timestamp: Date.now(),
|
|
360
|
+
})),
|
|
361
|
+
rx.auditTime(1e3),
|
|
362
|
+
rx.filter(Boolean),
|
|
363
|
+
rx.retryWhen((err$) =>
|
|
364
|
+
err$.pipe(
|
|
365
|
+
rx.tap((err) => logger.error({ err }, 'monitor.stats')),
|
|
366
|
+
rx.delay(10e3)
|
|
367
|
+
)
|
|
368
|
+
),
|
|
369
|
+
rx.startWith({}),
|
|
370
|
+
rx.publishReplay(1),
|
|
371
|
+
rx.refCount()
|
|
372
|
+
)
|
|
373
|
+
|
|
374
|
+
monitorProviders.stats$ = stats$
|
|
375
|
+
|
|
376
|
+
let elu1 = eventLoopUtilization?.()
|
|
377
|
+
const subscription = stats$.pipe(rx.auditTime(10e3)).subscribe((stats) => {
|
|
378
|
+
if (process.env.NODE_ENV === 'production') {
|
|
379
|
+
const elu2 = eventLoopUtilization?.()
|
|
380
|
+
logger.debug(
|
|
381
|
+
{
|
|
382
|
+
ds: ds?.stats,
|
|
383
|
+
couch: couch?.stats,
|
|
384
|
+
lag: toobusy?.lag(),
|
|
385
|
+
memory: process.memoryUsage(),
|
|
386
|
+
utilization: eventLoopUtilization?.(elu2, elu1),
|
|
387
|
+
heap: v8.getHeapStatistics(),
|
|
388
|
+
...stats,
|
|
389
|
+
},
|
|
390
|
+
'STATS'
|
|
391
|
+
)
|
|
392
|
+
elu1 = elu2
|
|
393
|
+
}
|
|
394
|
+
})
|
|
395
|
+
|
|
396
|
+
destroyers.push(() => {
|
|
397
|
+
subscription.unsubscribe()
|
|
398
|
+
})
|
|
399
|
+
}
|
|
400
|
+
|
|
401
|
+
let status$
|
|
334
402
|
if (appConfig.status) {
|
|
335
403
|
const rxjs = require('rxjs')
|
|
336
404
|
const rx = require('rxjs/operators')
|
|
@@ -338,7 +406,6 @@ module.exports = function (appConfig, onTerminate) {
|
|
|
338
406
|
const fp = require('lodash/fp')
|
|
339
407
|
const hashString = require('./hash')
|
|
340
408
|
|
|
341
|
-
let status$
|
|
342
409
|
if (appConfig.status.subscribe) {
|
|
343
410
|
status$ = appConfig.status
|
|
344
411
|
} else if (typeof appConfig.status === 'function') {
|
|
@@ -358,103 +425,157 @@ module.exports = function (appConfig, onTerminate) {
|
|
|
358
425
|
}
|
|
359
426
|
|
|
360
427
|
status$ = rxjs
|
|
361
|
-
.combineLatest(
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
428
|
+
.combineLatest(
|
|
429
|
+
[
|
|
430
|
+
status$.pipe(
|
|
431
|
+
rx.filter(Boolean),
|
|
432
|
+
rx.catchError((err) => {
|
|
433
|
+
logger.error({ err }, 'monitor.status')
|
|
434
|
+
return rxjs.of([
|
|
435
|
+
{
|
|
436
|
+
id: 'app:user_monitor_status',
|
|
437
|
+
level: 50,
|
|
438
|
+
code: err.code,
|
|
439
|
+
msg: err.message,
|
|
440
|
+
},
|
|
441
|
+
])
|
|
442
|
+
}),
|
|
443
|
+
rx.startWith([]),
|
|
444
|
+
rx.distinctUntilChanged(fp.isEqual),
|
|
445
|
+
rx.repeatWhen((complete$) => complete$.pipe(rx.delay(10e3)))
|
|
446
|
+
),
|
|
447
|
+
toobusy
|
|
448
|
+
? rxjs.timer(0, 1e3).pipe(
|
|
449
|
+
rx.map(() =>
|
|
450
|
+
toobusy.lag() > 1e3
|
|
451
|
+
? [
|
|
452
|
+
{
|
|
453
|
+
id: 'app:toobusy_lag',
|
|
454
|
+
level: 40,
|
|
455
|
+
code: 'NXT_LAG',
|
|
456
|
+
msg: `lag: ${toobusy.lag()}`,
|
|
457
|
+
},
|
|
458
|
+
]
|
|
459
|
+
: []
|
|
460
|
+
),
|
|
461
|
+
rx.startWith([]),
|
|
462
|
+
rx.distinctUntilChanged(fp.isEqual)
|
|
463
|
+
)
|
|
464
|
+
: rxjs.of({}),
|
|
465
|
+
couch
|
|
466
|
+
? rxjs.timer(0, 10e3).pipe(
|
|
467
|
+
rx.exhaustMap(async () => {
|
|
468
|
+
try {
|
|
469
|
+
await couch.info()
|
|
470
|
+
} catch (err) {
|
|
471
|
+
return [
|
|
384
472
|
{
|
|
385
|
-
id: 'app:
|
|
473
|
+
id: 'app:couch',
|
|
386
474
|
level: 40,
|
|
387
|
-
code:
|
|
388
|
-
msg:
|
|
475
|
+
code: err.code,
|
|
476
|
+
msg: 'couch: ' + err.message,
|
|
389
477
|
},
|
|
390
478
|
]
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
|
|
479
|
+
}
|
|
480
|
+
}),
|
|
481
|
+
rx.startWith([]),
|
|
482
|
+
rx.distinctUntilChanged(fp.isEqual)
|
|
483
|
+
)
|
|
484
|
+
: rxjs.of({}),
|
|
485
|
+
ds
|
|
486
|
+
? new rxjs.Observable((o) => {
|
|
487
|
+
const client = new undici.Client(`http://${new URL(ds._url || ds.url).host}`, {
|
|
488
|
+
keepAliveTimeout: 30e3,
|
|
489
|
+
})
|
|
490
|
+
|
|
491
|
+
const subscription = rxjs
|
|
492
|
+
.timer(0, 10e3)
|
|
493
|
+
.pipe(
|
|
494
|
+
rx.exhaustMap(async () => {
|
|
495
|
+
const messages = []
|
|
496
|
+
|
|
497
|
+
if (ds.stats.record.records > 100e3) {
|
|
498
|
+
messages.push({
|
|
499
|
+
id: 'app:ds_record_records',
|
|
500
|
+
level: 40,
|
|
501
|
+
code: 'NXT_DEEPSTREAM_RECORDS_RECORDS',
|
|
502
|
+
msg: 'ds: ' + ds.stats.record.records + ' records',
|
|
503
|
+
})
|
|
504
|
+
}
|
|
505
|
+
|
|
506
|
+
if (ds.stats.record.pruning > 100e3) {
|
|
507
|
+
messages.push({
|
|
508
|
+
id: 'app:ds_record_pruning',
|
|
509
|
+
level: 40,
|
|
510
|
+
code: 'NXT_DEEPSTREAM_RECORDS_PRUNING',
|
|
511
|
+
msg: 'ds: ' + ds.stats.record.pruning + ' pruning',
|
|
512
|
+
})
|
|
513
|
+
}
|
|
514
|
+
|
|
515
|
+
if (ds.stats.record.pending > 10e3) {
|
|
516
|
+
messages.push({
|
|
517
|
+
id: 'app:ds_record_pending',
|
|
518
|
+
level: 40,
|
|
519
|
+
code: 'NXT_DEEPSTREAM_RECORDS_PENDING',
|
|
520
|
+
msg: 'ds: ' + ds.stats.record.pending + ' pending',
|
|
521
|
+
})
|
|
522
|
+
}
|
|
523
|
+
|
|
524
|
+
if (ds.stats.record.updating > 10e3) {
|
|
525
|
+
messages.push({
|
|
526
|
+
id: 'app:ds_record_updating',
|
|
527
|
+
level: 40,
|
|
528
|
+
code: 'NXT_DEEPSTREAM_RECORDS_UPDATING',
|
|
529
|
+
msg: 'ds: ' + ds.stats.record.updating + ' updating',
|
|
530
|
+
})
|
|
531
|
+
}
|
|
532
|
+
|
|
533
|
+
if (ds.stats.record.patching > 10e3) {
|
|
534
|
+
messages.push({
|
|
535
|
+
id: 'app:ds_record_patching',
|
|
536
|
+
level: 40,
|
|
537
|
+
code: 'NXT_DEEPSTREAM_RECORDS_PATCHING',
|
|
538
|
+
msg: 'ds: ' + ds.stats.record.patching + ' patching',
|
|
539
|
+
})
|
|
540
|
+
}
|
|
541
|
+
|
|
431
542
|
try {
|
|
432
543
|
const { body } = await client.request({
|
|
433
544
|
method: 'GET',
|
|
434
545
|
path: '/healthcheck',
|
|
435
546
|
})
|
|
436
547
|
await body.dump()
|
|
437
|
-
} catch
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
548
|
+
} catch {
|
|
549
|
+
try {
|
|
550
|
+
const { body } = await client.request({
|
|
551
|
+
method: 'GET',
|
|
552
|
+
path: '/healthcheck',
|
|
553
|
+
})
|
|
554
|
+
await body.dump()
|
|
555
|
+
} catch (err) {
|
|
556
|
+
messages.push({
|
|
557
|
+
id: 'app:ds_http_connection',
|
|
558
|
+
level: 40,
|
|
559
|
+
code: err.code,
|
|
560
|
+
msg: 'ds: ' + err.message,
|
|
561
|
+
})
|
|
443
562
|
}
|
|
444
563
|
}
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
564
|
+
|
|
565
|
+
return messages
|
|
566
|
+
})
|
|
567
|
+
)
|
|
568
|
+
.subscribe(o)
|
|
569
|
+
|
|
570
|
+
return () => {
|
|
571
|
+
client.destroy()
|
|
572
|
+
subscription.unsubscribe()
|
|
573
|
+
}
|
|
574
|
+
}).pipe(rx.startWith([]), rx.distinctUntilChanged(fp.isEqual))
|
|
575
|
+
: rxjs.of({}),
|
|
576
|
+
rxjs.timer(0, 10e3),
|
|
577
|
+
].filter(Boolean)
|
|
578
|
+
)
|
|
458
579
|
.pipe(
|
|
459
580
|
rx.auditTime(1e3),
|
|
460
581
|
rx.map(([status, lag, couch, ds]) => {
|
|
@@ -527,73 +648,6 @@ module.exports = function (appConfig, onTerminate) {
|
|
|
527
648
|
})
|
|
528
649
|
}
|
|
529
650
|
|
|
530
|
-
if (appConfig.stats) {
|
|
531
|
-
const v8 = require('v8')
|
|
532
|
-
const rxjs = require('rxjs')
|
|
533
|
-
const rx = require('rxjs/operators')
|
|
534
|
-
const { eventLoopUtilization } = require('perf_hooks').performance
|
|
535
|
-
|
|
536
|
-
let stats$
|
|
537
|
-
if (typeof appConfig.stats.subscribe === 'function') {
|
|
538
|
-
stats$ = appConfig.stats
|
|
539
|
-
} else if (typeof appConfig.stats === 'function') {
|
|
540
|
-
stats$ = rxjs.timer(0, 10e3).pipe(
|
|
541
|
-
rx.exhaustMap(() => {
|
|
542
|
-
const ret = appConfig.stats({ ds, couch, logger })
|
|
543
|
-
return ret?.then || ret?.subscribe ? ret : rxjs.of(ret)
|
|
544
|
-
})
|
|
545
|
-
)
|
|
546
|
-
} else if (typeof appConfig.stats === 'object') {
|
|
547
|
-
stats$ = rxjs.timer(0, 10e3).pipe(rx.map(() => appConfig.stats))
|
|
548
|
-
} else {
|
|
549
|
-
stats$ = rxjs.timer(0, 10e3).pipe(rx.map(() => ({})))
|
|
550
|
-
}
|
|
551
|
-
|
|
552
|
-
stats$ = stats$.pipe(
|
|
553
|
-
rx.map((x) => ({
|
|
554
|
-
...x,
|
|
555
|
-
timestamp: Date.now(),
|
|
556
|
-
})),
|
|
557
|
-
rx.auditTime(1e3),
|
|
558
|
-
rx.filter(Boolean),
|
|
559
|
-
rx.retryWhen((err$) =>
|
|
560
|
-
err$.pipe(
|
|
561
|
-
rx.tap((err) => logger.error({ err }, 'monitor.stats')),
|
|
562
|
-
rx.delay(10e3)
|
|
563
|
-
)
|
|
564
|
-
),
|
|
565
|
-
rx.startWith({}),
|
|
566
|
-
rx.publishReplay(1),
|
|
567
|
-
rx.refCount()
|
|
568
|
-
)
|
|
569
|
-
|
|
570
|
-
monitorProviders.stats$ = stats$
|
|
571
|
-
|
|
572
|
-
let elu1 = eventLoopUtilization?.()
|
|
573
|
-
const subscription = stats$.pipe(rx.auditTime(10e3)).subscribe((stats) => {
|
|
574
|
-
if (process.env.NODE_ENV === 'production') {
|
|
575
|
-
const elu2 = eventLoopUtilization?.()
|
|
576
|
-
logger.debug(
|
|
577
|
-
{
|
|
578
|
-
ds: ds?.stats,
|
|
579
|
-
couch: couch?.stats,
|
|
580
|
-
lag: toobusy?.lag(),
|
|
581
|
-
memory: process.memoryUsage(),
|
|
582
|
-
utilization: eventLoopUtilization?.(elu2, elu1),
|
|
583
|
-
heap: v8.getHeapStatistics(),
|
|
584
|
-
...stats,
|
|
585
|
-
},
|
|
586
|
-
'STATS'
|
|
587
|
-
)
|
|
588
|
-
elu1 = elu2
|
|
589
|
-
}
|
|
590
|
-
})
|
|
591
|
-
|
|
592
|
-
destroyers.push(() => {
|
|
593
|
-
subscription.unsubscribe()
|
|
594
|
-
})
|
|
595
|
-
}
|
|
596
|
-
|
|
597
651
|
if (ds && Object.keys(monitorProviders).length && appConfig.monitor !== false) {
|
|
598
652
|
const { isMainThread } = require('node:worker_threads')
|
|
599
653
|
|